From 2b682ec61e83260b11cdf65d2f3723a89e4afa88 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 20 Oct 2022 19:47:29 +0400 Subject: [PATCH] feat: initial version This is mostly copied code from another project with small fixups to work in a standalone project. Signed-off-by: Andrey Smirnov --- .codecov.yml | 18 + .conform.yaml | 37 + .dockerignore | 13 + .drone.yml | 254 +++++ .gitignore | 5 + .golangci.yml | 165 ++++ .kres.yaml | 10 + .license-header.go.txt | 3 + .markdownlint.json | 9 + Dockerfile | 119 +++ LICENSE | 373 ++++++++ Makefile | 184 ++++ api/auth/auth.pb.go | 524 ++++++++++ api/auth/auth.pb.gw.go | 341 +++++++ api/auth/auth.proto | 39 + api/auth/auth_grpc.pb.go | 179 ++++ api/auth/auth_vtproto.pb.go | 1103 ++++++++++++++++++++++ go.mod | 32 + go.sum | 101 ++ hack/release.sh | 66 ++ hack/release.toml | 11 + pkg/client/auth/auth.go | 64 ++ pkg/client/interceptor/interceptor.go | 6 + pkg/client/interceptor/signature.go | 176 ++++ pkg/client/interceptor/signature_test.go | 186 ++++ pkg/client/interceptor/suite_test.go | 53 ++ pkg/jwt/claims.go | 17 + pkg/jwt/jwt.go | 6 + pkg/message/common.go | 98 ++ pkg/message/grpc.go | 165 ++++ pkg/message/grpc_test.go | 141 +++ pkg/message/http.go | 132 +++ pkg/message/http_test.go | 139 +++ pkg/message/message.go | 6 + pkg/message/mock_test.go | 34 + pkg/message/payload.go | 77 ++ pkg/message/signature.go | 29 + pkg/pgp/key.go | 162 ++++ pkg/pgp/key_test.go | 32 + 39 files changed, 5109 insertions(+) create mode 100644 .codecov.yml create mode 100644 .conform.yaml create mode 100644 .dockerignore create mode 100644 .drone.yml create mode 100644 .gitignore create mode 100644 .golangci.yml create mode 100644 .kres.yaml create mode 100644 .license-header.go.txt create mode 100644 .markdownlint.json create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 api/auth/auth.pb.go create mode 100644 api/auth/auth.pb.gw.go create mode 100644 api/auth/auth.proto create mode 100644 api/auth/auth_grpc.pb.go create mode 100644 api/auth/auth_vtproto.pb.go create mode 100644 go.mod create mode 100644 go.sum create mode 100755 hack/release.sh create mode 100644 hack/release.toml create mode 100644 pkg/client/auth/auth.go create mode 100644 pkg/client/interceptor/interceptor.go create mode 100644 pkg/client/interceptor/signature.go create mode 100644 pkg/client/interceptor/signature_test.go create mode 100644 pkg/client/interceptor/suite_test.go create mode 100644 pkg/jwt/claims.go create mode 100644 pkg/jwt/jwt.go create mode 100644 pkg/message/common.go create mode 100644 pkg/message/grpc.go create mode 100644 pkg/message/grpc_test.go create mode 100644 pkg/message/http.go create mode 100644 pkg/message/http_test.go create mode 100644 pkg/message/message.go create mode 100644 pkg/message/mock_test.go create mode 100644 pkg/message/payload.go create mode 100644 pkg/message/signature.go create mode 100644 pkg/pgp/key.go create mode 100644 pkg/pgp/key_test.go diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000..c9735f4 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,18 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +codecov: + require_ci_to_pass: false + +coverage: + status: + project: + default: + target: 50% + threshold: 0.5% + base: auto + if_ci_failed: success + patch: off + +comment: false diff --git a/.conform.yaml b/.conform.yaml new file mode 100644 index 0000000..ea90577 --- /dev/null +++ b/.conform.yaml @@ -0,0 +1,37 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +--- +policies: +- type: commit + spec: + dco: true + gpg: + required: true + identity: + gitHubOrganization: siderolabs + spellcheck: + locale: US + maximumOfOneCommit: true + header: + length: 89 + imperative: true + case: lower + invalidLastCharacters: . + body: + required: true + conventional: + types: ["chore","docs","perf","refactor","style","test","release"] + scopes: [".*"] +- type: license + spec: + skipPaths: + - .git/ + - testdata/ + includeSuffixes: + - .go + excludeSuffixes: + - .pb.go + - .pb.gw.go + header: "// This Source Code Form is subject to the terms of the Mozilla Public\u000A// License, v. 2.0. If a copy of the MPL was not distributed with this\u000A// file, You can obtain one at http://mozilla.org/MPL/2.0/.\u000A" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..03e60c7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T18:46:25Z by kres ef0ba25. + +** +!api +!pkg +!go.mod +!go.sum +!.golangci.yml +!README.md +!.markdownlint.json +!.license-header.go.txt diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..0a65041 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,254 @@ +--- +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +kind: pipeline +type: kubernetes +name: default + +platform: + os: linux + arch: amd64 + +steps: +- name: setup-ci + pull: always + image: autonomy/build-container:latest + commands: + - sleep 5 + - git fetch --tags + - install-ci-key + - docker buildx create --driver docker-container --platform linux/amd64 --name local --use unix:///var/outer-run/docker.sock + - docker buildx inspect --bootstrap + environment: + SSH_KEY: + from_secret: ssh_key + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + +- name: base + pull: always + image: autonomy/build-container:latest + commands: + - make base + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - setup-ci + +- name: unit-tests + pull: always + image: autonomy/build-container:latest + commands: + - make unit-tests + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +- name: unit-tests-race + pull: always + image: autonomy/build-container:latest + commands: + - make unit-tests-race + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +- name: coverage + pull: always + image: autonomy/build-container:latest + commands: + - make coverage + environment: + CODECOV_TOKEN: + from_secret: CODECOV_TOKEN + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - unit-tests + +- name: lint + pull: always + image: autonomy/build-container:latest + commands: + - make lint + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + depends_on: + - base + +- name: release-notes + pull: always + image: autonomy/build-container:latest + commands: + - make release-notes + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + when: + event: + - tag + depends_on: + - unit-tests + - coverage + - lint + +- name: release + pull: always + image: plugins/github-release + settings: + api_key: + from_secret: github_token + checksum: + - sha256 + - sha512 + draft: true + files: + - _out/* + note: _out/RELEASE_NOTES.md + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + when: + event: + - tag + depends_on: + - release-notes + +services: +- name: docker + image: docker:20.10-dind + entrypoint: + - dockerd + commands: + - --dns=8.8.8.8 + - --dns=8.8.4.4 + - --mtu=1500 + - --log-level=error + privileged: true + volumes: + - name: outer-docker-socket + path: /var/outer-run + - name: docker-socket + path: /var/run + - name: buildx + path: /root/.docker/buildx + - name: ssh + path: /root/.ssh + +volumes: +- name: outer-docker-socket + host: + path: /var/ci-docker +- name: docker-socket + temp: + medium: memory +- name: buildx + temp: + medium: memory +- name: ssh + temp: + medium: memory + +trigger: + branch: + exclude: + - renovate/* + - dependabot/* + +--- +kind: pipeline +type: kubernetes +name: notify + +platform: + os: linux + arch: amd64 + +clone: + disable: true + +steps: +- name: slack + image: plugins/slack + settings: + channel: proj-talos-maintainers + link_names: true + template: "{{#if build.pull }}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}*: {{ repo.owner }}/{{ repo.name }} - \n{{else}}\n*{{#success build.status}}✓ Success{{else}}✕ Fail{{/success}}: {{ repo.owner }}/{{ repo.name }} - Build #{{ build.number }}* (type: `{{ build.event }}`)\n{{/if}}\nCommit: \nBranch: \nAuthor: {{ build.author }}\n<{{ build.link }}|Visit build page>" + webhook: + from_secret: slack_webhook + when: + status: + - success + - failure + +trigger: + branch: + exclude: + - renovate/* + - dependabot/* + status: + - success + - failure + +depends_on: +- default + +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79be739 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +_out diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..50da8ae --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,165 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +# options for analysis running +run: + timeout: 10m + issues-exit-code: 1 + tests: true + build-tags: [] + skip-dirs: [] + skip-dirs-use-default: true + skip-files: [] + modules-download-mode: readonly + +# output configuration options +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + path-prefix: "" + +# all available settings of specific linters +linters-settings: + dogsled: + max-blank-identifiers: 2 + dupl: + threshold: 150 + errcheck: + check-type-assertions: true + check-blank: true + exhaustive: + default-signifies-exhaustive: false + funlen: + lines: 60 + statements: 40 + gci: + local-prefixes: github.com/siderolabs/go-api-signature + gocognit: + min-complexity: 30 + ireturn: + allow: + - anon + - error + - empty + - stdlib + - github.com\/talos-systems\/kres\/internal\/dag.Node + nestif: + min-complexity: 5 + goconst: + min-len: 3 + min-occurrences: 3 + gocritic: + disabled-checks: [] + gocyclo: + min-complexity: 20 + godot: + check-all: false + godox: + keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting + - NOTE + - OPTIMIZE # marks code that should be optimized before merging + - HACK # marks hack-arounds that should be removed before merging + gofmt: + simplify: true + goimports: + local-prefixes: github.com/siderolabs/go-api-signature + golint: + min-confidence: 0.8 + gomnd: + settings: {} + gomodguard: {} + govet: + check-shadowing: true + enable-all: true + depguard: + list-type: blacklist + include-go-root: false + lll: + line-length: 200 + tab-width: 4 + misspell: + locale: US + ignore-words: [] + nakedret: + max-func-lines: 30 + prealloc: + simple: true + range-loops: true # Report preallocation suggestions on range loops, true by default + for-loops: false # Report preallocation suggestions on for loops, false by default + nolintlint: + allow-unused: false + allow-leading-space: false + allow-no-explanation: [] + require-explanation: false + require-specific: true + rowserrcheck: {} + testpackage: {} + unparam: + check-exported: false + unused: + check-exported: false + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + wsl: + strict-append: true + allow-assign-and-call: true + allow-multiline-assign: true + allow-cuddle-declarations: false + allow-trailing-comment: false + force-case-trailing-whitespace: 0 + force-err-cuddling: false + allow-separated-leading-comment: false + gofumpt: + extra-rules: false + cyclop: + # the maximal code complexity to report + max-complexity: 20 + +linters: + enable-all: true + disable-all: false + fast: false + disable: + - exhaustruct + - exhaustivestruct + - forbidigo + - funlen + - gas + - gochecknoglobals + - gochecknoinits + - godox + - goerr113 + - gomnd + - gomoddirectives + - ireturn + - nestif + - nonamedreturns + - nosnakecase + - paralleltest + - tagliatelle + - thelper + - typecheck + - varnamelen + - wrapcheck + # abandoned linters for which golangci shows the warning that the repo is archived by the owner + - interfacer + - maligned + - golint + - scopelint + +issues: + exclude: [] + exclude-rules: [] + exclude-use-default: false + exclude-case-sensitive: false + max-issues-per-linter: 10 + max-same-issues: 3 + new: false + +severity: + default-severity: error + case-sensitive: false diff --git a/.kres.yaml b/.kres.yaml new file mode 100644 index 0000000..c693d2f --- /dev/null +++ b/.kres.yaml @@ -0,0 +1,10 @@ +--- +kind: golang.Generate +spec: + goGenerateSpecs: + - source: ./internal + vtProtobufEnabled: true + specs: + - source: api/auth/auth.proto + subdirectory: auth + genGateway: true diff --git a/.license-header.go.txt b/.license-header.go.txt new file mode 100644 index 0000000..66e0819 --- /dev/null +++ b/.license-header.go.txt @@ -0,0 +1,3 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..47f0117 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,9 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +{ + "MD013": false, + "MD033": false, + "default": true + } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0d509cb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,119 @@ +# syntax = docker/dockerfile-upstream:1.2.0-labs + +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T18:46:25Z by kres ef0ba25. + +ARG TOOLCHAIN + +# runs markdownlint +FROM docker.io/node:18.10.0-alpine3.16 AS lint-markdown +WORKDIR /src +RUN npm i -g markdownlint-cli@0.32.2 +RUN npm i sentences-per-line@0.2.1 +COPY .markdownlint.json . +COPY ./README.md ./README.md +RUN markdownlint --ignore "CHANGELOG.md" --ignore "**/node_modules/**" --ignore '**/hack/chglog/**' --rules node_modules/sentences-per-line/index.js . + +# collects proto specs +FROM scratch AS proto-specs +ADD api/auth/auth.proto /api/auth/ + +# base toolchain image +FROM ${TOOLCHAIN} AS toolchain +RUN apk --update --no-cache add bash curl build-base protoc protobuf-dev + +# build tools +FROM --platform=${BUILDPLATFORM} toolchain AS tools +ENV GO111MODULE on +ARG CGO_ENABLED +ENV CGO_ENABLED ${CGO_ENABLED} +ENV GOPATH /go +ARG GOLANGCILINT_VERSION +RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCILINT_VERSION} \ + && mv /go/bin/golangci-lint /bin/golangci-lint +ARG GOFUMPT_VERSION +RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \ + && mv /go/bin/gofumpt /bin/gofumpt +RUN go install golang.org/x/vuln/cmd/govulncheck@latest \ + && mv /go/bin/govulncheck /bin/govulncheck +ARG GOIMPORTS_VERSION +RUN go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \ + && mv /go/bin/goimports /bin/goimports +ARG PROTOBUF_GO_VERSION +RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOBUF_GO_VERSION} +RUN mv /go/bin/protoc-gen-go /bin +ARG GRPC_GO_VERSION +RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${GRPC_GO_VERSION} +RUN mv /go/bin/protoc-gen-go-grpc /bin +ARG GRPC_GATEWAY_VERSION +RUN go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v${GRPC_GATEWAY_VERSION} +RUN mv /go/bin/protoc-gen-grpc-gateway /bin +ARG VTPROTOBUF_VERSION +RUN go install github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v${VTPROTOBUF_VERSION} +RUN mv /go/bin/protoc-gen-go-vtproto /bin +ARG DEEPCOPY_VERSION +RUN go install github.com/siderolabs/deep-copy@${DEEPCOPY_VERSION} \ + && mv /go/bin/deep-copy /bin/deep-copy + +# tools and sources +FROM tools AS base +WORKDIR /src +COPY ./go.mod . +COPY ./go.sum . +RUN --mount=type=cache,target=/go/pkg go mod download +RUN --mount=type=cache,target=/go/pkg go mod verify +COPY ./api ./api +COPY ./pkg ./pkg +RUN --mount=type=cache,target=/go/pkg go list -mod=readonly all >/dev/null + +# runs protobuf compiler +FROM tools AS proto-compile +COPY --from=proto-specs / / +RUN protoc -I/api --grpc-gateway_out=paths=source_relative:/api --grpc-gateway_opt=generate_unbound_methods=true --go_out=paths=source_relative:/api --go-grpc_out=paths=source_relative:/api --go-vtproto_out=paths=source_relative:/api --go-vtproto_opt=features=marshal+unmarshal+size /api/auth/auth.proto +RUN rm /api/auth/auth.proto +RUN goimports -w -local github.com/siderolabs/go-api-signature /api +RUN gofumpt -w /api + +# run go generate +FROM base AS go-generate-0 +WORKDIR /src +COPY .license-header.go.txt hack/.license-header.go.txt +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go generate ./internal/... +RUN goimports -w -local github.com/siderolabs/go-api-signature ./internal + +# runs gofumpt +FROM base AS lint-gofumpt +RUN FILES="$(gofumpt -l .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumpt -w .':\n${FILES}"; exit 1) + +# runs goimports +FROM base AS lint-goimports +RUN FILES="$(goimports -l -local github.com/siderolabs/go-api-signature .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'goimports -w -local github.com/siderolabs/go-api-signature .':\n${FILES}"; exit 1) + +# runs golangci-lint +FROM base AS lint-golangci-lint +COPY .golangci.yml . +ENV GOGC 50 +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/.cache/golangci-lint --mount=type=cache,target=/go/pkg golangci-lint run --config .golangci.yml + +# runs govulncheck +FROM base AS lint-govulncheck +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg govulncheck ./... + +# runs unit-tests with race detector +FROM base AS unit-tests-race +ARG TESTPKGS +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp CGO_ENABLED=1 go test -v -race -count 1 ${TESTPKGS} + +# runs unit-tests +FROM base AS unit-tests-run +ARG TESTPKGS +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg --mount=type=cache,target=/tmp go test -v -covermode=atomic -coverprofile=coverage.txt -coverpkg=${TESTPKGS} -count 1 ${TESTPKGS} + +# cleaned up specs and compiled versions +FROM scratch AS generate +COPY --from=proto-compile /api/ /api/ + +FROM scratch AS unit-tests +COPY --from=unit-tests-run /src/coverage.txt /coverage.txt + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a612ad9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c67a94e --- /dev/null +++ b/Makefile @@ -0,0 +1,184 @@ +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T13:58:30Z by kres ef0ba25. + +# common variables + +SHA := $(shell git describe --match=none --always --abbrev=8 --dirty) +TAG := $(shell git describe --tag --always --dirty) +BRANCH := $(shell git rev-parse --abbrev-ref HEAD) +ARTIFACTS := _out +WITH_DEBUG ?= false +WITH_RACE ?= false +REGISTRY ?= ghcr.io +USERNAME ?= siderolabs +REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) +GOLANGCILINT_VERSION ?= v1.50.0 +GOFUMPT_VERSION ?= v0.4.0 +GO_VERSION ?= 1.19 +GOIMPORTS_VERSION ?= v0.1.12 +PROTOBUF_GO_VERSION ?= 1.28.1 +GRPC_GO_VERSION ?= 1.2.0 +GRPC_GATEWAY_VERSION ?= 2.11.3 +VTPROTOBUF_VERSION ?= 0.3.0 +DEEPCOPY_VERSION ?= v0.5.5 +GO_BUILDFLAGS ?= +GO_LDFLAGS ?= +CGO_ENABLED ?= 0 +TESTPKGS ?= ./... +KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest +CONFORMANCE_IMAGE ?= ghcr.io/siderolabs/conform:latest + +# docker build settings + +BUILD := docker buildx build +PLATFORM ?= linux/amd64 +PROGRESS ?= auto +PUSH ?= false +CI_ARGS ?= +COMMON_ARGS = --file=Dockerfile +COMMON_ARGS += --progress=$(PROGRESS) +COMMON_ARGS += --platform=$(PLATFORM) +COMMON_ARGS += --push=$(PUSH) +COMMON_ARGS += --build-arg=ARTIFACTS="$(ARTIFACTS)" +COMMON_ARGS += --build-arg=SHA="$(SHA)" +COMMON_ARGS += --build-arg=TAG="$(TAG)" +COMMON_ARGS += --build-arg=USERNAME="$(USERNAME)" +COMMON_ARGS += --build-arg=REGISTRY="$(REGISTRY)" +COMMON_ARGS += --build-arg=TOOLCHAIN="$(TOOLCHAIN)" +COMMON_ARGS += --build-arg=CGO_ENABLED="$(CGO_ENABLED)" +COMMON_ARGS += --build-arg=GO_BUILDFLAGS="$(GO_BUILDFLAGS)" +COMMON_ARGS += --build-arg=GO_LDFLAGS="$(GO_LDFLAGS)" +COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" +COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)" +COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" +COMMON_ARGS += --build-arg=PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" +COMMON_ARGS += --build-arg=GRPC_GO_VERSION="$(GRPC_GO_VERSION)" +COMMON_ARGS += --build-arg=GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" +COMMON_ARGS += --build-arg=VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" +COMMON_ARGS += --build-arg=DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" +COMMON_ARGS += --build-arg=TESTPKGS="$(TESTPKGS)" +TOOLCHAIN ?= docker.io/golang:1.19-alpine + +# help menu + +export define HELP_MENU_HEADER +# Getting Started + +To build this project, you must have the following installed: + +- git +- make +- docker (19.03 or higher) + +## Creating a Builder Instance + +The build process makes use of experimental Docker features (buildx). +To enable experimental features, add 'experimental: "true"' to '/etc/docker/daemon.json' on +Linux or enable experimental features in Docker GUI for Windows or Mac. + +To create a builder instance, run: + + docker buildx create --name local --use + + +If you already have a compatible builder instance, you may use that instead. + +## Artifacts + +All artifacts will be output to ./$(ARTIFACTS). Images will be tagged with the +registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(TAG)). +The registry and username can be overridden by exporting REGISTRY, and USERNAME +respectively. + +endef + +ifneq (, $(filter $(WITH_RACE), t true TRUE y yes 1)) +GO_BUILDFLAGS += -race +CGO_ENABLED := 1 +GO_LDFLAGS += -linkmode=external -extldflags '-static' +endif + +ifneq (, $(filter $(WITH_DEBUG), t true TRUE y yes 1)) +GO_BUILDFLAGS += -tags sidero.debug +else +GO_LDFLAGS += -s -w +endif + +all: unit-tests lint + +.PHONY: clean +clean: ## Cleans up all artifacts. + @rm -rf $(ARTIFACTS) + +target-%: ## Builds the specified target defined in the Dockerfile. The build result will only remain in the build cache. + @$(BUILD) --target=$* $(COMMON_ARGS) $(TARGET_ARGS) $(CI_ARGS) . + +local-%: ## Builds the specified target defined in the Dockerfile using the local output type. The build result will be output to the specified local destination. + @$(MAKE) target-$* TARGET_ARGS="--output=type=local,dest=$(DEST) $(TARGET_ARGS)" + +lint-golangci-lint: ## Runs golangci-lint linter. + @$(MAKE) target-$@ + +lint-gofumpt: ## Runs gofumpt linter. + @$(MAKE) target-$@ + +.PHONY: fmt +fmt: ## Formats the source code + @docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) \ + bash -c "export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; \ + go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION) && \ + gofumpt -w ." + +lint-govulncheck: ## Runs govulncheck linter. + @$(MAKE) target-$@ + +lint-goimports: ## Runs goimports linter. + @$(MAKE) target-$@ + +generate: ## Generate .proto definitions. + @$(MAKE) local-$@ DEST=./ + +.PHONY: base +base: ## Prepare base toolchain + @$(MAKE) target-$@ + +.PHONY: unit-tests +unit-tests: ## Performs unit tests + @$(MAKE) local-$@ DEST=$(ARTIFACTS) + +.PHONY: unit-tests-race +unit-tests-race: ## Performs unit tests with race detection enabled. + @$(MAKE) target-$@ + +.PHONY: coverage +coverage: ## Upload coverage data to codecov.io. + bash -c "bash <(curl -s https://codecov.io/bash) -f $(ARTIFACTS)/coverage.txt -X fix" + +.PHONY: lint-markdown +lint-markdown: ## Runs markdownlint. + @$(MAKE) target-$@ + +.PHONY: lint +lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-goimports lint-markdown ## Run all linters for the project. + +.PHONY: rekres +rekres: + @docker pull $(KRES_IMAGE) + @docker run --rm -v $(PWD):/src -w /src -e GITHUB_TOKEN $(KRES_IMAGE) + +.PHONY: help +help: ## This help menu. + @echo "$$HELP_MENU_HEADER" + @grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: release-notes +release-notes: + mkdir -p $(ARTIFACTS) + @ARTIFACTS=$(ARTIFACTS) ./hack/release.sh $@ $(ARTIFACTS)/RELEASE_NOTES.md $(TAG) + +.PHONY: conformance +conformance: + @docker pull $(CONFORMANCE_IMAGE) + @docker run --rm -it -v $(PWD):/src -w /src $(CONFORMANCE_IMAGE) enforce + diff --git a/api/auth/auth.pb.go b/api/auth/auth.pb.go new file mode 100644 index 0000000..96919c7 --- /dev/null +++ b/api/auth/auth.pb.go @@ -0,0 +1,524 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.18.1 +// source: auth/auth.proto + +package auth + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PublicKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PgpData []byte `protobuf:"bytes,1,opt,name=pgp_data,json=pgpData,proto3" json:"pgp_data,omitempty"` + WebauthnData []byte `protobuf:"bytes,2,opt,name=webauthn_data,json=webauthnData,proto3" json:"webauthn_data,omitempty"` +} + +func (x *PublicKey) Reset() { + *x = PublicKey{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublicKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicKey) ProtoMessage() {} + +func (x *PublicKey) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. +func (*PublicKey) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{0} +} + +func (x *PublicKey) GetPgpData() []byte { + if x != nil { + return x.PgpData + } + return nil +} + +func (x *PublicKey) GetWebauthnData() []byte { + if x != nil { + return x.WebauthnData + } + return nil +} + +type Identity struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` +} + +func (x *Identity) Reset() { + *x = Identity{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Identity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Identity) ProtoMessage() {} + +func (x *Identity) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Identity.ProtoReflect.Descriptor instead. +func (*Identity) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{1} +} + +func (x *Identity) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +type RegisterPublicKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PublicKey *PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + Identity *Identity `protobuf:"bytes,2,opt,name=identity,proto3" json:"identity,omitempty"` +} + +func (x *RegisterPublicKeyRequest) Reset() { + *x = RegisterPublicKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterPublicKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterPublicKeyRequest) ProtoMessage() {} + +func (x *RegisterPublicKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterPublicKeyRequest.ProtoReflect.Descriptor instead. +func (*RegisterPublicKeyRequest) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{2} +} + +func (x *RegisterPublicKeyRequest) GetPublicKey() *PublicKey { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *RegisterPublicKeyRequest) GetIdentity() *Identity { + if x != nil { + return x.Identity + } + return nil +} + +type RegisterPublicKeyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LoginUrl string `protobuf:"bytes,1,opt,name=login_url,json=loginUrl,proto3" json:"login_url,omitempty"` + PublicKeyId string `protobuf:"bytes,2,opt,name=public_key_id,json=publicKeyId,proto3" json:"public_key_id,omitempty"` +} + +func (x *RegisterPublicKeyResponse) Reset() { + *x = RegisterPublicKeyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterPublicKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterPublicKeyResponse) ProtoMessage() {} + +func (x *RegisterPublicKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterPublicKeyResponse.ProtoReflect.Descriptor instead. +func (*RegisterPublicKeyResponse) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{3} +} + +func (x *RegisterPublicKeyResponse) GetLoginUrl() string { + if x != nil { + return x.LoginUrl + } + return "" +} + +func (x *RegisterPublicKeyResponse) GetPublicKeyId() string { + if x != nil { + return x.PublicKeyId + } + return "" +} + +type AwaitPublicKeyConfirmationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PublicKeyId string `protobuf:"bytes,1,opt,name=public_key_id,json=publicKeyId,proto3" json:"public_key_id,omitempty"` +} + +func (x *AwaitPublicKeyConfirmationRequest) Reset() { + *x = AwaitPublicKeyConfirmationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AwaitPublicKeyConfirmationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AwaitPublicKeyConfirmationRequest) ProtoMessage() {} + +func (x *AwaitPublicKeyConfirmationRequest) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AwaitPublicKeyConfirmationRequest.ProtoReflect.Descriptor instead. +func (*AwaitPublicKeyConfirmationRequest) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{4} +} + +func (x *AwaitPublicKeyConfirmationRequest) GetPublicKeyId() string { + if x != nil { + return x.PublicKeyId + } + return "" +} + +type ConfirmPublicKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PublicKeyId string `protobuf:"bytes,1,opt,name=public_key_id,json=publicKeyId,proto3" json:"public_key_id,omitempty"` +} + +func (x *ConfirmPublicKeyRequest) Reset() { + *x = ConfirmPublicKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_auth_auth_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmPublicKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmPublicKeyRequest) ProtoMessage() {} + +func (x *ConfirmPublicKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_auth_auth_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfirmPublicKeyRequest.ProtoReflect.Descriptor instead. +func (*ConfirmPublicKeyRequest) Descriptor() ([]byte, []int) { + return file_auth_auth_proto_rawDescGZIP(), []int{5} +} + +func (x *ConfirmPublicKeyRequest) GetPublicKeyId() string { + if x != nil { + return x.PublicKeyId + } + return "" +} + +var File_auth_auth_proto protoreflect.FileDescriptor + +var file_auth_auth_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x04, 0x61, 0x75, 0x74, 0x68, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x67, 0x70, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x67, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x23, 0x0a, 0x0d, + 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x44, 0x61, 0x74, + 0x61, 0x22, 0x20, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x22, 0x76, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2e, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, + 0x2a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x5c, 0x0a, 0x19, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, + 0x69, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x21, 0x41, 0x77, 0x61, + 0x69, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, + 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, + 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, + 0x64, 0x32, 0x8d, 0x02, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x54, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x1a, 0x41, 0x77, 0x61, 0x69, 0x74, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x41, 0x77, 0x61, + 0x69, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x2e, 0x61, 0x75, 0x74, + 0x68, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x70, + 0x69, 0x2d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_auth_auth_proto_rawDescOnce sync.Once + file_auth_auth_proto_rawDescData = file_auth_auth_proto_rawDesc +) + +func file_auth_auth_proto_rawDescGZIP() []byte { + file_auth_auth_proto_rawDescOnce.Do(func() { + file_auth_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_auth_proto_rawDescData) + }) + return file_auth_auth_proto_rawDescData +} + +var file_auth_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_auth_auth_proto_goTypes = []interface{}{ + (*PublicKey)(nil), // 0: auth.PublicKey + (*Identity)(nil), // 1: auth.Identity + (*RegisterPublicKeyRequest)(nil), // 2: auth.RegisterPublicKeyRequest + (*RegisterPublicKeyResponse)(nil), // 3: auth.RegisterPublicKeyResponse + (*AwaitPublicKeyConfirmationRequest)(nil), // 4: auth.AwaitPublicKeyConfirmationRequest + (*ConfirmPublicKeyRequest)(nil), // 5: auth.ConfirmPublicKeyRequest + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty +} +var file_auth_auth_proto_depIdxs = []int32{ + 0, // 0: auth.RegisterPublicKeyRequest.public_key:type_name -> auth.PublicKey + 1, // 1: auth.RegisterPublicKeyRequest.identity:type_name -> auth.Identity + 2, // 2: auth.AuthService.RegisterPublicKey:input_type -> auth.RegisterPublicKeyRequest + 4, // 3: auth.AuthService.AwaitPublicKeyConfirmation:input_type -> auth.AwaitPublicKeyConfirmationRequest + 5, // 4: auth.AuthService.ConfirmPublicKey:input_type -> auth.ConfirmPublicKeyRequest + 3, // 5: auth.AuthService.RegisterPublicKey:output_type -> auth.RegisterPublicKeyResponse + 6, // 6: auth.AuthService.AwaitPublicKeyConfirmation:output_type -> google.protobuf.Empty + 6, // 7: auth.AuthService.ConfirmPublicKey:output_type -> google.protobuf.Empty + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_auth_auth_proto_init() } +func file_auth_auth_proto_init() { + if File_auth_auth_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_auth_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublicKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Identity); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterPublicKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterPublicKeyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_auth_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AwaitPublicKeyConfirmationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_auth_auth_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmPublicKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_auth_auth_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_auth_auth_proto_goTypes, + DependencyIndexes: file_auth_auth_proto_depIdxs, + MessageInfos: file_auth_auth_proto_msgTypes, + }.Build() + File_auth_auth_proto = out.File + file_auth_auth_proto_rawDesc = nil + file_auth_auth_proto_goTypes = nil + file_auth_auth_proto_depIdxs = nil +} diff --git a/api/auth/auth.pb.gw.go b/api/auth/auth.pb.gw.go new file mode 100644 index 0000000..be2fa6f --- /dev/null +++ b/api/auth/auth.pb.gw.go @@ -0,0 +1,341 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: auth/auth.proto + +/* +Package auth is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package auth + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_AuthService_RegisterPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterPublicKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.RegisterPublicKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_RegisterPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RegisterPublicKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.RegisterPublicKey(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthService_AwaitPublicKeyConfirmation_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AwaitPublicKeyConfirmationRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AwaitPublicKeyConfirmation(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_AwaitPublicKeyConfirmation_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AwaitPublicKeyConfirmationRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AwaitPublicKeyConfirmation(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthService_ConfirmPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ConfirmPublicKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ConfirmPublicKey(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_ConfirmPublicKey_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ConfirmPublicKeyRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ConfirmPublicKey(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux". +// UnaryRPC :call AuthServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead. +func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error { + + mux.Handle("POST", pattern_AuthService_RegisterPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/auth.AuthService/RegisterPublicKey", runtime.WithHTTPPathPattern("/auth.AuthService/RegisterPublicKey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_RegisterPublicKey_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_RegisterPublicKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_AwaitPublicKeyConfirmation_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/auth.AuthService/AwaitPublicKeyConfirmation", runtime.WithHTTPPathPattern("/auth.AuthService/AwaitPublicKeyConfirmation")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_AwaitPublicKeyConfirmation_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_AwaitPublicKeyConfirmation_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_ConfirmPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/auth.AuthService/ConfirmPublicKey", runtime.WithHTTPPathPattern("/auth.AuthService/ConfirmPublicKey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_ConfirmPublicKey_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_ConfirmPublicKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAuthServiceHandler(ctx, mux, conn) +} + +// RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAuthServiceHandlerClient(ctx, mux, NewAuthServiceClient(conn)) +} + +// RegisterAuthServiceHandlerClient registers the http handlers for service AuthService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AuthServiceClient" to call the correct interceptors. +func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error { + + mux.Handle("POST", pattern_AuthService_RegisterPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/auth.AuthService/RegisterPublicKey", runtime.WithHTTPPathPattern("/auth.AuthService/RegisterPublicKey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_RegisterPublicKey_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_RegisterPublicKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_AwaitPublicKeyConfirmation_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/auth.AuthService/AwaitPublicKeyConfirmation", runtime.WithHTTPPathPattern("/auth.AuthService/AwaitPublicKeyConfirmation")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_AwaitPublicKeyConfirmation_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_AwaitPublicKeyConfirmation_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_ConfirmPublicKey_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/auth.AuthService/ConfirmPublicKey", runtime.WithHTTPPathPattern("/auth.AuthService/ConfirmPublicKey")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_ConfirmPublicKey_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_ConfirmPublicKey_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_AuthService_RegisterPublicKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"auth.AuthService", "RegisterPublicKey"}, "")) + + pattern_AuthService_AwaitPublicKeyConfirmation_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"auth.AuthService", "AwaitPublicKeyConfirmation"}, "")) + + pattern_AuthService_ConfirmPublicKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"auth.AuthService", "ConfirmPublicKey"}, "")) +) + +var ( + forward_AuthService_RegisterPublicKey_0 = runtime.ForwardResponseMessage + + forward_AuthService_AwaitPublicKeyConfirmation_0 = runtime.ForwardResponseMessage + + forward_AuthService_ConfirmPublicKey_0 = runtime.ForwardResponseMessage +) diff --git a/api/auth/auth.proto b/api/auth/auth.proto new file mode 100644 index 0000000..68a41ab --- /dev/null +++ b/api/auth/auth.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package auth; + +option go_package = "github.com/siderolabs/go-api-signature/api/auth"; + +import "google/protobuf/empty.proto"; + +message PublicKey { + bytes pgp_data = 1; + bytes webauthn_data = 2; +} + +message Identity { + string email = 1; +} + +message RegisterPublicKeyRequest { + PublicKey public_key = 1; + Identity identity = 2; +} + +message RegisterPublicKeyResponse { + string login_url = 1; + string public_key_id = 2; +} + +message AwaitPublicKeyConfirmationRequest { + string public_key_id = 1; +} + +message ConfirmPublicKeyRequest { + string public_key_id = 1; +} + +service AuthService { + rpc RegisterPublicKey(RegisterPublicKeyRequest) returns (RegisterPublicKeyResponse); + rpc AwaitPublicKeyConfirmation(AwaitPublicKeyConfirmationRequest) returns (google.protobuf.Empty); + rpc ConfirmPublicKey(ConfirmPublicKeyRequest) returns (google.protobuf.Empty); +} diff --git a/api/auth/auth_grpc.pb.go b/api/auth/auth_grpc.pb.go new file mode 100644 index 0000000..081f820 --- /dev/null +++ b/api/auth/auth_grpc.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.18.1 +// source: auth/auth.proto + +package auth + +import ( + context "context" + + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AuthServiceClient is the client API for AuthService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AuthServiceClient interface { + RegisterPublicKey(ctx context.Context, in *RegisterPublicKeyRequest, opts ...grpc.CallOption) (*RegisterPublicKeyResponse, error) + AwaitPublicKeyConfirmation(ctx context.Context, in *AwaitPublicKeyConfirmationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + ConfirmPublicKey(ctx context.Context, in *ConfirmPublicKeyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type authServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { + return &authServiceClient{cc} +} + +func (c *authServiceClient) RegisterPublicKey(ctx context.Context, in *RegisterPublicKeyRequest, opts ...grpc.CallOption) (*RegisterPublicKeyResponse, error) { + out := new(RegisterPublicKeyResponse) + err := c.cc.Invoke(ctx, "/auth.AuthService/RegisterPublicKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) AwaitPublicKeyConfirmation(ctx context.Context, in *AwaitPublicKeyConfirmationRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/auth.AuthService/AwaitPublicKeyConfirmation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) ConfirmPublicKey(ctx context.Context, in *ConfirmPublicKeyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/auth.AuthService/ConfirmPublicKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AuthServiceServer is the server API for AuthService service. +// All implementations must embed UnimplementedAuthServiceServer +// for forward compatibility +type AuthServiceServer interface { + RegisterPublicKey(context.Context, *RegisterPublicKeyRequest) (*RegisterPublicKeyResponse, error) + AwaitPublicKeyConfirmation(context.Context, *AwaitPublicKeyConfirmationRequest) (*emptypb.Empty, error) + ConfirmPublicKey(context.Context, *ConfirmPublicKeyRequest) (*emptypb.Empty, error) + mustEmbedUnimplementedAuthServiceServer() +} + +// UnimplementedAuthServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAuthServiceServer struct { +} + +func (UnimplementedAuthServiceServer) RegisterPublicKey(context.Context, *RegisterPublicKeyRequest) (*RegisterPublicKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterPublicKey not implemented") +} +func (UnimplementedAuthServiceServer) AwaitPublicKeyConfirmation(context.Context, *AwaitPublicKeyConfirmationRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method AwaitPublicKeyConfirmation not implemented") +} +func (UnimplementedAuthServiceServer) ConfirmPublicKey(context.Context, *ConfirmPublicKeyRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmPublicKey not implemented") +} +func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} + +// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthServiceServer will +// result in compilation errors. +type UnsafeAuthServiceServer interface { + mustEmbedUnimplementedAuthServiceServer() +} + +func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { + s.RegisterService(&AuthService_ServiceDesc, srv) +} + +func _AuthService_RegisterPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterPublicKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).RegisterPublicKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/auth.AuthService/RegisterPublicKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).RegisterPublicKey(ctx, req.(*RegisterPublicKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_AwaitPublicKeyConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AwaitPublicKeyConfirmationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).AwaitPublicKeyConfirmation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/auth.AuthService/AwaitPublicKeyConfirmation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).AwaitPublicKeyConfirmation(ctx, req.(*AwaitPublicKeyConfirmationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_ConfirmPublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmPublicKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).ConfirmPublicKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/auth.AuthService/ConfirmPublicKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).ConfirmPublicKey(ctx, req.(*ConfirmPublicKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AuthService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "auth.AuthService", + HandlerType: (*AuthServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterPublicKey", + Handler: _AuthService_RegisterPublicKey_Handler, + }, + { + MethodName: "AwaitPublicKeyConfirmation", + Handler: _AuthService_AwaitPublicKeyConfirmation_Handler, + }, + { + MethodName: "ConfirmPublicKey", + Handler: _AuthService_ConfirmPublicKey_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "auth/auth.proto", +} diff --git a/api/auth/auth_vtproto.pb.go b/api/auth/auth_vtproto.pb.go new file mode 100644 index 0000000..87676ef --- /dev/null +++ b/api/auth/auth_vtproto.pb.go @@ -0,0 +1,1103 @@ +// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. +// protoc-gen-go-vtproto version: v0.3.0 +// source: auth/auth.proto + +package auth + +import ( + fmt "fmt" + io "io" + bits "math/bits" + + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +func (m *PublicKey) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublicKey) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PublicKey) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.WebauthnData) > 0 { + i -= len(m.WebauthnData) + copy(dAtA[i:], m.WebauthnData) + i = encodeVarint(dAtA, i, uint64(len(m.WebauthnData))) + i-- + dAtA[i] = 0x12 + } + if len(m.PgpData) > 0 { + i -= len(m.PgpData) + copy(dAtA[i:], m.PgpData) + i = encodeVarint(dAtA, i, uint64(len(m.PgpData))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Identity) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Identity) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Identity) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Email) > 0 { + i -= len(m.Email) + copy(dAtA[i:], m.Email) + i = encodeVarint(dAtA, i, uint64(len(m.Email))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RegisterPublicKeyRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RegisterPublicKeyRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RegisterPublicKeyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Identity != nil { + size, err := m.Identity.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if m.PublicKey != nil { + size, err := m.PublicKey.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RegisterPublicKeyResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RegisterPublicKeyResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RegisterPublicKeyResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.PublicKeyId) > 0 { + i -= len(m.PublicKeyId) + copy(dAtA[i:], m.PublicKeyId) + i = encodeVarint(dAtA, i, uint64(len(m.PublicKeyId))) + i-- + dAtA[i] = 0x12 + } + if len(m.LoginUrl) > 0 { + i -= len(m.LoginUrl) + copy(dAtA[i:], m.LoginUrl) + i = encodeVarint(dAtA, i, uint64(len(m.LoginUrl))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AwaitPublicKeyConfirmationRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AwaitPublicKeyConfirmationRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AwaitPublicKeyConfirmationRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.PublicKeyId) > 0 { + i -= len(m.PublicKeyId) + copy(dAtA[i:], m.PublicKeyId) + i = encodeVarint(dAtA, i, uint64(len(m.PublicKeyId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ConfirmPublicKeyRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConfirmPublicKeyRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ConfirmPublicKeyRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.PublicKeyId) > 0 { + i -= len(m.PublicKeyId) + copy(dAtA[i:], m.PublicKeyId) + i = encodeVarint(dAtA, i, uint64(len(m.PublicKeyId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarint(dAtA []byte, offset int, v uint64) int { + offset -= sov(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PublicKey) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PgpData) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.WebauthnData) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *Identity) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Email) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *RegisterPublicKeyRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PublicKey != nil { + l = m.PublicKey.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.Identity != nil { + l = m.Identity.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *RegisterPublicKeyResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.LoginUrl) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.PublicKeyId) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *AwaitPublicKeyConfirmationRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKeyId) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *ConfirmPublicKeyRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKeyId) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func sov(x uint64) (n int) { + return (bits.Len64(x|1) + 6) / 7 +} +func soz(x uint64) (n int) { + return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PublicKey) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PgpData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PgpData = append(m.PgpData[:0], dAtA[iNdEx:postIndex]...) + if m.PgpData == nil { + m.PgpData = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WebauthnData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WebauthnData = append(m.WebauthnData[:0], dAtA[iNdEx:postIndex]...) + if m.WebauthnData == nil { + m.WebauthnData = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Identity) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Identity: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Identity: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Email", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Email = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RegisterPublicKeyRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RegisterPublicKeyRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterPublicKeyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &PublicKey{} + } + if err := m.PublicKey.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identity", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Identity == nil { + m.Identity = &Identity{} + } + if err := m.Identity.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RegisterPublicKeyResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RegisterPublicKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisterPublicKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LoginUrl", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LoginUrl = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKeyId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AwaitPublicKeyConfirmationRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AwaitPublicKeyConfirmationRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AwaitPublicKeyConfirmationRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKeyId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConfirmPublicKeyRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConfirmPublicKeyRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfirmPublicKeyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKeyId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKeyId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skip(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflow + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLength + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroup + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLength + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflow = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") +) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..69d38d3 --- /dev/null +++ b/go.mod @@ -0,0 +1,32 @@ +module github.com/siderolabs/go-api-signature + +go 1.19 + +require ( + github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad + github.com/ProtonMail/gopenpgp/v2 v2.4.10 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 + github.com/hashicorp/go-multierror v1.1.1 + github.com/stretchr/testify v1.8.0 + google.golang.org/grpc v1.50.1 + google.golang.org/protobuf v1.28.1 +) + +require ( + github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f // indirect + github.com/cloudflare/circl v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.4.2 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect + golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect + golang.org/x/text v0.3.8 // indirect + google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8c7dbd5 --- /dev/null +++ b/go.sum @@ -0,0 +1,101 @@ +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY= +github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko= +github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4= +github.com/ProtonMail/gopenpgp/v2 v2.4.10 h1:EYgkxzwmQvsa6kxxkgP1AwzkFqKHscF2UINxaSn6rdI= +github.com/ProtonMail/gopenpgp/v2 v2.4.10/go.mod h1:CTRA7/toc/4DxDy5Du4hPDnIZnJvXSeQ8LsRTOUJoyc= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/creack/pty v1.1.9/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +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= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a h1:GH6UPn3ixhWcKDhpnEC55S75cerLPdpp3hrhfKYjZgw= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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= diff --git a/hack/release.sh b/hack/release.sh new file mode 100755 index 0000000..a8790d1 --- /dev/null +++ b/hack/release.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. +# +# Generated on 2022-10-20T12:09:57Z by kres ef0ba25. + +set -e + +RELEASE_TOOL_IMAGE="ghcr.io/siderolabs/release-tool:latest" + +function release-tool { + docker pull "${RELEASE_TOOL_IMAGE}" >/dev/null + docker run --rm -w /src -v "${PWD}":/src:ro "${RELEASE_TOOL_IMAGE}" -l -d -n -t "${1}" ./hack/release.toml +} + +function changelog { + if [ "$#" -eq 1 ]; then + (release-tool ${1}; echo; cat CHANGELOG.md) > CHANGELOG.md- && mv CHANGELOG.md- CHANGELOG.md + else + echo 1>&2 "Usage: $0 changelog [tag]" + exit 1 + fi +} + +function release-notes { + release-tool "${2}" > "${1}" +} + +function cherry-pick { + if [ $# -ne 2 ]; then + echo 1>&2 "Usage: $0 cherry-pick " + exit 1 + fi + + git checkout $2 + git fetch + git rebase upstream/$2 + git cherry-pick -x $1 +} + +function commit { + if [ $# -ne 1 ]; then + echo 1>&2 "Usage: $0 commit " + exit 1 + fi + + git commit -s -m "release($1): prepare release" -m "This is the official $1 release." +} + +if declare -f "$1" > /dev/null +then + cmd="$1" + shift + $cmd "$@" +else + cat <