From d37fdc59385ccc69b91296a24f57c9e95f1a0e87 Mon Sep 17 00:00:00 2001 From: Ben van B <030@users.noreply.github.com> Date: Sun, 4 Feb 2024 09:14:55 +0100 Subject: [PATCH] feat: [#440] Create user and assign roles. (#447) --- .github/dependabot.yml | 6 +- .github/workflows/dip.yml | 3 +- .github/workflows/go.yml | 3 +- .github/workflows/integration.yml | 6 +- .github/workflows/release.yml | 3 +- .gitignore | 4 +- .golangci.yml | 4 + Taskfile.yml | 50 +++ build/package/snap/snapcraft.yaml | 2 +- cmd/n3dr/configRole.go | 85 +++++ cmd/n3dr/configUser.go | 34 +- docs/CHANGELOG.md | 46 ++- docs/instructions/task.md | 6 + docs/quickstarts/snippets/n3dr/DOWNLOAD.md | 6 +- go.mod | 25 +- go.sum | 82 ++++ .../n3dr/artifactsv2/count/artifacts_test.go | 2 + .../n3dr/artifactsv2/upload/upload_test.go | 2 + .../n3dr/config/repository/repository_test.go | 2 + .../n3dr/config/security/anonymous_test.go | 2 + internal/app/n3dr/config/user/user.go | 128 +++++-- internal/app/n3dr/config/user/user_test.go | 352 ++++++++++++++++++ internal/app/n3dr/connection/connection.go | 2 +- 23 files changed, 801 insertions(+), 54 deletions(-) create mode 100644 Taskfile.yml create mode 100644 cmd/n3dr/configRole.go create mode 100644 docs/instructions/task.md create mode 100644 internal/app/n3dr/config/user/user_test.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 75bc82fd..5d1d7103 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,12 +4,12 @@ updates: - package-ecosystem: 'docker' directory: '/' schedule: - interval: 'weekly' + interval: 'daily' - package-ecosystem: 'github-actions' directory: '/' schedule: - interval: 'weekly' + interval: 'daily' - package-ecosystem: 'gomod' directory: '/' schedule: - interval: 'weekly' + interval: 'daily' diff --git a/.github/workflows/dip.yml b/.github/workflows/dip.yml index 2dced91a..5603e31e 100644 --- a/.github/workflows/dip.yml +++ b/.github/workflows/dip.yml @@ -23,7 +23,8 @@ jobs: - name: Set up Go uses: actions/setup-go@v5.0.0 with: - go-version: 1.19.0 + go-version-file: 'go.mod' + cache: false - name: Check Golang run: | ./dip image --name=golang --regex=^1\.[0-9]+\.[0-9]+-alpine3\.[0-9]+$ --updateDockerfile diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index bac0b0b3..70459ff6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,7 +21,8 @@ jobs: - name: Set up Go uses: actions/setup-go@v5.0.0 with: - go-version: 1.19.0 + go-version-file: 'go.mod' + cache: false - name: Unit tests run: | go test -short -cover -v -coverprofile=coverage.txt \ diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index cf1d80f0..71303ba2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.1.1 - - name: Set up Go - uses: actions/setup-go@v5.0.0 + - uses: actions/setup-go@v5.0.0 with: - go-version: 1.19.0 + go-version-file: 'go.mod' + cache: false - name: Install bats run: | set -x diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7eee6d9b..ec9ec49b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,8 @@ jobs: - name: Set up Go uses: actions/setup-go@v5.0.0 with: - go-version: 1.19.0 + go-version-file: 'go.mod' + cache: false - name: Set N3DR deliverable environment variable run: echo "n3dr-deliverable=n3dr-${{ matrix.os }}" >> $GITHUB_ENV if: | diff --git a/.gitignore b/.gitignore index cccfe766..70cbc0f2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ dip test/gpg/my_rsa_key test/rproxy-nginx-nexus3.conf.tmp -.vagrant \ No newline at end of file +.vagrant + +coverage* diff --git a/.golangci.yml b/.golangci.yml index 43f8cd12..edff67d2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,6 +17,10 @@ issues: - gochecknoinits path: cmd/n3dr/configUser.go text: "don't use `init` function" + - linters: + - gochecknoinits + path: cmd/n3dr/configRole.go + text: "don't use `init` function" - linters: - gochecknoinits path: cmd/n3dr/count.go diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 00000000..9e117a3c --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,50 @@ +--- +version: '3' + +env: + GIT_CHGLOG_URL: https://github.com/git-chglog/git-chglog/releases/download + GIT_CHGLOG_VERSION: v0.15.1/git-chglog_0.15.1_linux_amd64.tar.gz + CHANGELOG_NEXT_TAG: 7.4.0 + +tasks: + changelog: + cmds: + - | + git fetch -p -P + curl \ + -L ${GIT_CHGLOG_URL}/${GIT_CHGLOG_VERSION} \ + -o /tmp/git-chglog.tar.gz + tar -xvf /tmp/git-chglog.tar.gz -C /tmp + chmod +x /tmp/git-chglog + /tmp/git-chglog \ + -o docs/CHANGELOG.md \ + --config configs/chglog/config.yml \ + --next-tag ${CHANGELOG_NEXT_TAG} + sed -i "s|\/\([0-9]\+\.\)\{2\}[0-9]\+|/${CHANGELOG_NEXT_TAG}|g" \ + ./docs/quickstarts/snippets/n3dr/DOWNLOAD.md + sed -i "s|version:.*|version: ${CHANGELOG_NEXT_TAG}|" \ + ./build/package/snap/snapcraft.yaml + integration-tests: + cmds: + - | + go test \ + -coverprofile=coverage.cov \ + --tags=integration \ + -v \ + -count=1 \ + --cover \ + -race \ + -p=4 \ + ./... + go tool cover -func=coverage.cov > coverage-functions.out + go tool cover -html=coverage.cov -o coverage.html + open ./coverage.html + lint: + cmds: + - | + go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2 + ~/go/bin/golangci-lint --version + ~/go/bin/golangci-lint run \ + -v \ + --timeout 2m30s \ + --config .golangci.yml diff --git a/build/package/snap/snapcraft.yaml b/build/package/snap/snapcraft.yaml index fdcec6e9..79790c06 100644 --- a/build/package/snap/snapcraft.yaml +++ b/build/package/snap/snapcraft.yaml @@ -1,7 +1,7 @@ --- name: n3dr base: core20 -version: 7.3.3 +version: 7.4.0 summary: Nexus3 Disaster Recovery description: | Download all artifacts at once or migrate automatically from Nexus to Nexus. diff --git a/cmd/n3dr/configRole.go b/cmd/n3dr/configRole.go new file mode 100644 index 00000000..a4155019 --- /dev/null +++ b/cmd/n3dr/configRole.go @@ -0,0 +1,85 @@ +package main + +import ( + "github.com/030/n3dr/internal/app/n3dr/config/user" + "github.com/030/n3dr/internal/app/n3dr/connection" + "github.com/030/n3dr/internal/app/n3dr/goswagger/models" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var downloadRole, uploadRole bool + +// configUserCmd represents the configUser command. +var configRoleCmd = &cobra.Command{ + Use: "configRole", + Short: "Configure roles.", + Long: `Create roles. + +Examples: + # Create a download role: + n3dr configRole --downloadRole + + # Create an upload role: + n3dr configRole --uploadRole --https=false --n3drPass X --n3drUser admin --n3drURL localhost:9999 +`, + Run: func(cmd *cobra.Command, args []string) { + if !downloadRole && !uploadRole { + log.Fatal("either the downloadRole or uploadRole is required") + } + + acu := models.APICreateUser{ + EmailAddress: email, + FirstName: firstName, + LastName: lastName, + Password: pass, + UserID: id, + } + n := connection.Nexus3{ + FQDN: n3drURL, + HTTPS: &https, + Pass: n3drPass, + User: n3drUser, + } + u := user.User{APICreateUser: acu, Nexus3: n} + + if downloadRole { + u.Roles = []string{"nx-download"} + rr := models.RoleXORequest{ + ID: "nx-download", + Name: "nx-download", + Privileges: []string{ + "nx-repository-view-*-*-browse", + "nx-repository-view-*-*-read", + }, + } + r := user.Role{RoleXORequest: rr, Nexus3: n} + if err := r.CreateRole(); err != nil { + log.Fatal(err) + } + } + + if uploadRole { + u.Roles = []string{"nx-upload"} + rr := models.RoleXORequest{ + ID: "nx-upload", + Name: "nx-upload", + Privileges: []string{ + "nx-repository-view-*-*-add", + "nx-repository-view-*-*-edit", + }, + } + r := user.Role{RoleXORequest: rr, Nexus3: n} + if err := r.CreateRole(); err != nil { + log.Fatal(err) + } + } + }, +} + +func init() { + rootCmd.AddCommand(configRoleCmd) + + configRoleCmd.Flags().BoolVar(&downloadRole, "downloadRole", false, "Whether a download role should be created") + configRoleCmd.Flags().BoolVar(&uploadRole, "uploadRole", false, "Whether an upload role should be created") +} diff --git a/cmd/n3dr/configUser.go b/cmd/n3dr/configUser.go index 76b0b42f..f15459a5 100644 --- a/cmd/n3dr/configUser.go +++ b/cmd/n3dr/configUser.go @@ -9,8 +9,9 @@ import ( ) var ( - admin, changePass, downloadUser, uploadUser bool - email, firstName, id, lastName, pass string + admin, changePass, custom, downloadUser, uploadUser bool + email, firstName, id, lastName, pass string + roles []string ) // configUserCmd represents the configUser command. @@ -20,12 +21,24 @@ var configUserCmd = &cobra.Command{ Long: `Create users or change their passwords. Examples: + # Create an admin user: + n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --admin + + # Create a download user: + n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --downloadUser + + # Create an upload user: + n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --uploadUser + + # Create a custom user and assign certain roles: + n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --roles nx-download,nx-upload --custom + # Change the admin password: n3dr configUser --changePass --https=false --n3drUser admin --n3drURL nexus3:8081 --n3drPass initial-pass --pass some-pass --email admin@example.org --firstName admin --id admin --lastName admin `, Run: func(cmd *cobra.Command, args []string) { - if !admin && !downloadUser && !uploadUser && !changePass { - log.Fatal("either the admin, changePass, downloadUser or uploadUser is required") + if !admin && !custom && !downloadUser && !uploadUser && !changePass { + log.Fatal("either the admin, custom, changePass, create, downloadUser or uploadUser is required") } acu := models.APICreateUser{ @@ -33,6 +46,7 @@ Examples: FirstName: firstName, LastName: lastName, Password: pass, + Roles: roles, UserID: id, } n := connection.Nexus3{ @@ -50,6 +64,15 @@ Examples: } } + if custom { + u.Roles = roles + log.Info("roles:", u) + + if err := u.Create(); err != nil { + log.Fatal(err) + } + } + if downloadUser { u.Roles = []string{"nx-download"} rr := models.RoleXORequest{ @@ -125,7 +148,10 @@ func init() { } configUserCmd.Flags().BoolVar(&admin, "admin", false, "Whether a user should be admin") + configUserCmd.Flags().BoolVar(&custom, "custom", false, "Create a user and assign certain roles") configUserCmd.Flags().BoolVar(&downloadUser, "downloadUser", false, "Whether a user should be able to download") configUserCmd.Flags().BoolVar(&uploadUser, "uploadUser", false, "Whether a user should be able to upload") configUserCmd.Flags().BoolVar(&changePass, "changePass", false, "Whether a pass should be changed") + + configUserCmd.Flags().StringSliceVar(&roles, "roles", nil, "Which roles have to be assigned to the custom user") } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6db2a651..657fb184 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,10 +2,51 @@ ## [Unreleased] + +## [7.4.0] - 2024-02-03 +### Build +- [[#423](https://github.com/030/n3dr/issues/423)] Add golang action. ([#424](https://github.com/030/n3dr/issues/424)) +- Replace separate hadolint, dockle and trivy by one workflow. ([#417](https://github.com/030/n3dr/issues/417)) +- **deps:** bump github.com/spf13/viper from 1.17.0 to 1.18.2 ([#426](https://github.com/030/n3dr/issues/426)) +- **deps:** bump github.com/go-openapi/swag from 0.22.4 to 0.22.9 ([#454](https://github.com/030/n3dr/issues/454)) +- **deps:** bump github.com/aws/aws-sdk-go from 1.48.16 to 1.50.5 ([#453](https://github.com/030/n3dr/issues/453)) +- **deps:** bump golang.org/x/crypto from 0.14.0 to 0.17.0 ([#416](https://github.com/030/n3dr/issues/416)) +- **deps:** bump alpine from 3.19.0 to 3.19.1 ([#455](https://github.com/030/n3dr/issues/455)) +- **deps:** bump schubergphilis/mcvs-golang-action from 0.2.2 to 0.2.3 ([#457](https://github.com/030/n3dr/issues/457)) +- **deps:** bump EndBug/add-and-commit from 9.1.3 to 9.1.4 ([#458](https://github.com/030/n3dr/issues/458)) +- **deps:** bump schubergphilis/mcvs-golang-action from 0.1.1 to 0.2.2 ([#448](https://github.com/030/n3dr/issues/448)) +- **deps:** bump schubergphilis/mcvs-docker-action from 0.2.1 to 0.3.2 ([#449](https://github.com/030/n3dr/issues/449)) +- **deps:** bump github.com/go-playground/validator/v10 ([#444](https://github.com/030/n3dr/issues/444)) +- **deps:** bump golang from 1.21.5-alpine3.18 to 1.21.6-alpine3.18 ([#445](https://github.com/030/n3dr/issues/445)) +- **deps:** bump alpine from 3.18.5 to 3.19.0 ([#413](https://github.com/030/n3dr/issues/413)) +- **deps:** bump github.com/go-openapi/strfmt from 0.21.7 to 0.22.0 ([#434](https://github.com/030/n3dr/issues/434)) +- **deps:** bump schubergphilis/mcvs-docker-action from 0.2.0 to 0.2.1 ([#427](https://github.com/030/n3dr/issues/427)) +- **deps:** bump codecov/codecov-action from 3.1.4 to 4.0.1 ([#463](https://github.com/030/n3dr/issues/463)) +- **deps:** bump github.com/go-openapi/runtime from 0.26.0 to 0.27.1 ([#452](https://github.com/030/n3dr/issues/452)) +- **deps:** bump github.com/samber/lo from 1.38.1 to 1.39.0 ([#389](https://github.com/030/n3dr/issues/389)) +- **deps:** bump github.com/hashicorp/go-retryablehttp ([#392](https://github.com/030/n3dr/issues/392)) +- **deps:** bump github.com/spf13/cobra from 1.7.0 to 1.8.0 ([#393](https://github.com/030/n3dr/issues/393)) +- **deps:** bump github.com/aws/aws-sdk-go from 1.45.25 to 1.48.16 ([#406](https://github.com/030/n3dr/issues/406)) +- **deps:** bump golang from 1.21.0-alpine3.18 to 1.21.5-alpine3.18 ([#405](https://github.com/030/n3dr/issues/405)) +- **deps:** bump github.com/go-openapi/validate from 0.22.1 to 0.22.3 ([#388](https://github.com/030/n3dr/issues/388)) +- **deps:** bump alpine from 3.18.4 to 3.18.5 ([#387](https://github.com/030/n3dr/issues/387)) + +### Feat +- [[#440](https://github.com/030/n3dr/issues/440)] Create user and assign roles. + +### Fix +- [[#428](https://github.com/030/n3dr/issues/428)] Resolve race condition. ([#435](https://github.com/030/n3dr/issues/435)) +- [[#430](https://github.com/030/n3dr/issues/430)] Use semantic version. ([#432](https://github.com/030/n3dr/issues/432)) +- [[#430](https://github.com/030/n3dr/issues/430)] Do not run Sonar if dependabot branch. ([#431](https://github.com/030/n3dr/issues/431)) +- [[#428](https://github.com/030/n3dr/issues/428)] Resolve data race condition in upload. ([#429](https://github.com/030/n3dr/issues/429)) +- Ensure that integration tests are skipped on dep updates. ([#420](https://github.com/030/n3dr/issues/420)) + + ## [7.3.3] - 2023-12-09 ### Build -- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] Use semantic versioning for plugins in github actions. +- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] V is omitted in upload-release-action. ([#404](https://github.com/030/n3dr/issues/404)) +- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] Use semantic versioning for plugins in github actions. ([#403](https://github.com/030/n3dr/issues/403)) - **deps:** bump actions/checkout from 3 to 4 ([#394](https://github.com/030/n3dr/issues/394)) ### Fix @@ -413,7 +454,8 @@ The `backup`, `upload` and `repositories` commands have been removed. ## 1.0.0 - 2019-05-12 -[Unreleased]: https://github.com/030/n3dr/compare/7.3.3...HEAD +[Unreleased]: https://github.com/030/n3dr/compare/7.4.0...HEAD +[7.4.0]: https://github.com/030/n3dr/compare/7.3.3...7.4.0 [7.3.3]: https://github.com/030/n3dr/compare/7.3.2...7.3.3 [7.3.2]: https://github.com/030/n3dr/compare/7.3.1...7.3.2 [7.3.1]: https://github.com/030/n3dr/compare/7.3.0...7.3.1 diff --git a/docs/instructions/task.md b/docs/instructions/task.md new file mode 100644 index 00000000..2ee0bb4e --- /dev/null +++ b/docs/instructions/task.md @@ -0,0 +1,6 @@ +# task + +```bash +go install github.com/go-task/task/v3/cmd/task@v3.33.1 +~/go/bin/task integration-tests +``` diff --git a/docs/quickstarts/snippets/n3dr/DOWNLOAD.md b/docs/quickstarts/snippets/n3dr/DOWNLOAD.md index 867d1b66..3d69548b 100644 --- a/docs/quickstarts/snippets/n3dr/DOWNLOAD.md +++ b/docs/quickstarts/snippets/n3dr/DOWNLOAD.md @@ -1,12 +1,12 @@ # Download -Download the [latest N3DR binary](https://github.com/030/n3dr/releases/tag/7.3.3): +Download the [latest N3DR binary](https://github.com/030/n3dr/releases/tag/7.4.0): ```bash cd /tmp && \ -curl -L https://github.com/030/n3dr/releases/download/7.3.3/n3dr-ubuntu-latest \ +curl -L https://github.com/030/n3dr/releases/download/7.4.0/n3dr-ubuntu-latest \ -o n3dr-ubuntu-latest && \ -curl -L https://github.com/030/n3dr/releases/download/7.3.3/\ +curl -L https://github.com/030/n3dr/releases/download/7.4.0/\ n3dr-ubuntu-latest.sha512.txt \ -o n3dr-ubuntu-latest.sha512.txt && \ sha512sum -c n3dr-ubuntu-latest.sha512.txt && \ diff --git a/go.mod b/go.mod index b87b218e..e5e0475d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/030/n3dr -go 1.21 +go 1.21.5 require ( github.com/030/logging v0.1.2 @@ -16,6 +16,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.5 github.com/mholt/archiver/v3 v3.5.1 github.com/mitchellh/go-homedir v1.1.0 + github.com/ory/dockertest/v3 v3.10.0 github.com/samber/lo v1.39.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -25,9 +26,18 @@ require ( ) require ( + github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/docker/cli v20.10.24+incompatible // indirect + github.com/docker/docker v20.10.24+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect @@ -40,10 +50,13 @@ require ( github.com/go-openapi/spec v0.20.12 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -54,12 +67,17 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mholt/archiver/v4 v4.0.0-alpha.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/nwaples/rardecode v1.1.0 // indirect github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect github.com/oklog/ulid v1.3.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/runc v1.1.12 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -74,6 +92,9 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/ulikunitz/xz v0.5.11 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect go.mongodb.org/mongo-driver v1.13.1 // indirect go.opentelemetry.io/otel v1.17.0 // indirect @@ -82,10 +103,12 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.17.0 // indirect + golang.org/x/mod v0.13.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index fbdfc126..43e96439 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,12 @@ github.com/030/mij v1.0.2 h1:fJ6URW86neK1J0XXZ6VPdrN1ulv37hLgadIj7k3CuYg= github.com/030/mij v1.0.2/go.mod h1:UZDCXdouLCtNrTS/UPUXzHkL09iNS6BFK6rVatYpSSo= github.com/030/p2iwd v1.0.3 h1:Uk6lulNGQfMnQNBt2PoNv63ofsoYN4UN3yKYe2jsQNg= github.com/030/p2iwd v1.0.3/go.mod h1:Vc2w6AckFhvyqPNFYnePs+F1fciCkmmct9yrdRKjlyo= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -11,11 +17,25 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.50.5 h1:H2Aadcgwr7a2aqS6ZwcE+l1mA6ZrTseYCvjw2QLmxIA= github.com/aws/aws-sdk-go v1.50.5/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/cli v20.10.24+incompatible h1:vfV+1kv9yD0/cpL6wWY9cE+Y9J8hL/NqJDGob0B3RVw= +github.com/docker/cli v20.10.24+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= +github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= @@ -60,14 +80,22 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -79,6 +107,8 @@ github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -87,6 +117,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -103,6 +135,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -119,6 +153,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -126,13 +162,24 @@ github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= +github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -158,6 +205,7 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -191,9 +239,17 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= @@ -210,25 +266,40 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -248,18 +319,29 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= +gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= diff --git a/internal/app/n3dr/artifactsv2/count/artifacts_test.go b/internal/app/n3dr/artifactsv2/count/artifacts_test.go index 0c3086f6..5af6cb5a 100644 --- a/internal/app/n3dr/artifactsv2/count/artifacts_test.go +++ b/internal/app/n3dr/artifactsv2/count/artifacts_test.go @@ -1,3 +1,5 @@ +//go:build !integration + package count import ( diff --git a/internal/app/n3dr/artifactsv2/upload/upload_test.go b/internal/app/n3dr/artifactsv2/upload/upload_test.go index a5a3311f..4861eccf 100644 --- a/internal/app/n3dr/artifactsv2/upload/upload_test.go +++ b/internal/app/n3dr/artifactsv2/upload/upload_test.go @@ -1,3 +1,5 @@ +//go:build !integration + package upload import ( diff --git a/internal/app/n3dr/config/repository/repository_test.go b/internal/app/n3dr/config/repository/repository_test.go index 37e02c23..754f46cf 100644 --- a/internal/app/n3dr/config/repository/repository_test.go +++ b/internal/app/n3dr/config/repository/repository_test.go @@ -1,3 +1,5 @@ +//go:build !integration + package repository import ( diff --git a/internal/app/n3dr/config/security/anonymous_test.go b/internal/app/n3dr/config/security/anonymous_test.go index 07fe7392..a735374f 100644 --- a/internal/app/n3dr/config/security/anonymous_test.go +++ b/internal/app/n3dr/config/security/anonymous_test.go @@ -1,3 +1,5 @@ +//go:build !integration + package security import ( diff --git a/internal/app/n3dr/config/user/user.go b/internal/app/n3dr/config/user/user.go index b22e4c93..e808d907 100644 --- a/internal/app/n3dr/config/user/user.go +++ b/internal/app/n3dr/config/user/user.go @@ -23,63 +23,126 @@ type User struct { } func (u *User) Create() error { - log.Infof("creating user: '%s'...", u.UserID) - status := "active" - u.Status = &status + exists, err := u.exists() + if err != nil { + return err + } + if !exists { + status := "active" + u.Status = &status + + client, err := u.Nexus3.Client() + if err != nil { + return err + } + + createUser := security_management_users.CreateUserParams{Body: &u.APICreateUser} + createUser.WithTimeout(time.Second * 30) + resp, err := client.SecurityManagementUsers.CreateUser(&createUser) + if err != nil { + return fmt.Errorf("could not create user: '%w'", err) + } + log.Infof("created the following user: '%v'", resp.Payload) + return nil + } + log.Infof("user: '%s' exists already", u.APICreateUser.UserID) + + return nil +} + +func (u *User) exists() (bool, error) { + exists := false + + log.Info("checking whether user exists...") client, err := u.Nexus3.Client() if err != nil { - return err + return exists, err } - createUser := security_management_users.CreateUserParams{Body: &u.APICreateUser} - createUser.WithTimeout(time.Second * 30) - resp, err := client.SecurityManagementUsers.CreateUser(&createUser) + getUsersParams := security_management_users.GetUsersParams{} + getUsersParams.WithTimeout(time.Second * 30) + resp, err := client.SecurityManagementUsers.GetUsers(&getUsersParams) if err != nil { - userCreated, errRegex := regexp.MatchString("status 500", err.Error()) - if errRegex != nil { + return exists, fmt.Errorf("could not check whether user: '%s' exists. Error: '%w'", u.APICreateUser.UserID, err) + } + + users := resp.GetPayload() + for _, user := range users { + log.Infof("found user: '%+v'", user) + log.Infof("looking for user: '%+v'", u.APICreateUser) + + if user.UserID == u.APICreateUser.UserID { + log.Infof("user: '%s' exists", u.APICreateUser.UserID) + exists = true + } + } + + return exists, nil +} + +func (r *Role) CreateRole() error { + log.Infof("creating role: '%s' if it does not exist...", r.ID) + + exists, err := r.checkWhetherRoleExists() + if err != nil { + return err + } + if !exists { + client, err := r.Nexus3.Client() + if err != nil { return err } - if userCreated { - log.Infof("user: '%s' has already been created", u.UserID) - return nil + + createRole := security_management_roles.CreateParams{Body: &r.RoleXORequest} + createRole.WithTimeout(time.Second * 30) + resp, err := client.SecurityManagementRoles.Create(&createRole) + if err != nil { + return fmt.Errorf("could not create role. Error: '%w'", err) } - return fmt.Errorf("could not create user: '%w'", err) + + log.Infof("created the following role: '%+v'", resp.Payload) + return nil } - log.Infof("created the following user: '%v'", resp.Payload) + log.Infof("role: '%s' exists already", r.RoleXORequest.ID) return nil } -func (r *Role) CreateRole() error { - log.Infof("creating role: '%s'...", r.ID) +func (r *Role) checkWhetherRoleExists() (bool, error) { + exists := false + + log.Infof("checking whether role id: '%s' exists...", r.ID) client, err := r.Nexus3.Client() if err != nil { - return err + return exists, err } - createRole := security_management_roles.CreateParams{Body: &r.RoleXORequest} - createRole.WithTimeout(time.Second * 30) - resp, err := client.SecurityManagementRoles.Create(&createRole) + getRoleParams := security_management_roles.GetRoleParams{ID: r.RoleXORequest.ID} + getRoleParams.WithTimeout(time.Second * 30) + resp, err := client.SecurityManagementRoles.GetRole(&getRoleParams) if err != nil { - roleCreated, errRegex := regexp.MatchString("status 400", err.Error()) + roleDoesNotExist, errRegex := regexp.MatchString(`\]\[404\] getRoleNotFound`, err.Error()) if errRegex != nil { - return err + return exists, err } - if roleCreated { - log.Infof("role: '%s' has already been created", r.Name) - return nil + if roleDoesNotExist { + log.Infof("role id: '%s' does not exist...", r.ID) + return exists, nil } - return fmt.Errorf("could not create role: '%w', perhaps the role already exists?", err) + return exists, fmt.Errorf("could not get role: '%s'. Error: '%w'", getRoleParams.ID, err) } - log.Infof("created the following role: '%v'", resp.Payload) - return nil + log.Infof("role: '%s' exists", resp.GetPayload().ID) + exists = true + + return exists, nil } func (u *User) ChangePass() error { log.Infof("changing pass user: '%s'...", u.UserID) + client, err := u.Nexus3.Client() if err != nil { return err @@ -87,18 +150,19 @@ func (u *User) ChangePass() error { changePass := security_management_users.ChangePasswordParams{Body: u.Password, UserID: u.UserID} changePass.WithTimeout(time.Second * 30) + if err := client.SecurityManagementUsers.ChangePassword(&changePass); err != nil { passwordChanged, errRegex := regexp.MatchString("status 204", err.Error()) if errRegex != nil { return err } - if passwordChanged { - log.Infof("user: '%s' pass has been changed", u.UserID) - return nil + if !passwordChanged { + return fmt.Errorf("password of userID: '%s' did not change. Error: '%w'", u.UserID, err) } - return err } + log.Infof("user: '%s' pass has been changed", u.UserID) + return nil } diff --git a/internal/app/n3dr/config/user/user_test.go b/internal/app/n3dr/config/user/user_test.go new file mode 100644 index 00000000..394f7fb1 --- /dev/null +++ b/internal/app/n3dr/config/user/user_test.go @@ -0,0 +1,352 @@ +//go:build integration + +package user + +import ( + "bytes" + "fmt" + "net/http" + "os" + "testing" + "time" + + "github.com/030/n3dr/internal/app/n3dr/connection" + "github.com/030/n3dr/internal/app/n3dr/goswagger/models" + "github.com/ory/dockertest/v3" + "github.com/ory/dockertest/v3/docker" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +const integrationTestAdminPassword = "someIntegrationTestPassword123!" + +var hostAndPort, initialAdminPassword string + +func TestMain(m *testing.M) { + // uses a sensible default on windows (tcp/http) and linux/osx (socket) + pool, err := dockertest.NewPool("") + if err != nil { + log.Fatalf("Could not construct pool: %s", err) + } + + err = pool.Client.Ping() + if err != nil { + log.Fatalf("Could not connect to Docker: %s", err) + } + + // pulls an image, creates a container based on it and runs it + resource, err := pool.RunWithOptions(&dockertest.RunOptions{ + Repository: "sonatype/nexus3", + Tag: "3.64.0", + }, func(config *docker.HostConfig) { + // set AutoRemove to true so that stopped container goes away by itself + config.AutoRemove = true + config.RestartPolicy = docker.RestartPolicy{Name: "no"} + }) + if err != nil { + log.Fatalf("Could not start resource: %s", err) + } + + hostAndPort = resource.GetHostPort("8081/tcp") + log.Info("hostAndPort", hostAndPort) + + client := http.Client{} + + pool.MaxWait = time.Minute * 3 + // exponential backoff-retry, because the application in the container might not be ready to accept connections yet. + if err = pool.Retry(func() error { + // Check whether Nexus3 is ready and writable + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%s/service/rest/v1/status/writable", resource.GetPort("8081/tcp")), nil) + if err != nil { + return err + } + + _, err = client.Do(req) + + return err + }); err != nil { + log.Fatalf("Could not connect to docker: %s", err) + } + + var out bytes.Buffer + resource.Exec([]string{"cat", "/nexus-data/admin.password"}, dockertest.ExecOptions{ + StdOut: &out, + StdErr: &out, + }) + initialAdminPassword = out.String() + + code := m.Run() + + // You can't defer this because os.Exit doesn't care for defer + if err := pool.Purge(resource); err != nil { + log.Fatalf("Could not purge resource: %s", err) + } + + os.Exit(code) +} + +func TestChangePass(t *testing.T) { + https := false + c := connection.Nexus3{ + HTTPS: &https, + User: "admin", + } + macu := models.APICreateUser{ + EmailAddress: "admin@example.org", + FirstName: "admin", + UserID: "admin", + LastName: "admin", + Password: initialAdminPassword, + } + + tests := []struct { + adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged string + unsetHostAndPort bool + }{ + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "If admin password is valid then it should be possible to change it with the same password that is valid.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + }, + { + adminPassword: "incorrectPassword", + expectedErrorString: "password of userID: 'admin' did not change. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 401): {}'", + name: "Test that change of password will fail if it is not possible to login to Nexus3 due to an incorrect password.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "password of userID: 'someUserIDThatDoesNotExist' did not change. Error: '[PUT /v1/security/users/{userId}/change-password][404] changePasswordNotFound '", + name: "Test that password change will fail if userID does not exist.", + passwordOfUserIdThatHasToBeChanged: "someUserIDThatDoesNotExist", + unsetHostAndPort: false, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag", + name: "Test that password change will fail if host and port have not been set.", + passwordOfUserIdThatHasToBeChanged: "someUserIDThatDoesNotExist", + unsetHostAndPort: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + c.Pass = test.adminPassword + c.FQDN = hostAndPort + if test.unsetHostAndPort { + c.FQDN = "" + } + + macu.UserID = test.passwordOfUserIdThatHasToBeChanged + u := User{c, macu} + err := u.ChangePass() + + if test.expectedErrorString == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.expectedErrorString) + } + }) + } +} + +func TestCreateRole(t *testing.T) { + https := false + c := connection.Nexus3{ + HTTPS: &https, + User: "admin", + } + mrxr := models.RoleXORequest{ + Name: "nx-upload", + } + + tests := []struct { + adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged, roleID string + rolePrivileges []string + unsetHostAndPort bool + }{ + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "Create a role.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + roleID: "nx-upload", + rolePrivileges: []string{ + "nx-repository-view-*-*-add", + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "Trying to create a role that exists should be handled by the code and return without any error.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + roleID: "nx-upload", + rolePrivileges: []string{ + "nx-repository-view-*-*-edit", + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "could not create role. Response: ''. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 400): {}'", + name: "Trying to create a role with a privilege that does not exist.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + roleID: "role-that-does-not-exist", + rolePrivileges: []string{ + "a-privilege-that-does-not-exist", + }, + }, + { + adminPassword: "incorrectPassword", + expectedErrorString: "could not get role: 'role-that-does-not-exist'. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 401): {}'", + name: "Test that role creatiom will fail if it is not possible to login to Nexus3 due to an incorrect password.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: false, + roleID: "role-that-does-not-exist", + rolePrivileges: []string{ + "a-privilege-that-does-not-exist", + }, + }, + { + adminPassword: "incorrectPassword", + expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag", + name: "Test that role creatiom will fail if it is not possible to login to Nexus3 due to an incorrect password.", + passwordOfUserIdThatHasToBeChanged: "admin", + unsetHostAndPort: true, + roleID: "role-that-does-not-exist", + rolePrivileges: []string{ + "a-privilege-that-does-not-exist", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + c.Pass = test.adminPassword + c.FQDN = hostAndPort + if test.unsetHostAndPort { + c.FQDN = "" + } + + r := Role{c, mrxr} + r.RoleXORequest.ID = test.roleID + r.RoleXORequest.Privileges = test.rolePrivileges + err := r.CreateRole() + + if test.expectedErrorString == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.expectedErrorString) + } + }) + } +} + +func TestCreateUser(t *testing.T) { + https := false + c := connection.Nexus3{ + HTTPS: &https, + User: "admin", + } + + tests := []struct { + adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged, roleID string + rolePrivileges []string + unsetHostAndPort bool + macu models.APICreateUser + }{ + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "Create a user that exists.", + unsetHostAndPort: false, + macu: models.APICreateUser{ + EmailAddress: "admin@example.org", + FirstName: "admin", + LastName: "admin", + Password: "some-password1234!", + UserID: "admin", + Roles: []string{"nx-anonymous"}, + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "Create a user that does not exist.", + unsetHostAndPort: false, + macu: models.APICreateUser{ + EmailAddress: "admin42@example.org", + FirstName: "admin42", + LastName: "admin42", + Password: "some-password1234!", + UserID: "admin42", + Roles: []string{"nx-anonymous"}, + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "", + name: "Create a user that has just been created for the second time.", + unsetHostAndPort: false, + macu: models.APICreateUser{ + EmailAddress: "admin42@example.org", + FirstName: "admin42", + LastName: "admin42", + Password: "some-password1234!", + UserID: "admin42", + Roles: []string{"nx-anonymous"}, + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "could not create user: '[POST /v1/security/users][400] createUserBadRequest '", + name: "Create a new user without specifying a role should return a 400 bad request as roles are required.", + unsetHostAndPort: false, + macu: models.APICreateUser{ + EmailAddress: "admin43@example.org", + FirstName: "admin43", + LastName: "admin43", + Password: "some-password1234!", + UserID: "admin43", + }, + }, + { + adminPassword: initialAdminPassword, + expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag", + name: "Create a new user, but this should fail as the Nexus3 URL is invalid.", + unsetHostAndPort: true, + macu: models.APICreateUser{ + EmailAddress: "admin43@example.org", + FirstName: "admin43", + LastName: "admin43", + Password: "some-password1234!", + UserID: "admin43", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + c.Pass = test.adminPassword + c.FQDN = hostAndPort + if test.unsetHostAndPort { + c.FQDN = "" + } + + u := User{c, test.macu} + err := u.Create() + + if test.expectedErrorString == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.expectedErrorString) + } + }) + } +} diff --git a/internal/app/n3dr/connection/connection.go b/internal/app/n3dr/connection/connection.go index b70d96ca..4473f223 100644 --- a/internal/app/n3dr/connection/connection.go +++ b/internal/app/n3dr/connection/connection.go @@ -13,7 +13,7 @@ type Nexus3 struct { DockerPort int32 DockerPortSecure, SkipErrors, StrictContentTypeValidation, WithoutWaitGroups, WithoutWaitGroupArtifacts, WithoutWaitGroupRepositories, ZIP bool HTTPS *bool `validate:"required"` - FQDN string `validate:"required"` + FQDN string `validate:"required,min=3"` } func (n *Nexus3) Client() (*apiclient.Nexus3, error) {