diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 074bbd20a..b6b50327c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version: '1.25.7' + go-version: '1.26.8' - name: tests run: make test diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index f84f4c389..2ce6a0111 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version: ~1.25.7 + go-version: ~1.26.8 - name: Log in to GHCR uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 468743e63..cdce57ece 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version: ~1.25.7 + go-version: ~1.26.8 - name: Log in to GHCR uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: diff --git a/buf.gen.yaml b/buf.gen.yaml old mode 100755 new mode 100644 index d9886d9a1..87ae00821 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -1,40 +1,52 @@ -#!/usr/bin/env -S buf generate --template ---- -version: v1 +version: v2 +inputs: + - directory: proto managed: enabled: true - go_package_prefix: - default: github.com/Permify/permify/pkg/pb - except: - - buf.build/googleapis/googleapis - - buf.build/envoyproxy/protoc-gen-validate - - buf.build/grpc-ecosystem/grpc-gateway + disable: + - file_option: go_package + module: buf.build/googleapis/googleapis + - file_option: go_package + module: buf.build/grpc-ecosystem/grpc-gateway + - file_option: go_package + module: buf.build/bufbuild/protovalidate + override: + - file_option: go_package_prefix + value: github.com/Permify/permify/pkg/pb plugins: - - name: go - path: ["go", "run", "google.golang.org/protobuf/cmd/protoc-gen-go"] + - local: + - go + - run + - google.golang.org/protobuf/cmd/protoc-gen-go out: pkg/pb opt: paths=source_relative - - name: go-grpc - path: ["go", "run", "google.golang.org/grpc/cmd/protoc-gen-go-grpc"] + - local: + - go + - run + - google.golang.org/grpc/cmd/protoc-gen-go-grpc out: pkg/pb opt: paths=source_relative - - name: go-vtproto - path: ["go", "run", "github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto"] + - local: + - go + - run + - github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto out: pkg/pb opt: paths=source_relative,features=marshal+unmarshal+size+clone+pool+equal - - name: validate - path: ["go", "run", "github.com/envoyproxy/protoc-gen-validate"] - out: pkg/pb - opt: paths=source_relative,lang=go - - name: grpc-gateway - path: ["go", "run", "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"] + - local: + - go + - run + - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway out: pkg/pb opt: paths=source_relative - - name: openapiv2 - path: ["go", "run", "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"] + - local: + - go + - run + - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 out: docs/api-reference opt: openapi_naming_strategy=simple,allow_merge=true - - name: openapiv2 - path: ["go", "run", "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"] + - local: + - go + - run + - github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 out: docs/api-reference/openapiv2 - opt: omit_enum_default_value=true,openapi_naming_strategy=simple,allow_merge=true + opt: omit_enum_default_value=true,openapi_naming_strategy=simple,allow_merge=true \ No newline at end of file diff --git a/buf.work.yaml b/buf.work.yaml deleted file mode 100644 index 2b96194a4..000000000 --- a/buf.work.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -version: v1 -directories: - - proto \ No newline at end of file diff --git a/go.mod b/go.mod index 24e2074fa..6f28cfef1 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,9 @@ module github.com/Permify/permify -go 1.25.7 +go 1.26.0 tool ( github.com/bufbuild/buf/cmd/buf - github.com/envoyproxy/protoc-gen-validate github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 @@ -23,7 +22,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 github.com/dgraph-io/ristretto v1.0.0 github.com/dustin/go-humanize v1.0.1 - github.com/envoyproxy/protoc-gen-validate v1.3.3 github.com/exaring/otelpgx v0.10.0 github.com/fatih/color v1.19.0 github.com/go-jose/go-jose/v3 v3.0.5 @@ -70,12 +68,12 @@ require ( go.opentelemetry.io/otel/sdk v1.46.0 go.opentelemetry.io/otel/sdk/metric v1.46.0 go.opentelemetry.io/otel/trace v1.46.0 - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 + golang.org/x/exp v0.0.0-20260820142414-ca536658362e golang.org/x/net v0.58.0 // indirect golang.org/x/sync v0.22.0 - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa + google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 google.golang.org/grpc v1.83.2 - google.golang.org/protobuf v1.36.11 + google.golang.org/protobuf v1.36.12 resenje.org/singleflight v0.4.3 ) @@ -84,18 +82,18 @@ require ( 4d63.com/gocheckcompilerdirectives v1.3.0 // indirect 4d63.com/gochecknoglobals v0.2.2 // indirect buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.10-20250718181942-e35f9b667443.1 // indirect - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250717185734-6c6e0d3c608e.1 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.1 buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.0-20250924144421-cb55f06efbd2.1 // indirect buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.10-20250924144421-cb55f06efbd2.1 // indirect buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.9-20241007202033-cf42259fcbfc.1 // indirect buf.build/go/app v0.1.0 // indirect buf.build/go/bufplugin v0.9.0 // indirect buf.build/go/interrupt v1.1.0 // indirect - buf.build/go/protovalidate v1.0.0 // indirect + buf.build/go/protovalidate v1.4.0 buf.build/go/protoyaml v0.6.0 // indirect buf.build/go/spdx v0.2.0 // indirect buf.build/go/standard v0.1.0 // indirect - cel.dev/expr v0.25.2 // indirect + cel.dev/expr v0.25.3 // indirect cloud.google.com/go v0.123.0 // indirect cloud.google.com/go/ai v0.12.1 // indirect cloud.google.com/go/auth v0.18.2 // indirect @@ -217,7 +215,6 @@ require ( github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/iancoleman/strcase v0.3.0 // indirect github.com/jdx/go-netrc v1.0.0 // indirect github.com/jgautheron/goconst v1.8.2 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect @@ -242,7 +239,6 @@ require ( github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/lyft/protoc-gen-star/v2 v2.0.4 // indirect github.com/macabu/inamedparam v0.2.0 // indirect github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect github.com/manuelarte/funcorder v0.5.0 // indirect @@ -326,7 +322,7 @@ require ( go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v3 v3.0.5 golang.org/x/exp/typeparams v0.0.0-20250911091902-df9299821621 // indirect - golang.org/x/mod v0.38.0 // indirect + golang.org/x/mod v0.39.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/term v0.45.0 // indirect golang.org/x/time v0.14.0 // indirect @@ -409,11 +405,12 @@ require ( golang.org/x/crypto v0.55.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/text v0.41.0 // indirect - golang.org/x/tools v0.48.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + golang.org/x/tools v0.49.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect ) require ( + cel.dev/cel-go v0.32.0 // indirect github.com/clipperhouse/displaywidth v0.10.0 // indirect github.com/clipperhouse/uax29/v2 v2.6.0 // indirect github.com/moby/moby/api v1.54.1 // indirect diff --git a/go.sum b/go.sum index dcf8a95f1..a43e8165c 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ 4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0= buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.10-20250718181942-e35f9b667443.1 h1:FzJGrb8r7vir+P3zJ5Ebey8p54LYTYtQsrM/U35YO9Q= buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.10-20250718181942-e35f9b667443.1/go.mod h1:E6HwqUm4Ag7bXtg/tX7jHWO7CgpknbmeACgDax0icV0= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250717185734-6c6e0d3c608e.1 h1:N4XvWMoswHV6F6c8vmWw2BeR9hYuUX0wrr0NssttyUw= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250717185734-6c6e0d3c608e.1/go.mod h1:fUl8CEN/6ZAMk6bP8ahBJPUJw7rbp+j4x+wCcYi2IG4= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.1 h1:Slv0uGxx219srASyiaI5C9cDlyG8kNDcXpTSYcuAeE4= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.1/go.mod h1:TCt1lluMFnctISJXvkIQ4x3ABrPuUKCWKyjKdkJNBpw= buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.0-20250924144421-cb55f06efbd2.1 h1:GPNjspvq4O2Cj1BJ5Z4c7Y+I9pDX5ixlbcGoqxyBDx0= buf.build/gen/go/bufbuild/registry/connectrpc/go v1.19.0-20250924144421-cb55f06efbd2.1/go.mod h1:V7mUsvSd9Gw0ir8u7Jgh+IpSm631EqcdMEj29un7YOY= buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.10-20250924144421-cb55f06efbd2.1 h1:4ZcqdlWZF5tQUyHBeLyOwFjRwZ/93X/W5GfOZX9dJZo= @@ -18,16 +18,18 @@ buf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo= buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY= buf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE= buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM= -buf.build/go/protovalidate v1.0.0 h1:IAG1etULddAy93fiBsFVhpj7es5zL53AfB/79CVGtyY= -buf.build/go/protovalidate v1.0.0/go.mod h1:KQmEUrcQuC99hAw+juzOEAmILScQiKBP1Oc36vvCLW8= +buf.build/go/protovalidate v1.4.0 h1:UjLrYbt5VX7+TMOs2+pG5FhZhIG1mSfK4EIopbb4LcM= +buf.build/go/protovalidate v1.4.0/go.mod h1:8vJfzNT6NIG2qm3uFsJDXMlRmG+bQJzbcIn1Aa0vPGs= buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w= buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q= buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw= buf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8= buf.build/go/standard v0.1.0 h1:g98T9IyvAl0vS3Pq8iVk6Cvj2ZiFvoUJRtfyGa0120U= buf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg= -cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= -cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cel.dev/cel-go v0.32.0 h1:irvpFKr5EuGPyxeME03ERh0rii1TX+BDAnB9eL3IvNk= +cel.dev/cel-go v0.32.0/go.mod h1:DnVip7tpJSsgZymwfT+m1tnEVy3ivAjSMXPx12YrMkU= +cel.dev/expr v0.25.3 h1:A2jO8jwOugrrovveCWfj0KEZOfqiLgAcwjpHPhzIGw0= +cel.dev/expr v0.25.3/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= @@ -150,6 +152,8 @@ github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE= github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE= github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg= github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s= +github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= +github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/bufbuild/buf v1.58.0 h1:TMgp0jmfPD5SixbUCB2iqGnK/X+2KQXTzsVc7F2LbLc= github.com/bufbuild/buf v1.58.0/go.mod h1:guevy4hwwKlc9h69k4E9O/D23ecJHnP5LJ9QlDQoBtg= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= @@ -456,8 +460,6 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= @@ -600,8 +602,6 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k= github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= -github.com/lyft/protoc-gen-star/v2 v2.0.4 h1:JDlNKttNIRd68AAIychs0AqEpO8/I/WYi01OQ7Raw6Q= -github.com/lyft/protoc-gen-star/v2 v2.0.4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE= github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= @@ -750,6 +750,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8= +github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWgejz1AlYpY1mI0= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= @@ -1016,8 +1018,8 @@ golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZP golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20260820142414-ca536658362e h1:01Ju2A/fZKkci4zqx0eZxw//DnRYOnBiGJG14hFBhO8= +golang.org/x/exp v0.0.0-20260820142414-ca536658362e/go.mod h1:zeBbvyFKDaLwa7CH/zI8KXt7gTl14SF7sO08Pl5jBCM= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20250911091902-df9299821621 h1:Yl4H5w2RV7L/dvSHp2GerziT5K2CORgFINPaMFxWGWw= @@ -1037,8 +1039,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= -golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/mod v0.39.0 h1:UF5zwQdCRRUpHfyPwr7d4UrGiVeldIsogtzWVnczL74= +golang.org/x/mod v0.39.0/go.mod h1:bvIbwjQ0HUFFf5AKukeeYQG4ZBUG9yxQbR9aEweIwYY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1161,8 +1163,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= -golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -1184,10 +1186,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 h1:ax2KzoSRIZU/M0cIxri3pKxy99vniH1PVxWC6si/eZI= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688/go.mod h1:1RJ9BQGyNdZwkGc1eTqkErfRZ6RJyYPHZo73BZ1vQqI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -1197,8 +1199,8 @@ google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/go.work b/go.work index 38ebce6f7..957f5b9c5 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,3 @@ -go 1.25.7 +go 1.26.0 use . diff --git a/go.work.sum b/go.work.sum index 64c5c37c6..a0018cea4 100644 --- a/go.work.sum +++ b/go.work.sum @@ -4,6 +4,7 @@ buf.build/gen/go/bufbuild/protovalidate/connectrpc/go v1.19.0-20250717185734-6c6 buf.build/gen/go/bufbuild/protovalidate/connectrpc/go v1.19.0-20250717185734-6c6e0d3c608e.1/go.mod h1:4TTUoOHJGTpciUKRMv3Qiqi/Y0qsDPzs57CKn8f9eQI= buf.build/go/hyperpb v0.1.0 h1:utndCev4u1XvvCqcpmqLnYuaqTvVlLSFDc87mW7iQKA= buf.build/go/hyperpb v0.1.0/go.mod h1:EZWL//pO7VKbCxzZU0JlTzFDGmfN5reHshsFHOu3AKI= +buf.build/go/hyperpb v0.1.3/go.mod h1:IHXAM5qnS0/Fsnd7/HGDghFNvUET646WoHmq1FDZXIE= cloud.google.com/go/accessapproval v1.8.7 h1:Sc9ZjxFBEM/PoAxNlUwVGDcv8DYyjLYWDxHlzPG0q5I= cloud.google.com/go/accessapproval v1.8.7/go.mod h1:BFvZOW4GJjJnl6aA/YDEg0TGViFHyusa/bMdcVFmh8A= cloud.google.com/go/accessapproval v1.8.8/go.mod h1:RFwPY9JDKseP4gJrX1BlAVsP5O6kI8NdGlTmaeDefmk= @@ -545,6 +546,7 @@ golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZ golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE= golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959/go.mod h1:LV7u5Oco+Z/g6XI7PqN+EUUUGGkEcmB1uj2ceI0fOVg= +golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= diff --git a/internal/servers/bundle_server.go b/internal/servers/bundle_server.go index 83336d0e8..b98a09591 100644 --- a/internal/servers/bundle_server.go +++ b/internal/servers/bundle_server.go @@ -7,6 +7,8 @@ import ( otelCodes "go.opentelemetry.io/otel/codes" "google.golang.org/grpc/status" + "buf.build/go/protovalidate" + "github.com/Permify/permify/internal" "github.com/Permify/permify/internal/storage" "github.com/Permify/permify/internal/validation" @@ -36,7 +38,7 @@ func (r *BundleServer) Write(ctx context.Context, request *v1.BundleWriteRequest ctx, span := internal.Tracer.Start(ctx, "bundle.write") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -77,7 +79,7 @@ func (r *BundleServer) Read(ctx context.Context, request *v1.BundleReadRequest) ctx, span := internal.Tracer.Start(ctx, "bundle.read") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -100,7 +102,7 @@ func (r *BundleServer) Delete(ctx context.Context, request *v1.BundleDeleteReque ctx, span := internal.Tracer.Start(ctx, "bundle.delete") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } diff --git a/internal/servers/data_server.go b/internal/servers/data_server.go index ba7eb6378..ac24d30ce 100644 --- a/internal/servers/data_server.go +++ b/internal/servers/data_server.go @@ -4,6 +4,7 @@ import ( "context" "log/slog" + "buf.build/go/protovalidate" otelCodes "go.opentelemetry.io/otel/codes" api "go.opentelemetry.io/otel/metric" "google.golang.org/grpc/status" @@ -67,7 +68,7 @@ func (r *DataServer) ReadRelationships(ctx context.Context, request *v1.Relation size = 50 } - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -116,7 +117,7 @@ func (r *DataServer) ReadAttributes(ctx context.Context, request *v1.AttributeRe size = 50 } - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -160,7 +161,7 @@ func (r *DataServer) Write(ctx context.Context, request *v1.DataWriteRequest) (* ctx, span := internal.Tracer.Start(ctx, "data.write") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -256,7 +257,7 @@ func (r *DataServer) WriteRelationships(ctx context.Context, request *v1.Relatio ctx, span := internal.Tracer.Start(ctx, "relationships.write") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -322,7 +323,7 @@ func (r *DataServer) Delete(ctx context.Context, request *v1.DataDeleteRequest) ctx, span := internal.Tracer.Start(ctx, "data.delete") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -352,7 +353,7 @@ func (r *DataServer) DeleteRelationships(ctx context.Context, request *v1.Relati ctx, span := internal.Tracer.Start(ctx, "relationships.delete") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -382,7 +383,7 @@ func (r *DataServer) RunBundle(ctx context.Context, request *v1.BundleRunRequest ctx, span := internal.Tracer.Start(ctx, "bundle.run") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } diff --git a/internal/servers/permission_server.go b/internal/servers/permission_server.go index 1fc14ce15..a4a879d51 100644 --- a/internal/servers/permission_server.go +++ b/internal/servers/permission_server.go @@ -9,6 +9,8 @@ import ( otelCodes "go.opentelemetry.io/otel/codes" "google.golang.org/grpc/status" + "buf.build/go/protovalidate" + "github.com/Permify/permify/internal" "github.com/Permify/permify/internal/invoke" v1 "github.com/Permify/permify/pkg/pb/base/v1" @@ -33,7 +35,7 @@ func (r *PermissionServer) Check(ctx context.Context, request *v1.PermissionChec ctx, span := internal.Tracer.Start(ctx, "permissions.check") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -103,7 +105,7 @@ func (r *PermissionServer) BulkCheck(ctx context.Context, request *v1.Permission defer wg.Done() // Validate individual request - v := checkRequestItem.Validate() + v := protovalidate.Validate(checkRequestItem) if v != nil { resultChannel <- resultItem{ index: index, @@ -185,7 +187,7 @@ func (r *PermissionServer) Expand(ctx context.Context, request *v1.PermissionExp ctx, span := internal.Tracer.Start(ctx, "permissions.expand") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -206,7 +208,7 @@ func (r *PermissionServer) LookupEntity(ctx context.Context, request *v1.Permiss ctx, span := internal.Tracer.Start(ctx, "permissions.lookup-entity") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -227,7 +229,7 @@ func (r *PermissionServer) LookupEntityStream(request *v1.PermissionLookupEntity ctx, span := internal.Tracer.Start(server.Context(), "permissions.lookup-entity-stream") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return v } @@ -248,7 +250,7 @@ func (r *PermissionServer) LookupSubject(ctx context.Context, request *v1.Permis ctx, span := internal.Tracer.Start(ctx, "permissions.lookup-subject") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } @@ -269,7 +271,7 @@ func (r *PermissionServer) SubjectPermission(ctx context.Context, request *v1.Pe ctx, span := internal.Tracer.Start(ctx, "permissions.subject-permission") defer span.End() - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return nil, status.Error(GetStatus(v), v.Error()) // Return validation error } diff --git a/internal/servers/server_behavior_test.go b/internal/servers/server_behavior_test.go index 9c91fc50c..6c7e487ef 100644 --- a/internal/servers/server_behavior_test.go +++ b/internal/servers/server_behavior_test.go @@ -13,6 +13,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" gwruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "google.golang.org/grpc" "google.golang.org/grpc/codes" health "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" @@ -173,6 +174,30 @@ func (f *fakePermissionInvoker) SubjectPermission(_ context.Context, request *v1 }, nil } +type fakeServerStream struct { + grpc.ServerStream +} + +func (f *fakeServerStream) Context() context.Context { + return context.Background() +} + +type fakeLookupEntityStreamServer struct { + fakeServerStream +} + +func (f *fakeLookupEntityStreamServer) Send(*v1.PermissionLookupEntityStreamResponse) error { + return nil +} + +type fakeWatchStreamServer struct { + fakeServerStream +} + +func (f *fakeWatchStreamServer) Send(*v1.WatchResponse) error { + return nil +} + type testContextKey struct{} func testEntity() *v1.Entity { @@ -405,6 +430,214 @@ func TestPermissionServerValidationAndInvokerErrors(t *testing.T) { } } +func TestPermissionServerBulkCheckItemValidation(t *testing.T) { + invoker := &fakePermissionInvoker{} + server := NewPermissionServer(invoker) + + tests := []struct { + name string + permission string + wantDenied bool + }{ + {name: "empty permission", permission: "", wantDenied: true}, + {name: "permission longer than 64 bytes", permission: strings.Repeat("a", 65), wantDenied: true}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + invoker.checkReq = nil + bulk, err := server.BulkCheck(context.Background(), &v1.PermissionBulkCheckRequest{ + TenantId: "tenant-1", + Items: []*v1.PermissionBulkCheckRequestItem{{ + Entity: testEntity(), + Permission: tc.permission, + Subject: testSubject(), + }}, + }) + if err != nil { + t.Fatalf("unexpected bulk check error: %v", err) + } + if len(bulk.GetResults()) != 1 { + t.Fatalf("expected 1 result, got %d", len(bulk.GetResults())) + } + denied := bulk.GetResults()[0].GetCan() == v1.CheckResult_CHECK_RESULT_DENIED + if denied != tc.wantDenied { + t.Fatalf("denied = %v, want %v", denied, tc.wantDenied) + } + if tc.wantDenied && invoker.checkReq != nil { + t.Fatal("invalid bulk item should not reach invoker") + } + }) + } +} + +func TestPermissionServerLookupEntityStreamValidation(t *testing.T) { + invoker := &fakePermissionInvoker{} + server := NewPermissionServer(invoker) + + tests := []struct { + name string + tenantID string + }{ + {name: "empty tenant_id", tenantID: ""}, + {name: "tenant_id longer than 128 bytes", tenantID: strings.Repeat("a", 129)}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + invoker.lookupEntityReq = nil + req := validPermissionLookupEntityRequest() + req.TenantId = tc.tenantID + err := server.LookupEntityStream(req, &fakeLookupEntityStreamServer{}) + if err == nil { + t.Fatal("expected validation to fail") + } + if invoker.lookupEntityReq != nil { + t.Fatal("invalid lookup entity stream request should not reach invoker") + } + }) + } +} + +func TestDataServerValidation(t *testing.T) { + server := NewDataServer(nil, nil, nil, nil) + ctx := context.Background() + + tenantIDs := []struct { + name string + id string + }{ + {name: "empty tenant_id", id: ""}, + {name: "tenant_id longer than 128 bytes", id: strings.Repeat("a", 129)}, + } + + methods := []struct { + name string + call func(tenantID string) error + }{ + { + name: "ReadRelationships", + call: func(tenantID string) error { + _, err := server.ReadRelationships(ctx, &v1.RelationshipReadRequest{ + TenantId: tenantID, + Metadata: &v1.RelationshipReadRequestMetadata{}, + Filter: &v1.TupleFilter{}, + }) + return err + }, + }, + { + name: "ReadAttributes", + call: func(tenantID string) error { + _, err := server.ReadAttributes(ctx, &v1.AttributeReadRequest{ + TenantId: tenantID, + Metadata: &v1.AttributeReadRequestMetadata{}, + Filter: &v1.AttributeFilter{}, + }) + return err + }, + }, + { + name: "Write", + call: func(tenantID string) error { + _, err := server.Write(ctx, &v1.DataWriteRequest{ + TenantId: tenantID, + Metadata: &v1.DataWriteRequestMetadata{}, + }) + return err + }, + }, + { + name: "WriteRelationships", + call: func(tenantID string) error { + _, err := server.WriteRelationships(ctx, &v1.RelationshipWriteRequest{ + TenantId: tenantID, + Metadata: &v1.RelationshipWriteRequestMetadata{}, + Tuples: []*v1.Tuple{{Entity: testEntity(), Relation: "viewer", Subject: testSubject()}}, + }) + return err + }, + }, + { + name: "Delete", + call: func(tenantID string) error { + _, err := server.Delete(ctx, &v1.DataDeleteRequest{ + TenantId: tenantID, + TupleFilter: &v1.TupleFilter{ + Entity: &v1.EntityFilter{Type: "document", Ids: []string{"document-1"}}, + Relation: "viewer", + Subject: &v1.SubjectFilter{Type: "user", Ids: []string{"user-1"}}, + }, + AttributeFilter: &v1.AttributeFilter{}, + }) + return err + }, + }, + { + name: "DeleteRelationships", + call: func(tenantID string) error { + _, err := server.DeleteRelationships(ctx, &v1.RelationshipDeleteRequest{ + TenantId: tenantID, + Filter: &v1.TupleFilter{ + Entity: &v1.EntityFilter{Type: "document", Ids: []string{"document-1"}}, + Relation: "viewer", + Subject: &v1.SubjectFilter{Type: "user", Ids: []string{"user-1"}}, + }, + }) + return err + }, + }, + { + name: "RunBundle", + call: func(tenantID string) error { + _, err := server.RunBundle(ctx, &v1.BundleRunRequest{TenantId: tenantID}) + return err + }, + }, + } + + for _, method := range methods { + for _, tenant := range tenantIDs { + t.Run(method.name+"/"+tenant.name, func(t *testing.T) { + if err := method.call(tenant.id); err == nil { + t.Fatal("expected validation to fail") + } + }) + } + } + + t.Run("WriteRelationships/empty tuples", func(t *testing.T) { + _, err := server.WriteRelationships(ctx, &v1.RelationshipWriteRequest{ + TenantId: "a", + Metadata: &v1.RelationshipWriteRequestMetadata{}, + }) + if err == nil { + t.Fatal("expected validation to fail") + } + }) +} + +func TestWatchServerValidation(t *testing.T) { + server := NewWatchServer(nil, nil) + + tests := []struct { + name string + tenantID string + }{ + {name: "empty tenant_id", tenantID: ""}, + {name: "tenant_id longer than 128 bytes", tenantID: strings.Repeat("a", 129)}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + err := server.Watch(&v1.WatchRequest{TenantId: tc.tenantID}, &fakeWatchStreamServer{}) + if err == nil { + t.Fatal("expected validation to fail") + } + }) + } +} + func TestTenancyServer(t *testing.T) { store := &fakeTenantStore{ tenants: []*v1.Tenant{{Id: "tenant-1", Name: "Tenant One"}}, diff --git a/internal/servers/watch_server.go b/internal/servers/watch_server.go index f07beac9d..cdc61df14 100644 --- a/internal/servers/watch_server.go +++ b/internal/servers/watch_server.go @@ -1,6 +1,7 @@ package servers import ( + "buf.build/go/protovalidate" "google.golang.org/grpc/status" "github.com/Permify/permify/internal" @@ -32,7 +33,7 @@ func (r *WatchServer) Watch(request *v1.WatchRequest, server v1.Watch_WatchServe defer span.End() // Ensure the span ends when the function returns. // Validate the incoming request. - v := request.Validate() + v := protovalidate.Validate(request) if v != nil { return v // Return validation error, if any. } diff --git a/internal/storage/postgres/data_writer.go b/internal/storage/postgres/data_writer.go index 1c2ada851..9d77a10b9 100644 --- a/internal/storage/postgres/data_writer.go +++ b/internal/storage/postgres/data_writer.go @@ -312,6 +312,7 @@ func (w *DataWriter) delete( // Return snapshot token return snapshot.NewToken(xid, snapshotValue).Encode(), nil } // End Delete + // Helper functions for RunBundle // RunBundle helper function // RunBundle implementation diff --git a/internal/storage/postgres/tenant_writer_test.go b/internal/storage/postgres/tenant_writer_test.go index f3a3949fc..5dde173e1 100644 --- a/internal/storage/postgres/tenant_writer_test.go +++ b/internal/storage/postgres/tenant_writer_test.go @@ -9,12 +9,13 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/rs/xid" + "github.com/Permify/permify/internal/storage" "github.com/Permify/permify/pkg/database" base "github.com/Permify/permify/pkg/pb/base/v1" "github.com/Permify/permify/pkg/testinstance" "github.com/Permify/permify/pkg/tuple" - "github.com/rs/xid" ) var _ = Describe("TenantWriter", func() { diff --git a/pkg/database/postgres/xid8.go b/pkg/database/postgres/xid8.go index cbfc9af19..60ce5eed9 100644 --- a/pkg/database/postgres/xid8.go +++ b/pkg/database/postgres/xid8.go @@ -16,7 +16,7 @@ func (x *XID8) Set(src interface{}) error { // Get returns the underlying value func (x XID8) Get() interface{} { - return (pguint64)(x).Get() + return pguint64(x).Get() } // AssignTo assigns the value to the destination @@ -36,12 +36,12 @@ func (x *XID8) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error { // EncodeText encodes to text format func (x XID8) EncodeText(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) { - return (pguint64)(x).EncodeText(ci, buf) + return pguint64(x).EncodeText(ci, buf) } // EncodeBinary encodes to binary format func (x XID8) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) { - return (pguint64)(x).EncodeBinary(ci, buf) + return pguint64(x).EncodeBinary(ci, buf) } // Scan implements the database/sql Scanner interface @@ -51,5 +51,5 @@ func (x *XID8) Scan(src interface{}) error { // Value implements the database/sql/driver Valuer interface func (x XID8) Value() (driver.Value, error) { - return (pguint64)(x).Value() + return pguint64(x).Value() } diff --git a/pkg/dsl/parser/parser.go b/pkg/dsl/parser/parser.go index b65012eec..1367e26d1 100644 --- a/pkg/dsl/parser/parser.go +++ b/pkg/dsl/parser/parser.go @@ -131,6 +131,7 @@ func (p *Parser) previousTokenIs(tokens ...token.Type) bool { // Check if previo } // All types checked return false // No match found } // End previousTokenIs + // peekTokenIs checks if the Parser's peekToken is any of the given token types func (p *Parser) peekTokenIs(tokens ...token.Type) bool { // iterate through the given token types and check if any of them match the peekToken's type diff --git a/pkg/dsl/parser/parser_test.go b/pkg/dsl/parser/parser_test.go index 5365decf0..1ea25832a 100644 --- a/pkg/dsl/parser/parser_test.go +++ b/pkg/dsl/parser/parser_test.go @@ -2,15 +2,18 @@ package parser // Parser package tests import ( // Test imports "testing" // Testing framework + . "github.com/onsi/ginkgo/v2" // BDD framework + . "github.com/onsi/gomega" // Matchers + "github.com/Permify/permify/pkg/dsl/ast" // AST types - . "github.com/onsi/ginkgo/v2" // BDD framework - . "github.com/onsi/gomega" // Matchers ) // End imports + // TestParser - Parser test suite entry point func TestParser(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "parser-suite") -} // End TestParser +} // End TestParser + var _ = Describe("parser", func() { // Parser test suite Context("Statement", func() { It("Case // Test case 1 - Repository with parent and owner relations and read action", func() { diff --git a/pkg/pb/base/v1/base.pb.go b/pkg/pb/base/v1/base.pb.go index 9de6e7356..878f607f9 100644 --- a/pkg/pb/base/v1/base.pb.go +++ b/pkg/pb/base/v1/base.pb.go @@ -7,7 +7,7 @@ package basev1 import ( - _ "github.com/envoyproxy/protoc-gen-validate/validate" + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -3280,23 +3280,23 @@ var File_base_v1_base_proto protoreflect.FileDescriptor const file_base_v1_base_proto_rawDesc = "" + "\n" + - "\x12base/v1/base.proto\x12\abase.v1\x1a&google/api/expr/v1alpha1/checked.proto\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17validate/validate.proto\"\x92\x01\n" + + "\x12base/v1/base.proto\x12\abase.v1\x1a\x1bbuf/validate/validate.proto\x1a&google/api/expr/v1alpha1/checked.proto\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x92\x01\n" + "\aContext\x12&\n" + "\x06tuples\x18\x01 \x03(\v2\x0e.base.v1.TupleR\x06tuples\x122\n" + "\n" + "attributes\x18\x02 \x03(\v2\x12.base.v1.AttributeR\n" + "attributes\x12+\n" + - "\x04data\x18\x03 \x01(\v2\x17.google.protobuf.StructR\x04data\"{\n" + - "\x05Child\x12-\n" + - "\x04leaf\x18\x01 \x01(\v2\r.base.v1.LeafB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\x04leaf\x126\n" + - "\arewrite\x18\x02 \x01(\v2\x10.base.v1.RewriteB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\arewriteB\v\n" + - "\x04type\x12\x03\xf8B\x01\"\xbb\x02\n" + - "\x04Leaf\x12P\n" + - "\x11computed_user_set\x18\x01 \x01(\v2\x18.base.v1.ComputedUserSetB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\x0fcomputedUserSet\x12N\n" + - "\x11tuple_to_user_set\x18\x02 \x01(\v2\x17.base.v1.TupleToUserSetB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\x0etupleToUserSet\x12U\n" + - "\x12computed_attribute\x18\x03 \x01(\v2\x1a.base.v1.ComputedAttributeB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\x11computedAttribute\x12-\n" + - "\x04call\x18\x04 \x01(\v2\r.base.v1.CallB\b\xfaB\x05\x8a\x01\x02\x10\x01H\x00R\x04callB\v\n" + - "\x04type\x12\x03\xf8B\x01\"\xf0\x01\n" + + "\x04data\x18\x03 \x01(\v2\x17.google.protobuf.StructR\x04data\"i\n" + + "\x05Child\x12#\n" + + "\x04leaf\x18\x01 \x01(\v2\r.base.v1.LeafH\x00R\x04leaf\x12,\n" + + "\arewrite\x18\x02 \x01(\v2\x10.base.v1.RewriteH\x00R\arewriteB\r\n" + + "\x04type\x12\x05\xbaH\x02\b\x01\"\x95\x02\n" + + "\x04Leaf\x12F\n" + + "\x11computed_user_set\x18\x01 \x01(\v2\x18.base.v1.ComputedUserSetH\x00R\x0fcomputedUserSet\x12D\n" + + "\x11tuple_to_user_set\x18\x02 \x01(\v2\x17.base.v1.TupleToUserSetH\x00R\x0etupleToUserSet\x12K\n" + + "\x12computed_attribute\x18\x03 \x01(\v2\x1a.base.v1.ComputedAttributeH\x00R\x11computedAttribute\x12#\n" + + "\x04call\x18\x04 \x01(\v2\r.base.v1.CallH\x00R\x04callB\r\n" + + "\x04type\x12\x05\xbaH\x02\b\x01\"\xf0\x01\n" + "\aRewrite\x12G\n" + "\x11rewrite_operation\x18\x01 \x01(\x0e2\x1a.base.v1.Rewrite.OperationR\x10rewriteOperation\x12*\n" + "\bchildren\x18\x02 \x03(\v2\x0e.base.v1.ChildR\bchildren\"p\n" + @@ -3325,7 +3325,7 @@ const file_base_v1_base_proto_rawDesc = "" + "\x10REFERENCE_ENTITY\x10\x01\x12\x12\n" + "\x0eREFERENCE_RULE\x10\x02\"\xdc\x06\n" + "\x10EntityDefinition\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12F\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12F\n" + "\trelations\x18\x02 \x03(\v2(.base.v1.EntityDefinition.RelationsEntryR\trelations\x12L\n" + "\vpermissions\x18\x03 \x03(\v2*.base.v1.EntityDefinition.PermissionsEntryR\vpermissions\x12I\n" + "\n" + @@ -3352,7 +3352,7 @@ const file_base_v1_base_proto_rawDesc = "" + "\x14REFERENCE_PERMISSION\x10\x02\x12\x17\n" + "\x13REFERENCE_ATTRIBUTE\x10\x03\"\xa3\x02\n" + "\x0eRuleDefinition\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12D\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12D\n" + "\targuments\x18\x02 \x03(\v2&.base.v1.RuleDefinition.ArgumentsEntryR\targuments\x12E\n" + "\n" + "expression\x18\x03 \x01(\v2%.google.api.expr.v1alpha1.CheckedExprR\n" + @@ -3361,20 +3361,20 @@ const file_base_v1_base_proto_rawDesc = "" + "\x03key\x18\x01 \x01(\tR\x03key\x12,\n" + "\x05value\x18\x02 \x01(\x0e2\x16.base.v1.AttributeTypeR\x05value:\x028\x01\"q\n" + "\x13AttributeDefinition\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12*\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12*\n" + "\x04type\x18\x02 \x01(\x0e2\x16.base.v1.AttributeTypeR\x04type\"\x91\x01\n" + "\x12RelationDefinition\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12K\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12K\n" + "\x13relation_references\x18\x02 \x03(\v2\x1a.base.v1.RelationReferenceR\x12relationReferences\"l\n" + "\x14PermissionDefinition\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12$\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\x12$\n" + "\x05child\x18\x02 \x01(\v2\x0e.base.v1.ChildR\x05child\"~\n" + "\x11RelationReference\x12.\n" + - "\x04type\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x129\n" + - "\brelation\x18\x02 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x01R\brelation\"l\n" + + "\x04type\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x129\n" + + "\brelation\x18\x02 \x01(\tB\x1d\xbaH\x1a\xd8\x01\x01r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"l\n" + "\bEntrance\x12.\n" + - "\x04type\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x120\n" + - "\x05value\x18\x02 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x05value\"_\n" + + "\x04type\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x120\n" + + "\x05value\x18\x02 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x05value\"_\n" + "\bArgument\x12K\n" + "\x12computed_attribute\x18\x01 \x01(\v2\x1a.base.v1.ComputedAttributeH\x00R\x11computedAttributeB\x06\n" + "\x04type\"T\n" + @@ -3382,20 +3382,20 @@ const file_base_v1_base_proto_rawDesc = "" + "\trule_name\x18\x01 \x01(\tR\bruleName\x12/\n" + "\targuments\x18\x02 \x03(\v2\x11.base.v1.ArgumentR\targuments\"C\n" + "\x11ComputedAttribute\x12.\n" + - "\x04name\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\"I\n" + + "\x04name\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04name\"I\n" + "\x0fComputedUserSet\x126\n" + - "\brelation\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"u\n" + + "\brelation\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"u\n" + "\x0eTupleToUserSet\x12-\n" + "\btupleSet\x18\x01 \x01(\v2\x11.base.v1.TupleSetR\btupleSet\x124\n" + "\bcomputed\x18\x02 \x01(\v2\x18.base.v1.ComputedUserSetR\bcomputed\"B\n" + "\bTupleSet\x126\n" + - "\brelation\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"\xa8\x01\n" + - "\x05Tuple\x121\n" + - "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x126\n" + - "\brelation\x18\x02 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\x124\n" + - "\asubject\x18\x03 \x01(\v2\x10.base.v1.SubjectB\b\xfaB\x05\x8a\x01\x02\x10\x01R\asubject\"\x88\x01\n" + - "\tAttribute\x121\n" + - "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x12\x1c\n" + + "\brelation\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"\xa4\x01\n" + + "\x05Tuple\x12/\n" + + "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x126\n" + + "\brelation\x18\x02 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\x122\n" + + "\asubject\x18\x03 \x01(\v2\x10.base.v1.SubjectB\x06\xbaH\x03\xc8\x01\x01R\asubject\"\x86\x01\n" + + "\tAttribute\x12/\n" + + "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x12\x1c\n" + "\tattribute\x18\x02 \x01(\tR\tattribute\x12*\n" + "\x05value\x18\x03 \x01(\v2\x14.google.protobuf.AnyR\x05value\"0\n" + "\x06Tuples\x12&\n" + @@ -3406,15 +3406,15 @@ const file_base_v1_base_proto_rawDesc = "" + "attributes\x18\x01 \x03(\v2\x12.base.v1.AttributeR\n" + "attributes\"u\n" + "\x06Entity\x12.\n" + - "\x04type\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x12;\n" + - "\x02id\x18\x02 \x01(\tB+\xfaB(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\x02id\"~\n" + - "\x11EntityAndRelation\x121\n" + - "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x126\n" + - "\brelation\x18\x02 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"\xb1\x01\n" + + "\x04type\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x12;\n" + + "\x02id\x18\x02 \x01(\tB+\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\x02id\"|\n" + + "\x11EntityAndRelation\x12/\n" + + "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x126\n" + + "\brelation\x18\x02 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"\xb1\x01\n" + "\aSubject\x12.\n" + - "\x04type\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x12;\n" + - "\x02id\x18\x02 \x01(\tB+\xfaB(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\x02id\x129\n" + - "\brelation\x18\x03 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x01R\brelation\"`\n" + + "\x04type\x18\x01 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\x04type\x12;\n" + + "\x02id\x18\x02 \x01(\tB+\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\x02id\x129\n" + + "\brelation\x18\x03 \x01(\tB\x1d\xbaH\x1a\xd8\x01\x01r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"`\n" + "\x0fAttributeFilter\x12-\n" + "\x06entity\x18\x01 \x01(\v2\x15.base.v1.EntityFilterR\x06entity\x12\x1e\n" + "\n" + @@ -3422,7 +3422,7 @@ const file_base_v1_base_proto_rawDesc = "" + "attributes\"\xa9\x01\n" + "\vTupleFilter\x12-\n" + "\x06entity\x18\x01 \x01(\v2\x15.base.v1.EntityFilterR\x06entity\x129\n" + - "\brelation\x18\x02 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x01R\brelation\x120\n" + + "\brelation\x18\x02 \x01(\tB\x1d\xbaH\x1a\xd8\x01\x01r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\x120\n" + "\asubject\x18\x03 \x01(\v2\x16.base.v1.SubjectFilterR\asubject\"4\n" + "\fEntityFilter\x12\x12\n" + "\x04type\x18\x01 \x01(\tR\x04type\x12\x10\n" + @@ -3430,7 +3430,7 @@ const file_base_v1_base_proto_rawDesc = "" + "\rSubjectFilter\x12\x12\n" + "\x04type\x18\x01 \x01(\tR\x04type\x12\x10\n" + "\x03ids\x18\x02 \x03(\tR\x03ids\x129\n" + - "\brelation\x18\x03 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x01R\brelation\"\xf0\x01\n" + + "\brelation\x18\x03 \x01(\tB\x1d\xbaH\x1a\xd8\x01\x01r\x15(@2\x11^[a-zA-Z_]{1,64}$R\brelation\"\xf0\x01\n" + "\x0eExpandTreeNode\x12?\n" + "\toperation\x18\x01 \x01(\x0e2!.base.v1.ExpandTreeNode.OperationR\toperation\x12+\n" + "\bchildren\x18\x02 \x03(\v2\x0f.base.v1.ExpandR\bchildren\"p\n" + @@ -3447,13 +3447,13 @@ const file_base_v1_base_proto_rawDesc = "" + "\targuments\x18\x03 \x03(\v2\x11.base.v1.ArgumentR\targuments\x121\n" + "\x06expand\x18\x04 \x01(\v2\x17.base.v1.ExpandTreeNodeH\x00R\x06expand\x12)\n" + "\x04leaf\x18\x05 \x01(\v2\x13.base.v1.ExpandLeafH\x00R\x04leafB\x06\n" + - "\x04node\"\xa3\x01\n" + + "\x04node\"\xa5\x01\n" + "\n" + "ExpandLeaf\x12/\n" + "\bsubjects\x18\x01 \x01(\v2\x11.base.v1.SubjectsH\x00R\bsubjects\x12)\n" + "\x06values\x18\x02 \x01(\v2\x0f.base.v1.ValuesH\x00R\x06values\x12,\n" + - "\x05value\x18\x03 \x01(\v2\x14.google.protobuf.AnyH\x00R\x05valueB\v\n" + - "\x04type\x12\x03\xf8B\x01\"\x8e\x01\n" + + "\x05value\x18\x03 \x01(\v2\x14.google.protobuf.AnyH\x00R\x05valueB\r\n" + + "\x04type\x12\x05\xbaH\x02\b\x01\"\x8e\x01\n" + "\x06Values\x123\n" + "\x06values\x18\x01 \x03(\v2\x1b.base.v1.Values.ValuesEntryR\x06values\x1aO\n" + "\vValuesEntry\x12\x10\n" + @@ -3471,7 +3471,7 @@ const file_base_v1_base_proto_rawDesc = "" + "\n" + "snap_token\x18\x01 \x01(\tR\n" + "snap_token\x127\n" + - "\fdata_changes\x18\x02 \x03(\v2\x13.base.v1.DataChangeR\fdata_changes\"\x86\x02\n" + + "\fdata_changes\x18\x02 \x03(\v2\x13.base.v1.DataChangeR\fdata_changes\"\x88\x02\n" + "\n" + "DataChange\x12;\n" + "\toperation\x18\x01 \x01(\x0e2\x1d.base.v1.DataChange.OperationR\toperation\x12&\n" + @@ -3480,8 +3480,8 @@ const file_base_v1_base_proto_rawDesc = "" + "\tOperation\x12\x19\n" + "\x15OPERATION_UNSPECIFIED\x10\x00\x12\x14\n" + "\x10OPERATION_CREATE\x10\x01\x12\x14\n" + - "\x10OPERATION_DELETE\x10\x02B\v\n" + - "\x04type\x12\x03\xf8B\x01\"!\n" + + "\x10OPERATION_DELETE\x10\x02B\r\n" + + "\x04type\x12\x05\xbaH\x02\b\x01\"!\n" + "\vStringValue\x12\x12\n" + "\x04data\x18\x01 \x01(\tR\x04data\"\"\n" + "\fIntegerValue\x12\x12\n" + diff --git a/pkg/pb/base/v1/service.pb.go b/pkg/pb/base/v1/service.pb.go index fe4c4ce86..a6f12b196 100644 --- a/pkg/pb/base/v1/service.pb.go +++ b/pkg/pb/base/v1/service.pb.go @@ -7,7 +7,7 @@ package basev1 import ( - _ "github.com/envoyproxy/protoc-gen-validate/validate" + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -3898,15 +3898,15 @@ var File_base_v1_service_proto protoreflect.FileDescriptor const file_base_v1_service_proto_rawDesc = "" + "\n" + - "\x15base/v1/service.proto\x12\abase.v1\x1a\x12base/v1/base.proto\x1a\x1cgoogle/api/annotations.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x17validate/validate.proto\"\x80\a\n" + - "\x16PermissionCheckRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12M\n" + - "\bmetadata\x18\x02 \x01(\v2'.base.v1.PermissionCheckRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12D\n" + - "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\x1b\x92A\x10J\x0e\"repository:1\"\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x12v\n" + + "\x15base/v1/service.proto\x12\abase.v1\x1a\x12base/v1/base.proto\x1a\x1bbuf/validate/validate.proto\x1a\x1cgoogle/api/annotations.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\xf4\x06\n" + + "\x16PermissionCheckRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12K\n" + + "\bmetadata\x18\x02 \x01(\v2'.base.v1.PermissionCheckRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12B\n" + + "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\x19\x92A\x10J\x0e\"repository:1\"\xbaH\x03\xc8\x01\x01R\x06entity\x12s\n" + "\n" + - "permission\x18\x04 \x01(\tBV\x92A624The action the user wants to perform on the resource\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x00R\n" + - "permission\x124\n" + - "\asubject\x18\x05 \x01(\v2\x10.base.v1.SubjectB\b\xfaB\x05\x8a\x01\x02\x10\x01R\asubject\x12\xc4\x01\n" + + "permission\x18\x04 \x01(\tBS\x92A624The action the user wants to perform on the resource\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\n" + + "permission\x122\n" + + "\asubject\x18\x05 \x01(\v2\x10.base.v1.SubjectB\x06\xbaH\x03\xc8\x01\x01R\asubject\x12\xc4\x01\n" + "\acontext\x18\x06 \x01(\v2\x10.base.v1.ContextB\x97\x01\x92A\x93\x012\x90\x01Contextual data that can be dynamically added to permission check requests. See details on [Contextual Data](../../operations/contextual-tuples)R\acontext\x12/\n" + "\targuments\x18\a \x03(\v2\x11.base.v1.ArgumentR\targuments\"\xb2\x02\n" + "\x1ePermissionCheckRequestMetadata\x12&\n" + @@ -3914,33 +3914,33 @@ const file_base_v1_service_proto_rawDesc = "" + "\n" + "snap_token\x18\x02 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + "snap_token\x12\\\n" + - "\x05depth\x18\x03 \x01(\x05BF\x92A<2:Query limit when if recursive database queries got in loop\xfaB\x04\x1a\x02(\x03R\x05depth\"\x87\x01\n" + + "\x05depth\x18\x03 \x01(\x05BF\x92A<2:Query limit when if recursive database queries got in loop\xbaH\x04\x1a\x02(\x03R\x05depth\"\x87\x01\n" + "\x17PermissionCheckResponse\x12&\n" + "\x03can\x18\x01 \x01(\x0e2\x14.base.v1.CheckResultR\x03can\x12D\n" + "\bmetadata\x18\x02 \x01(\v2(.base.v1.PermissionCheckResponseMetadataR\bmetadata\"C\n" + "\x1fPermissionCheckResponseMetadata\x12 \n" + - "\vcheck_count\x18\x01 \x01(\x05R\vcheck_count\"\x94\x02\n" + - "\x1ePermissionBulkCheckRequestItem\x12D\n" + - "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\x1b\x92A\x10J\x0e\"repository:1\"\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x12v\n" + + "\vcheck_count\x18\x01 \x01(\x05R\vcheck_count\"\x8d\x02\n" + + "\x1ePermissionBulkCheckRequestItem\x12B\n" + + "\x06entity\x18\x01 \x01(\v2\x0f.base.v1.EntityB\x19\x92A\x10J\x0e\"repository:1\"\xbaH\x03\xc8\x01\x01R\x06entity\x12s\n" + "\n" + - "permission\x18\x02 \x01(\tBV\x92A624The action the user wants to perform on the resource\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x00R\n" + - "permission\x124\n" + - "\asubject\x18\x03 \x01(\v2\x10.base.v1.SubjectB\b\xfaB\x05\x8a\x01\x02\x10\x01R\asubject\"\xdb\x05\n" + - "\x1aPermissionBulkCheckRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12M\n" + - "\bmetadata\x18\x02 \x01(\v2'.base.v1.PermissionCheckRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12I\n" + + "permission\x18\x02 \x01(\tBS\x92A624The action the user wants to perform on the resource\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\n" + + "permission\x122\n" + + "\asubject\x18\x03 \x01(\v2\x10.base.v1.SubjectB\x06\xbaH\x03\xc8\x01\x01R\asubject\"\xd6\x05\n" + + "\x1aPermissionBulkCheckRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12K\n" + + "\bmetadata\x18\x02 \x01(\v2'.base.v1.PermissionCheckRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12I\n" + "\x05items\x18\x03 \x03(\v2'.base.v1.PermissionBulkCheckRequestItemB\n" + - "\xfaB\a\x92\x01\x04\b\x01\x10dR\x05items\x12\xc4\x01\n" + + "\xbaH\a\x92\x01\x04\b\x01\x10dR\x05items\x12\xc4\x01\n" + "\acontext\x18\x04 \x01(\v2\x10.base.v1.ContextB\x97\x01\x92A\x93\x012\x90\x01Contextual data that can be dynamically added to permission check requests. See details on [Contextual Data](../../operations/contextual-tuples)R\acontext\x12/\n" + "\targuments\x18\x05 \x03(\v2\x11.base.v1.ArgumentR\targuments\"Y\n" + "\x1bPermissionBulkCheckResponse\x12:\n" + - "\aresults\x18\x01 \x03(\v2 .base.v1.PermissionCheckResponseR\aresults\"\xe5\x04\n" + - "\x17PermissionExpandRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12N\n" + - "\bmetadata\x18\x02 \x01(\v2(.base.v1.PermissionExpandRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x121\n" + - "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x12=\n" + + "\aresults\x18\x01 \x03(\v2 .base.v1.PermissionCheckResponseR\aresults\"\xde\x04\n" + + "\x17PermissionExpandRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12L\n" + + "\bmetadata\x18\x02 \x01(\v2(.base.v1.PermissionExpandRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12/\n" + + "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x12=\n" + "\n" + - "permission\x18\x04 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x01R\n" + + "permission\x18\x04 \x01(\tB\x1d\xbaH\x1a\xd8\x01\x01r\x15(@2\x11^[a-zA-Z_]{1,64}$R\n" + "permission\x12*\n" + "\acontext\x18\x05 \x01(\v2\x10.base.v1.ContextR\acontext\x12/\n" + "\targuments\x18\x06 \x03(\v2\x11.base.v1.ArgumentR\targuments\"\xd6\x01\n" + @@ -3950,19 +3950,20 @@ const file_base_v1_service_proto_rawDesc = "" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\"?\n" + "\x18PermissionExpandResponse\x12#\n" + - "\x04tree\x18\x01 \x01(\v2\x0f.base.v1.ExpandR\x04tree\"\x81\a\n" + - "\x1dPermissionLookupEntityRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12T\n" + - "\bmetadata\x18\x02 \x01(\v2..base.v1.PermissionLookupEntityRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12?\n" + - "\ventity_type\x18\x03 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x00R\ventity_type\x12=\n" + + "\x04tree\x18\x01 \x01(\v2\x0f.base.v1.ExpandR\x04tree\"\xf5\x06\n" + + "\x1dPermissionLookupEntityRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12R\n" + + "\bmetadata\x18\x02 \x01(\v2..base.v1.PermissionLookupEntityRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12<\n" + + "\ventity_type\x18\x03 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\ventity_type\x12:\n" + "\n" + - "permission\x18\x04 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x00R\n" + - "permission\x124\n" + - "\asubject\x18\x05 \x01(\v2\x10.base.v1.SubjectB\b\xfaB\x05\x8a\x01\x02\x10\x01R\asubject\x12*\n" + + "permission\x18\x04 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\n" + + "permission\x122\n" + + "\asubject\x18\x05 \x01(\v2\x10.base.v1.SubjectB\x06\xbaH\x03\xc8\x01\x01R\asubject\x12*\n" + "\acontext\x18\x06 \x01(\v2\x10.base.v1.ContextR\acontext\x12G\n" + - "\x05scope\x18\a \x03(\v21.base.v1.PermissionLookupEntityRequest.ScopeEntryR\x05scope\x12'\n" + - "\tpage_size\x18\b \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\t \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\x1aS\n" + + "\x05scope\x18\a \x03(\v21.base.v1.PermissionLookupEntityRequest.ScopeEntryR\x05scope\x12(\n" + + "\tpage_size\x18\b \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\t \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\x1aS\n" + "\n" + "ScopeEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12/\n" + @@ -3972,7 +3973,7 @@ const file_base_v1_service_proto_rawDesc = "" + "\n" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\x12]\n" + - "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xfaB\x04\x1a\x02(\x03R\x05depth\"l\n" + + "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xbaH\x04\x1a\x02(\x03R\x05depth\"l\n" + "\x1ePermissionLookupEntityResponse\x12\x1e\n" + "\n" + "entity_ids\x18\x01 \x03(\tR\n" + @@ -3980,15 +3981,15 @@ const file_base_v1_service_proto_rawDesc = "" + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"p\n" + "$PermissionLookupEntityStreamResponse\x12\x1c\n" + "\tentity_id\x18\x01 \x01(\tR\tentity_id\x12*\n" + - "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xe9\x05\n" + - "\x1dPermissionEntityFilterRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12T\n" + - "\bmetadata\x18\x02 \x01(\v2..base.v1.PermissionEntityFilterRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12-\n" + + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xe4\x05\n" + + "\x1dPermissionEntityFilterRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12R\n" + + "\bmetadata\x18\x02 \x01(\v2..base.v1.PermissionEntityFilterRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12-\n" + "\bentrance\x18\x03 \x01(\v2\x11.base.v1.EntranceR\bentrance\x12*\n" + "\asubject\x18\x04 \x01(\v2\x10.base.v1.SubjectR\asubject\x12*\n" + "\acontext\x18\x05 \x01(\v2\x10.base.v1.ContextR\acontext\x12G\n" + "\x05scope\x18\x06 \x03(\v21.base.v1.PermissionEntityFilterRequest.ScopeEntryR\x05scope\x12 \n" + - "\x06cursor\x18\a \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x06cursor\x1aS\n" + + "\x06cursor\x18\a \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x06cursor\x1aS\n" + "\n" + "ScopeEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12/\n" + @@ -3998,33 +3999,34 @@ const file_base_v1_service_proto_rawDesc = "" + "\n" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\x12]\n" + - "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xfaB\x04\x1a\x02(\x03R\x05depth\"\xa6\x06\n" + - "\x1ePermissionLookupSubjectRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12U\n" + - "\bmetadata\x18\x02 \x01(\v2/.base.v1.PermissionLookupSubjectRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x121\n" + - "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x12=\n" + + "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xbaH\x04\x1a\x02(\x03R\x05depth\"\x9b\x06\n" + + "\x1ePermissionLookupSubjectRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12S\n" + + "\bmetadata\x18\x02 \x01(\v2/.base.v1.PermissionLookupSubjectRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12/\n" + + "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x12:\n" + "\n" + - "permission\x18\x04 \x01(\tB\x1d\xfaB\x1ar\x18(@2\x11^[a-zA-Z_]{1,64}$\xd0\x01\x00R\n" + - "permission\x12R\n" + - "\x11subject_reference\x18\x05 \x01(\v2\x1a.base.v1.RelationReferenceB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x11subject_reference\x12*\n" + + "permission\x18\x04 \x01(\tB\x1a\xbaH\x17r\x15(@2\x11^[a-zA-Z_]{1,64}$R\n" + + "permission\x12P\n" + + "\x11subject_reference\x18\x05 \x01(\v2\x1a.base.v1.RelationReferenceB\x06\xbaH\x03\xc8\x01\x01R\x11subject_reference\x12*\n" + "\acontext\x18\x06 \x01(\v2\x10.base.v1.ContextR\acontext\x12/\n" + - "\targuments\x18\a \x03(\v2\x11.base.v1.ArgumentR\targuments\x12'\n" + - "\tpage_size\x18\b \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\t \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\"\xbc\x02\n" + + "\targuments\x18\a \x03(\v2\x11.base.v1.ArgumentR\targuments\x12(\n" + + "\tpage_size\x18\b \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\t \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\"\xbc\x02\n" + "&PermissionLookupSubjectRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\x12\x8a\x01\n" + "\n" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\x12]\n" + - "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xfaB\x04\x1a\x02(\x03R\x05depth\"o\n" + + "\x05depth\x18\x03 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xbaH\x04\x1a\x02(\x03R\x05depth\"o\n" + "\x1fPermissionLookupSubjectResponse\x12 \n" + "\vsubject_ids\x18\x01 \x03(\tR\vsubject_ids\x12*\n" + - "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xc1\x04\n" + - "\"PermissionSubjectPermissionRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12Y\n" + - "\bmetadata\x18\x02 \x01(\v23.base.v1.PermissionSubjectPermissionRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x121\n" + - "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06entity\x124\n" + - "\asubject\x18\x04 \x01(\v2\x10.base.v1.SubjectB\b\xfaB\x05\x8a\x01\x02\x10\x01R\asubject\x12*\n" + + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xb8\x04\n" + + "\"PermissionSubjectPermissionRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12W\n" + + "\bmetadata\x18\x02 \x01(\v23.base.v1.PermissionSubjectPermissionRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12/\n" + + "\x06entity\x18\x03 \x01(\v2\x0f.base.v1.EntityB\x06\xbaH\x03\xc8\x01\x01R\x06entity\x122\n" + + "\asubject\x18\x04 \x01(\v2\x10.base.v1.SubjectB\x06\xbaH\x03\xc8\x01\x01R\asubject\x12*\n" + "\acontext\x18\x05 \x01(\v2\x10.base.v1.ContextR\acontext\"\xea\x02\n" + "*PermissionSubjectPermissionRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\x12\x8a\x01\n" + @@ -4032,27 +4034,27 @@ const file_base_v1_service_proto_rawDesc = "" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\x12(\n" + "\x0fonly_permission\x18\x03 \x01(\bR\x0fonly_permission\x12]\n" + - "\x05depth\x18\x04 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xfaB\x04\x1a\x02(\x03R\x05depth\"\xcc\x01\n" + + "\x05depth\x18\x04 \x01(\x05BG\x92A=2;Query limit when if recursive database queries got in loop.\xbaH\x04\x1a\x02(\x03R\x05depth\"\xcc\x01\n" + "#PermissionSubjectPermissionResponse\x12S\n" + "\aresults\x18\x01 \x03(\v29.base.v1.PermissionSubjectPermissionResponse.ResultsEntryR\aresults\x1aP\n" + "\fResultsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12*\n" + - "\x05value\x18\x02 \x01(\x0e2\x14.base.v1.CheckResultR\x05value:\x028\x01\"\xc8\x03\n" + - "\fWatchRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12\x8a\x01\n" + + "\x05value\x18\x02 \x01(\x0e2\x14.base.v1.CheckResultR\x05value:\x028\x01\"\xc5\x03\n" + + "\fWatchRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12\x8a\x01\n" + "\n" + "snap_token\x18\x02 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + "snap_token\"?\n" + "\rWatchResponse\x12.\n" + - "\achanges\x18\x01 \x01(\v2\x14.base.v1.DataChangesR\achanges\"\xd9\x02\n" + - "\x12SchemaWriteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12\x16\n" + + "\achanges\x18\x01 \x01(\v2\x14.base.v1.DataChangesR\achanges\"\xd6\x02\n" + + "\x12SchemaWriteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12\x16\n" + "\x06schema\x18\x02 \x01(\tR\x06schema\"=\n" + "\x13SchemaWriteResponse\x12&\n" + - "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\xd9\x02\n" + - "\x19SchemaPartialWriteRequest\x12L\n" + - "\ttenant_id\x18\x01 \x01(\tB.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12P\n" + - "\bmetadata\x18\x02 \x01(\v2*.base.v1.SchemaPartialWriteRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12L\n" + + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\xd4\x02\n" + + "\x19SchemaPartialWriteRequest\x12I\n" + + "\ttenant_id\x18\x01 \x01(\tB+\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12N\n" + + "\bmetadata\x18\x02 \x01(\v2*.base.v1.SchemaPartialWriteRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x12L\n" + "\bpartials\x18\x03 \x03(\v20.base.v1.SchemaPartialWriteRequest.PartialsEntryR\bpartials\x1aN\n" + "\rPartialsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12'\n" + @@ -4060,18 +4062,19 @@ const file_base_v1_service_proto_rawDesc = "" + "!SchemaPartialWriteRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"D\n" + "\x1aSchemaPartialWriteResponse\x12&\n" + - "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\x8a\x03\n" + - "\x11SchemaReadRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12H\n" + - "\bmetadata\x18\x02 \x01(\v2\".base.v1.SchemaReadRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\"C\n" + + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\x85\x03\n" + + "\x11SchemaReadRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12F\n" + + "\bmetadata\x18\x02 \x01(\v2\".base.v1.SchemaReadRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\"C\n" + "\x19SchemaReadRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"G\n" + "\x12SchemaReadResponse\x121\n" + - "\x06schema\x18\x01 \x01(\v2\x19.base.v1.SchemaDefinitionR\x06schema\"\x9f\x03\n" + - "\x11SchemaListRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12'\n" + - "\tpage_size\x18\x02 \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\x03 \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\"\x83\x01\n" + + "\x06schema\x18\x01 \x01(\v2\x19.base.v1.SchemaDefinitionR\x06schema\"\x9d\x03\n" + + "\x11SchemaListRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12(\n" + + "\tpage_size\x18\x02 \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\x03 \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\"\x83\x01\n" + "\x12SchemaListResponse\x12\x12\n" + "\x04head\x18\x01 \x01(\tR\x04head\x12-\n" + "\aschemas\x18\x02 \x03(\v2\x13.base.v1.SchemaListR\aschemas\x12*\n" + @@ -4081,49 +4084,51 @@ const file_base_v1_service_proto_rawDesc = "" + "\aversion\x18\x01 \x01(\tR\aversion\x12\x1e\n" + "\n" + "created_at\x18\x02 \x01(\tR\n" + - "created_at\"\x86\x04\n" + - "\x10DataWriteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12G\n" + - "\bmetadata\x18\x02 \x01(\v2!.base.v1.DataWriteRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x127\n" + - "\x06tuples\x18\x03 \x03(\v2\x0e.base.v1.TupleB\x0f\xfaB\f\x92\x01\t\b\x00\"\x05\x8a\x01\x02\x10\x01R\x06tuples\x12C\n" + + "created_at\"\xf3\x03\n" + + "\x10DataWriteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12E\n" + + "\bmetadata\x18\x02 \x01(\v2!.base.v1.DataWriteRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x120\n" + + "\x06tuples\x18\x03 \x03(\v2\x0e.base.v1.TupleB\b\xbaH\x05\x92\x01\x02\b\x00R\x06tuples\x12<\n" + "\n" + - "attributes\x18\x04 \x03(\v2\x12.base.v1.AttributeB\x0f\xfaB\f\x92\x01\t\b\x00\"\x05\x8a\x01\x02\x10\x01R\n" + + "attributes\x18\x04 \x03(\v2\x12.base.v1.AttributeB\b\xbaH\x05\x92\x01\x02\b\x00R\n" + "attributes\"B\n" + "\x18DataWriteRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\xa0\x01\n" + "\x11DataWriteResponse\x12\x8a\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBj\x92Ag2eThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens).R\n" + - "snap_token\"\xd1\x03\n" + - "\x18RelationshipWriteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12O\n" + - "\bmetadata\x18\x02 \x01(\v2).base.v1.RelationshipWriteRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x127\n" + - "\x06tuples\x18\x03 \x03(\v2\x0e.base.v1.TupleB\x0f\xfaB\f\x92\x01\t\b\x01\"\x05\x8a\x01\x02\x10\x01R\x06tuples\"J\n" + + "snap_token\"\xc5\x03\n" + + "\x18RelationshipWriteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12M\n" + + "\bmetadata\x18\x02 \x01(\v2).base.v1.RelationshipWriteRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x120\n" + + "\x06tuples\x18\x03 \x03(\v2\x0e.base.v1.TupleB\b\xbaH\x05\x92\x01\x02\b\x01R\x06tuples\"J\n" + " RelationshipWriteRequestMetadata\x12&\n" + "\x0eschema_version\x18\x01 \x01(\tR\x0eschema_version\"\xa7\x01\n" + "\x19RelationshipWriteResponse\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + - "snap_token\"\xad\x04\n" + - "\x17RelationshipReadRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12N\n" + - "\bmetadata\x18\x02 \x01(\v2(.base.v1.RelationshipReadRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x126\n" + - "\x06filter\x18\x03 \x01(\v2\x14.base.v1.TupleFilterB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06filter\x12'\n" + - "\tpage_size\x18\x04 \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\x05 \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\"\xad\x01\n" + + "snap_token\"\xa7\x04\n" + + "\x17RelationshipReadRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12L\n" + + "\bmetadata\x18\x02 \x01(\v2(.base.v1.RelationshipReadRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x124\n" + + "\x06filter\x18\x03 \x01(\v2\x14.base.v1.TupleFilterB\x06\xbaH\x03\xc8\x01\x01R\x06filter\x12(\n" + + "\tpage_size\x18\x04 \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\x05 \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\"\xad\x01\n" + "\x1fRelationshipReadRequestMetadata\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + "snap_token\"n\n" + "\x18RelationshipReadResponse\x12&\n" + "\x06tuples\x18\x01 \x03(\v2\x0e.base.v1.TupleR\x06tuples\x12*\n" + - "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xab\x04\n" + - "\x14AttributeReadRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12K\n" + - "\bmetadata\x18\x02 \x01(\v2%.base.v1.AttributeReadRequestMetadataB\b\xfaB\x05\x8a\x01\x02\x10\x01R\bmetadata\x12:\n" + - "\x06filter\x18\x03 \x01(\v2\x18.base.v1.AttributeFilterB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x06filter\x12'\n" + - "\tpage_size\x18\x04 \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\x05 \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\"\xaa\x01\n" + + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xa5\x04\n" + + "\x14AttributeReadRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12I\n" + + "\bmetadata\x18\x02 \x01(\v2%.base.v1.AttributeReadRequestMetadataB\x06\xbaH\x03\xc8\x01\x01R\bmetadata\x128\n" + + "\x06filter\x18\x03 \x01(\v2\x18.base.v1.AttributeFilterB\x06\xbaH\x03\xc8\x01\x01R\x06filter\x12(\n" + + "\tpage_size\x18\x04 \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\x05 \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\"\xaa\x01\n" + "\x1cAttributeReadRequestMetadata\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + @@ -4132,24 +4137,24 @@ const file_base_v1_service_proto_rawDesc = "" + "\n" + "attributes\x18\x01 \x03(\v2\x12.base.v1.AttributeR\n" + "attributes\x12*\n" + - "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xd4\x03\n" + - "\x11DataDeleteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12B\n" + - "\ftuple_filter\x18\x02 \x01(\v2\x14.base.v1.TupleFilterB\b\xfaB\x05\x8a\x01\x02\x10\x01R\ftuple_filter\x12N\n" + - "\x10attribute_filter\x18\x03 \x01(\v2\x18.base.v1.AttributeFilterB\b\xfaB\x05\x8a\x01\x02\x10\x01R\x10attribute_filter\"\xa0\x01\n" + + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token\"\xcd\x03\n" + + "\x11DataDeleteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12@\n" + + "\ftuple_filter\x18\x02 \x01(\v2\x14.base.v1.TupleFilterB\x06\xbaH\x03\xc8\x01\x01R\ftuple_filter\x12L\n" + + "\x10attribute_filter\x18\x03 \x01(\v2\x18.base.v1.AttributeFilterB\x06\xbaH\x03\xc8\x01\x01R\x10attribute_filter\"\xa0\x01\n" + "\x12DataDeleteResponse\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + - "snap_token\"\xf6\x02\n" + - "\x19RelationshipDeleteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12,\n" + + "snap_token\"\xf3\x02\n" + + "\x19RelationshipDeleteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12,\n" + "\x06filter\x18\x02 \x01(\v2\x14.base.v1.TupleFilterR\x06filter\"\xa8\x01\n" + "\x1aRelationshipDeleteResponse\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + - "snap_token\"\xd9\x03\n" + - "\x10BundleRunRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12\x12\n" + + "snap_token\"\xd6\x03\n" + + "\x10BundleRunRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12F\n" + "\targuments\x18\x03 \x03(\v2(.base.v1.BundleRunRequest.ArgumentsEntryR\targuments\x1a<\n" + "\x0eArgumentsEntry\x12\x10\n" + @@ -4158,35 +4163,35 @@ const file_base_v1_service_proto_rawDesc = "" + "\x11BundleRunResponse\x12\x89\x01\n" + "\n" + "snap_token\x18\x01 \x01(\tBi\x92Af2dThe snap token to avoid stale cache, see more details on [Snap Tokens](../../operations/snap-tokens)R\n" + - "snap_token\"\xf0\x02\n" + - "\x12BundleWriteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12-\n" + + "snap_token\"\xed\x02\n" + + "\x12BundleWriteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12-\n" + "\abundles\x18\x02 \x03(\v2\x13.base.v1.DataBundleR\abundles\"+\n" + "\x13BundleWriteResponse\x12\x14\n" + - "\x05names\x18\x01 \x03(\tR\x05names\"\xd4\x02\n" + - "\x11BundleReadRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12\x12\n" + + "\x05names\x18\x01 \x03(\tR\x05names\"\xd1\x02\n" + + "\x11BundleReadRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\"A\n" + "\x12BundleReadResponse\x12+\n" + - "\x06bundle\x18\x01 \x01(\v2\x13.base.v1.DataBundleR\x06bundle\"\xd6\x02\n" + - "\x13BundleDeleteRequest\x12\xaa\x02\n" + - "\ttenant_id\x18\x01 \x01(\tB\x8b\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xfaB+r)(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$\xd0\x01\x00R\ttenant_id\x12\x12\n" + + "\x06bundle\x18\x01 \x01(\v2\x13.base.v1.DataBundleR\x06bundle\"\xd3\x02\n" + + "\x13BundleDeleteRequest\x12\xa7\x02\n" + + "\ttenant_id\x18\x01 \x01(\tB\x88\x02\x92A\xd9\x012\xd6\x01Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes.\xbaH(r&(\x80\x012!^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$R\ttenant_id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\"*\n" + "\x14BundleDeleteResponse\x12\x12\n" + - "\x04name\x18\x01 \x01(\tR\x04name\"a\n" + - "\x13TenantCreateRequest\x12*\n" + - "\x02id\x18\x01 \x01(\tB\x1a\xfaB\x17r\x15(@2\x0e[a-zA-Z0-9-,]+\xd0\x01\x00R\x02id\x12\x1e\n" + - "\x04name\x18\x02 \x01(\tB\n" + - "\xfaB\ar\x05(@\xd0\x01\x00R\x04name\"?\n" + + "\x04name\x18\x01 \x01(\tR\x04name\"[\n" + + "\x13TenantCreateRequest\x12'\n" + + "\x02id\x18\x01 \x01(\tB\x17\xbaH\x14r\x12(@2\x0e[a-zA-Z0-9-,]+R\x02id\x12\x1b\n" + + "\x04name\x18\x02 \x01(\tB\a\xbaH\x04r\x02(@R\x04name\"?\n" + "\x14TenantCreateResponse\x12'\n" + - "\x06tenant\x18\x01 \x01(\v2\x0f.base.v1.TenantR\x06tenant\"/\n" + - "\x13TenantDeleteRequest\x12\x18\n" + - "\x02id\x18\x01 \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x00R\x02id\"4\n" + + "\x06tenant\x18\x01 \x01(\v2\x0f.base.v1.TenantR\x06tenant\",\n" + + "\x13TenantDeleteRequest\x12\x15\n" + + "\x02id\x18\x01 \x01(\tB\x05\xbaH\x02r\x00R\x02id\"4\n" + "\x14TenantDeleteResponse\x12\x1c\n" + - "\ttenant_id\x18\x01 \x01(\tR\ttenant_id\"r\n" + - "\x11TenantListRequest\x12'\n" + - "\tpage_size\x18\x01 \x01(\rB\t\xfaB\x06*\x04(\x01@\x01R\tpage_size\x124\n" + - "\x10continuous_token\x18\x02 \x01(\tB\b\xfaB\x05r\x03\xd0\x01\x01R\x10continuous_token\"k\n" + + "\ttenant_id\x18\x01 \x01(\tR\ttenant_id\"s\n" + + "\x11TenantListRequest\x12(\n" + + "\tpage_size\x18\x01 \x01(\rB\n" + + "\xbaH\a\xd8\x01\x01*\x02(\x01R\tpage_size\x124\n" + + "\x10continuous_token\x18\x02 \x01(\tB\b\xbaH\x05\xd8\x01\x01r\x00R\x10continuous_token\"k\n" + "\x12TenantListResponse\x12)\n" + "\atenants\x18\x01 \x03(\v2\x0f.base.v1.TenantR\atenants\x12*\n" + "\x10continuous_token\x18\x02 \x01(\tR\x10continuous_token2\xafN\n" + diff --git a/pkg/pb/base/v1/service_grpc.pb.go b/pkg/pb/base/v1/service_grpc.pb.go index a2dd326db..e77922dbb 100644 --- a/pkg/pb/base/v1/service_grpc.pb.go +++ b/pkg/pb/base/v1/service_grpc.pb.go @@ -48,9 +48,12 @@ type PermissionClient interface { Expand(ctx context.Context, in *PermissionExpandRequest, opts ...grpc.CallOption) (*PermissionExpandResponse, error) // LookupEntity method receives a PermissionLookupEntityRequest and returns a PermissionLookupEntityResponse. // It is used to retrieve an entity by its identifier. + // buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE LookupEntity(ctx context.Context, in *PermissionLookupEntityRequest, opts ...grpc.CallOption) (*PermissionLookupEntityResponse, error) // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. // It is used to retrieve entities by their identifiers in a streaming fashion. + // buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME LookupEntityStream(ctx context.Context, in *PermissionLookupEntityRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[PermissionLookupEntityStreamResponse], error) // LookupSubject method receives a PermissionLookupSubjectRequest and returns a PermissionLookupSubjectResponse. // It is used to retrieve a subject by its identifier. @@ -167,9 +170,12 @@ type PermissionServer interface { Expand(context.Context, *PermissionExpandRequest) (*PermissionExpandResponse, error) // LookupEntity method receives a PermissionLookupEntityRequest and returns a PermissionLookupEntityResponse. // It is used to retrieve an entity by its identifier. + // buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE LookupEntity(context.Context, *PermissionLookupEntityRequest) (*PermissionLookupEntityResponse, error) // LookupEntityStream method receives a PermissionLookupEntityRequest and streams a series of PermissionLookupEntityStreamResponse messages. // It is used to retrieve entities by their identifiers in a streaming fashion. + // buf:lint:ignore RPC_REQUEST_RESPONSE_UNIQUE + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME LookupEntityStream(*PermissionLookupEntityRequest, grpc.ServerStreamingServer[PermissionLookupEntityStreamResponse]) error // LookupSubject method receives a PermissionLookupSubjectRequest and returns a PermissionLookupSubjectResponse. // It is used to retrieve a subject by its identifier. @@ -750,16 +756,26 @@ type DataClient interface { // The Write RPC method creates a new relation tuple. Write(ctx context.Context, in *DataWriteRequest, opts ...grpc.CallOption) (*DataWriteResponse, error) // RPC method to write relationships for a tenant. This can be accessed via a POST request to the given HTTP path. It's tagged under "Data" in OpenAPI documentation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME WriteRelationships(ctx context.Context, in *RelationshipWriteRequest, opts ...grpc.CallOption) (*RelationshipWriteResponse, error) // The ReadRelationships RPC method reads relation tuple(s). + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME ReadRelationships(ctx context.Context, in *RelationshipReadRequest, opts ...grpc.CallOption) (*RelationshipReadResponse, error) // The ReadAttributes RPC method reads attribute(s) of a relation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME ReadAttributes(ctx context.Context, in *AttributeReadRequest, opts ...grpc.CallOption) (*AttributeReadResponse, error) // The Delete RPC method deletes a relation tuple. Delete(ctx context.Context, in *DataDeleteRequest, opts ...grpc.CallOption) (*DataDeleteResponse, error) // RPC method to delete relationships for a tenant, accessed via a POST request to the specified path, tagged as "Data" in OpenAPI documentation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME DeleteRelationships(ctx context.Context, in *RelationshipDeleteRequest, opts ...grpc.CallOption) (*RelationshipDeleteResponse, error) // Executes or runs a specific bundle. This method is useful for processing or triggering actions based on the bundle's data. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME RunBundle(ctx context.Context, in *BundleRunRequest, opts ...grpc.CallOption) (*BundleRunResponse, error) } @@ -850,16 +866,26 @@ type DataServer interface { // The Write RPC method creates a new relation tuple. Write(context.Context, *DataWriteRequest) (*DataWriteResponse, error) // RPC method to write relationships for a tenant. This can be accessed via a POST request to the given HTTP path. It's tagged under "Data" in OpenAPI documentation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME WriteRelationships(context.Context, *RelationshipWriteRequest) (*RelationshipWriteResponse, error) // The ReadRelationships RPC method reads relation tuple(s). + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME ReadRelationships(context.Context, *RelationshipReadRequest) (*RelationshipReadResponse, error) // The ReadAttributes RPC method reads attribute(s) of a relation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME ReadAttributes(context.Context, *AttributeReadRequest) (*AttributeReadResponse, error) // The Delete RPC method deletes a relation tuple. Delete(context.Context, *DataDeleteRequest) (*DataDeleteResponse, error) // RPC method to delete relationships for a tenant, accessed via a POST request to the specified path, tagged as "Data" in OpenAPI documentation. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME DeleteRelationships(context.Context, *RelationshipDeleteRequest) (*RelationshipDeleteResponse, error) // Executes or runs a specific bundle. This method is useful for processing or triggering actions based on the bundle's data. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME RunBundle(context.Context, *BundleRunRequest) (*BundleRunResponse, error) mustEmbedUnimplementedDataServer() } @@ -1275,12 +1301,18 @@ const ( type TenancyClient interface { // Create is a unary RPC to create a new tenant. // It requires a TenantCreateRequest and returns a TenantCreateResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME Create(ctx context.Context, in *TenantCreateRequest, opts ...grpc.CallOption) (*TenantCreateResponse, error) // Delete is a unary RPC to delete an existing tenant. // It requires a TenantDeleteRequest and returns a TenantDeleteResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME Delete(ctx context.Context, in *TenantDeleteRequest, opts ...grpc.CallOption) (*TenantDeleteResponse, error) // List is a unary RPC to get a list of all tenants. // It requires a TenantListRequest and returns a TenantListResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME List(ctx context.Context, in *TenantListRequest, opts ...grpc.CallOption) (*TenantListResponse, error) } @@ -1328,12 +1360,18 @@ func (c *tenancyClient) List(ctx context.Context, in *TenantListRequest, opts .. type TenancyServer interface { // Create is a unary RPC to create a new tenant. // It requires a TenantCreateRequest and returns a TenantCreateResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME Create(context.Context, *TenantCreateRequest) (*TenantCreateResponse, error) // Delete is a unary RPC to delete an existing tenant. // It requires a TenantDeleteRequest and returns a TenantDeleteResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME Delete(context.Context, *TenantDeleteRequest) (*TenantDeleteResponse, error) // List is a unary RPC to get a list of all tenants. // It requires a TenantListRequest and returns a TenantListResponse. + // buf:lint:ignore RPC_REQUEST_STANDARD_NAME + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME List(context.Context, *TenantListRequest) (*TenantListResponse, error) mustEmbedUnimplementedTenancyServer() } diff --git a/pkg/schema/loader.go b/pkg/schema/loader.go index a1f57b9df..ac9fa5aaf 100644 --- a/pkg/schema/loader.go +++ b/pkg/schema/loader.go @@ -9,13 +9,16 @@ import ( // Package imports "path/filepath" // Path utilities "strings" // String utilities ) // End imports + // Type defines an enumeration for different schema types. type Type int // Schema type enum -const ( // Schema type constants + +const ( // Schema type constants URL Type = iota // URL represents a schema type for URLs File // File represents a schema type for file paths Inline // Inline represents a schema type for inline data ) // End constants + // Loader is a struct that holds a map of loader functions, each corresponding to a Type. type Loader struct { // loaders is a map where each Type is associated with a corresponding function @@ -23,6 +26,7 @@ type Loader struct { // These functions are responsible for loading data based on the Type. loaders map[Type]func(string) (string, error) } // End Loader struct + // NewSchemaLoader initializes and returns a new Loader instance. // It sets up the map of loader functions for each Type. func NewSchemaLoader() *Loader { @@ -34,6 +38,7 @@ func NewSchemaLoader() *Loader { }, // End loaders map } // End return } // End NewSchemaLoader + // LoadSchema loads a schema based on its type func (s *Loader) LoadSchema(input string) (string, error) { schemaType, err := determineSchemaType(input) @@ -46,6 +51,7 @@ func (s *Loader) LoadSchema(input string) (string, error) { } return loaderFunc(input) // Execute loader } // End LoadSchema + // determineSchemaType determines the type of schema based on the input string func determineSchemaType(input string) (Type, error) { if isURL(input) { // Check URL first @@ -60,6 +66,7 @@ func determineSchemaType(input string) (Type, error) { } return Inline, nil // Default to inline } // End determineSchemaType + func isURL(input string) bool { // Check if input is URL parsedURL, err := url.Parse(input) if err != nil { @@ -68,6 +75,7 @@ func isURL(input string) bool { // Check if input is URL // Check if the URL has a valid scheme and host return parsedURL.Scheme != "" && parsedURL.Host != "" } // End isURL + func isFilePath(input string) (bool, error) { // Check if input is file _, err := os.Stat(input) // Get file info if err != nil { @@ -81,6 +89,7 @@ func isFilePath(input string) (bool, error) { // Check if input is file } return true, nil // File exists } // End isFilePath + func loadFromURL(inputURL string) (string, error) { // Load schema from URL // Parse and validate the URL parsedURL, err := url.Parse(inputURL) @@ -105,6 +114,7 @@ func loadFromURL(inputURL string) (string, error) { // Load schema from URL } // Read succeeded return string(body), nil // Return body } // End loadFromURL + func loadFromFile(path string) (string, error) { // Load schema from file // Clean the path cleanPath := filepath.Clean(path) @@ -118,6 +128,7 @@ func loadFromFile(path string) (string, error) { // Load schema from file } // Read succeeded return string(content), nil // Return content } // End loadFromFile + // loadInline is a function that handles inline schema types. func loadInline(schema string) (string, error) { // Load inline schema // Add validation if necessary. For example: diff --git a/pkg/schema/loader_test.go b/pkg/schema/loader_test.go index dcab61233..daefd6f0b 100644 --- a/pkg/schema/loader_test.go +++ b/pkg/schema/loader_test.go @@ -4,7 +4,8 @@ import ( // Package imports // Test frameworks . "github.com/onsi/ginkgo/v2" // BDD test framework . "github.com/onsi/gomega" // Matcher library -) // End imports +) // End imports + var _ = Describe("Loader", func() { // Loader test suite Context("LoadSchema function", func() { // LoadSchema tests It("should load schema from URL", func() { // Test URL loading diff --git a/pkg/telemetry/meterexporters/otlp_grpc.go b/pkg/telemetry/meterexporters/otlp_grpc.go index 19a3027b6..ec2a288eb 100644 --- a/pkg/telemetry/meterexporters/otlp_grpc.go +++ b/pkg/telemetry/meterexporters/otlp_grpc.go @@ -6,6 +6,7 @@ import ( // gRPC metric dependencies "go.opentelemetry.io/otel/sdk/metric" // Metric SDK "google.golang.org/grpc/credentials" // TLS credentials ) // End imports + // NewOTLPGrpc - Creates new OTLP metric exporter using GRPC protocol for metrics collection. func NewOTLPGrpc( endpoint string, diff --git a/pkg/telemetry/tracerexporters/otlp.go b/pkg/telemetry/tracerexporters/otlp.go index b22fb8b83..963eb6710 100644 --- a/pkg/telemetry/tracerexporters/otlp.go +++ b/pkg/telemetry/tracerexporters/otlp.go @@ -8,6 +8,7 @@ import ( // OTLP trace dependencies "go.opentelemetry.io/otel/sdk/trace" // Trace SDK "google.golang.org/grpc/credentials" // TLS credentials ) // End imports + // NewOTLP - Creates new OTLP trace exporter based on protocol (HTTP or gRPC). func NewOTLP(endpoint string, insecure bool, urlpath string, headers map[string]string, protocol string) (trace.SpanExporter, error) { // Create OTLP tracer switch protocol { // Select protocol diff --git a/proto/base/v1/base.proto b/proto/base/v1/base.proto index e2efa0cff..c84cb07de 100644 --- a/proto/base/v1/base.proto +++ b/proto/base/v1/base.proto @@ -1,11 +1,11 @@ syntax = "proto3"; package base.v1; +import "buf/validate/validate.proto"; import "google/api/expr/v1alpha1/checked.proto"; import "google/protobuf/any.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; -import "validate/validate.proto"; option go_package = "github.com/Permify/permify/pkg/pb/base/v1"; @@ -65,13 +65,13 @@ message Child { // Child node can be either a leaf or a rewrite operation. oneof type { // Either leaf or rewrite operation is required. - option (validate.required) = true; + option (buf.validate.oneof).required = true; // Leaf node in the permission tree. - Leaf leaf = 1 [(validate.rules).message.required = true]; + Leaf leaf = 1; // Rewrite operation in the permission tree. - Rewrite rewrite = 2 [(validate.rules).message.required = true]; + Rewrite rewrite = 2; } } @@ -80,19 +80,19 @@ message Leaf { // Leaf node can be one of several types. oneof type { // One type is required. - option (validate.required) = true; + option (buf.validate.oneof).required = true; // A computed set of users. - ComputedUserSet computed_user_set = 1 [(validate.rules).message.required = true]; + ComputedUserSet computed_user_set = 1; // A tuple to user set conversion. - TupleToUserSet tuple_to_user_set = 2 [(validate.rules).message.required = true]; + TupleToUserSet tuple_to_user_set = 2; // A computed attribute. - ComputedAttribute computed_attribute = 3 [(validate.rules).message.required = true]; + ComputedAttribute computed_attribute = 3; // A call to a function or method. - Call call = 4 [(validate.rules).message.required = true]; + Call call = 4; } } @@ -148,7 +148,7 @@ message EntityDefinition { } // The name of the entity, which follows a specific string pattern and has a maximum byte size. - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -169,7 +169,7 @@ message EntityDefinition { // The RuleDefinition message provides detailed information about a specific rule. message RuleDefinition { // The name of the rule, which follows a specific string pattern and has a maximum byte size. - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -184,7 +184,7 @@ message RuleDefinition { // The AttributeDefinition message provides detailed information about a specific attribute. message AttributeDefinition { // The name of the attribute, which follows a specific string pattern and has a maximum byte size. - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -196,7 +196,7 @@ message AttributeDefinition { // The RelationDefinition message provides detailed information about a specific relation. message RelationDefinition { // The name of the relation, which follows a specific string pattern and has a maximum byte size. - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -208,7 +208,7 @@ message RelationDefinition { // The PermissionDefinition message provides detailed information about a specific permission. message PermissionDefinition { // The name of the permission, which follows a specific string pattern and has a maximum byte size. - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -220,28 +220,30 @@ message PermissionDefinition { // The RelationReference message provides a reference to a specific relation. message RelationReference { // The type of the referenced entity, which follows a specific string pattern and has a maximum byte size. - string type = 1 [(validate.rules).string = { + string type = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; // The name of the referenced relation, which follows a specific string pattern and has a maximum byte size. - string relation = 2 [(validate.rules).string = { - pattern: "^[a-zA-Z_]{1,64}$" - max_bytes: 64 - ignore_empty: true - }]; + string relation = 2 [ + (buf.validate.field).string = { + pattern: "^[a-zA-Z_]{1,64}$" + max_bytes: 64 + }, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE + ]; } message Entrance { // The type of the entrance entity, which follows a specific string pattern and has a maximum byte size. - string type = 1 [(validate.rules).string = { + string type = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; // The value associated with the entrance, which follows a specific string pattern and has a maximum byte size. - string value = 2 [(validate.rules).string = { + string value = 2 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -262,7 +264,7 @@ message Call { // ComputedAttribute defines a computed attribute which includes its name. message ComputedAttribute { - string name = 1 [(validate.rules).string = { + string name = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; // Name of the computed attribute @@ -270,7 +272,7 @@ message ComputedAttribute { // ComputedUserSet defines a set of computed users which includes the relation name. message ComputedUserSet { - string relation = 1 [(validate.rules).string = { + string relation = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; // Relation name @@ -284,7 +286,7 @@ message TupleToUserSet { // TupleSet represents a set of tuples associated with a specific relation. message TupleSet { - string relation = 1 [(validate.rules).string = { + string relation = 1 [(buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 }]; @@ -294,12 +296,12 @@ message TupleSet { message Tuple { Entity entity = 1 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; string relation = 2 [ json_name = "relation", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 } @@ -307,7 +309,7 @@ message Tuple { Subject subject = 3 [ json_name = "subject", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; } @@ -315,7 +317,7 @@ message Tuple { message Attribute { Entity entity = 1 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; string attribute = 2 [json_name = "attribute"]; // Name of the attribute @@ -337,7 +339,7 @@ message Attributes { message Entity { string type = 1 [ json_name = "type", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 } @@ -345,7 +347,7 @@ message Entity { string id = 2 [ json_name = "id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 } @@ -356,12 +358,12 @@ message Entity { message EntityAndRelation { Entity entity = 1 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; string relation = 2 [ json_name = "relation", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 } @@ -372,7 +374,7 @@ message EntityAndRelation { message Subject { string type = 1 [ json_name = "type", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 } @@ -380,7 +382,7 @@ message Subject { string id = 2 [ json_name = "id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 } @@ -388,11 +390,11 @@ message Subject { string relation = 3 [ json_name = "relation", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: true - } + }, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -409,11 +411,11 @@ message TupleFilter { string relation = 2 [ json_name = "relation", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: true - } + }, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; SubjectFilter subject = 3 [json_name = "subject"]; // The subject filter @@ -434,11 +436,11 @@ message SubjectFilter { string relation = 3 [ json_name = "relation", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: true - } + }, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -482,7 +484,7 @@ message Expand { // ExpandLeaf is the leaf node of an Expand tree and can be either a set of Subjects or a set of Values. message ExpandLeaf { oneof type { // type can be either Subjects or Values. - option (validate.required) = true; + option (buf.validate.oneof).required = true; // subjects are used when the leaf is a set of subjects. Subjects subjects = 1 [json_name = "subjects"]; @@ -529,7 +531,7 @@ message DataChange { Operation operation = 1 [json_name = "operation"]; // The operation type. oneof type { // The type of the change which can be either a tuple or an attribute. - option (validate.required) = true; + option (buf.validate.oneof).required = true; Tuple tuple = 2 [json_name = "tuple"]; // If the change is a tuple. Attribute attribute = 3 [json_name = "attribute"]; // If the change is an attribute. } diff --git a/proto/base/v1/service.proto b/proto/base/v1/service.proto index fdb64090c..bfdab9573 100644 --- a/proto/base/v1/service.proto +++ b/proto/base/v1/service.proto @@ -2,11 +2,12 @@ syntax = "proto3"; package base.v1; import "base/v1/base.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; -import "validate/validate.proto"; option go_package = "github.com/Permify/permify/pkg/pb/base/v1"; + // ** PERMISSION SERVICE ** // Permission service contains methods to interact with permissions. service Permission { @@ -791,10 +792,9 @@ message PermissionCheckRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -802,23 +802,22 @@ message PermissionCheckRequest { // Metadata associated with this request, required. PermissionCheckRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Entity on which the permission needs to be checked, required. Entity entity = 3 [ json_name = "entity", - (validate.rules).message.required = true, + (buf.validate.field).required = true, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {example: "\"repository:1\""} ]; // Name of the permission or relation, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. string permission = 4 [ json_name = "permission", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "The action the user wants to perform on the resource"} ]; @@ -826,7 +825,7 @@ message PermissionCheckRequest { // Subject for which the permission needs to be checked, required. Subject subject = 5 [ json_name = "subject", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Context associated with this request. @@ -853,7 +852,7 @@ message PermissionCheckRequestMetadata { // Depth of the check, must be greater than or equal to 3. int32 depth = 3 [ json_name = "depth", - (validate.rules).int32.gte = 3, + (buf.validate.field).int32.gte = 3, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Query limit when if recursive database queries got in loop"} ]; } @@ -878,17 +877,16 @@ message PermissionBulkCheckRequestItem { // Entity on which the permission needs to be checked, required. Entity entity = 1 [ json_name = "entity", - (validate.rules).message.required = true, + (buf.validate.field).required = true, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {example: "\"repository:1\""} ]; // Name of the permission or relation, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. string permission = 2 [ json_name = "permission", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "The action the user wants to perform on the resource"} ]; @@ -896,18 +894,18 @@ message PermissionBulkCheckRequestItem { // Subject for which the permission needs to be checked, required. Subject subject = 3 [ json_name = "subject", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; } + // PermissionBulkCheckRequest is the request message for the BulkCheck method in the Permission service. message PermissionBulkCheckRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -915,13 +913,13 @@ message PermissionBulkCheckRequest { // Metadata associated with this request, required. PermissionCheckRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // List of permission check requests, maximum 100 items. repeated PermissionBulkCheckRequestItem items = 3 [ json_name = "items", - (validate.rules).repeated = { + (buf.validate.field).repeated = { min_items: 1 max_items: 100 } @@ -950,10 +948,9 @@ message PermissionExpandRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -961,23 +958,23 @@ message PermissionExpandRequest { // Metadata associated with this request, required. PermissionExpandRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Entity on which the permission needs to be expanded, required. Entity entity = 3 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Name of the permission to be expanded, not required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. string permission = 4 [ json_name = "permission", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: true - } + }, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // Context associated with this request. @@ -1012,10 +1009,9 @@ message PermissionLookupEntityRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1023,33 +1019,31 @@ message PermissionLookupEntityRequest { // Metadata associated with this request, required. PermissionLookupEntityRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Type of the entity to lookup, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. string entity_type = 3 [ json_name = "entity_type", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: false } ]; // Name of the permission to check, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. string permission = 4 [ json_name = "permission", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: false } ]; // Subject for which to check the permission, required. Subject subject = 5 [ json_name = "subject", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Context associated with this request. @@ -1063,17 +1057,16 @@ message PermissionLookupEntityRequest { // The value should be between 1 and 100. uint32 page_size = 8 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is an optional parameter used for pagination. // It should be the value received in the previous response. string continuous_token = 9 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -1091,7 +1084,7 @@ message PermissionLookupEntityRequestMetadata { // Depth of lookup, required, must be greater or equal to 3. int32 depth = 3 [ json_name = "depth", - (validate.rules).int32.gte = 3, + (buf.validate.field).int32.gte = 3, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Query limit when if recursive database queries got in loop."} ]; } @@ -1121,10 +1114,9 @@ message PermissionEntityFilterRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1132,7 +1124,7 @@ message PermissionEntityFilterRequest { // Metadata associated with this request, required. PermissionEntityFilterRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Reference to the entity to filter. @@ -1152,7 +1144,8 @@ message PermissionEntityFilterRequest { // It should be the value received in the previous response. string cursor = 7 [ json_name = "cursor", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -1170,7 +1163,7 @@ message PermissionEntityFilterRequestMetadata { // Depth of lookup, required, must be greater or equal to 3. int32 depth = 3 [ json_name = "depth", - (validate.rules).int32.gte = 3, + (buf.validate.field).int32.gte = 3, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Query limit when if recursive database queries got in loop."} ]; } @@ -1182,10 +1175,9 @@ message PermissionLookupSubjectRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1193,29 +1185,28 @@ message PermissionLookupSubjectRequest { // Metadata associated with this request, required. PermissionLookupSubjectRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Entity for which to check the permission, required. Entity entity = 3 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Permission to be checked, can be a permission or relation. Required, and must match the pattern "^([a-zA-Z][a-zA-Z0-9_]{1,62}[a-zA-Z0-9])$", max 64 bytes. string permission = 4 [ json_name = "permission", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^[a-zA-Z_]{1,64}$" max_bytes: 64 - ignore_empty: false } ]; // Reference to the subject to lookup. RelationReference subject_reference = 5 [ json_name = "subject_reference", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Context associated with this request. @@ -1228,17 +1219,16 @@ message PermissionLookupSubjectRequest { // The value should be between 1 and 100. uint32 page_size = 8 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is an optional parameter used for pagination. // It should be the value received in the previous response. string continuous_token = 9 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -1256,7 +1246,7 @@ message PermissionLookupSubjectRequestMetadata { // Depth of the check, must be greater than or equal to 3. int32 depth = 3 [ json_name = "depth", - (validate.rules).int32.gte = 3, + (buf.validate.field).int32.gte = 3, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Query limit when if recursive database queries got in loop."} ]; } @@ -1277,10 +1267,9 @@ message PermissionSubjectPermissionRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1288,19 +1277,19 @@ message PermissionSubjectPermissionRequest { // Metadata associated with this request, required. PermissionSubjectPermissionRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Entity for which to check the permission, required. Entity entity = 3 [ json_name = "entity", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Subject for which to check the permission, required. Subject subject = 4 [ json_name = "subject", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Context associated with this request. @@ -1324,7 +1313,7 @@ message PermissionSubjectPermissionRequestMetadata { // Depth of the check, must be greater than or equal to 3. int32 depth = 4 [ json_name = "depth", - (validate.rules).int32.gte = 3, + (buf.validate.field).int32.gte = 3, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Query limit when if recursive database queries got in loop."} ]; } @@ -1436,10 +1425,9 @@ message WatchRequest { // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1772,7 +1760,7 @@ service Schema { } fields: { // cURL example for listing schemas key: "source" // Source code example - value: {string_value: // cURL command string + value: {string_value: /* cURL command string */ "curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/schemas/list' \\\n" // List schemas endpoint "--header 'Content-Type: application/json' \\\n" "--data-raw '{\n" @@ -1799,10 +1787,9 @@ message SchemaWriteRequest { // be a maximum of 64 bytes, and must not be empty. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1827,17 +1814,16 @@ message SchemaPartialWriteRequest { // be a maximum of 64 bytes, and must not be empty. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false } ]; // metadata is the additional information needed for the Partial Write request. SchemaPartialWriteRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // Map of entity name with the values needed to be updated @@ -1867,10 +1853,9 @@ message SchemaReadRequest { // be a maximum of 64 bytes, and must not be empty. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1878,7 +1863,7 @@ message SchemaReadRequest { // metadata is the additional information needed for the Read request. SchemaReadRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; } @@ -1905,10 +1890,9 @@ message SchemaListRequest { // be a maximum of 64 bytes, and must not be empty. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -1917,17 +1901,16 @@ message SchemaListRequest { // The value should be between 1 and 100. uint32 page_size = 2 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is an optional parameter used for pagination. // It should be the value received in the previous response. string continuous_token = 3 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -2666,10 +2649,9 @@ message DataWriteRequest { // tenant_id represents the unique identifier of the tenant for which data is written. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2677,29 +2659,19 @@ message DataWriteRequest { // metadata holds additional data related to the request. DataWriteRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // tuples contains the list of tuples (entity-relation-entity triples) that need to be written. repeated Tuple tuples = 3 [ json_name = "tuples", - (validate.rules).repeated = { - min_items: 0 - items: { - message: {required: true} - } - } + (buf.validate.field).repeated.min_items = 0 ]; // attributes contains the list of attributes (entity-attribute-value triples) that need to be written. repeated Attribute attributes = 4 [ json_name = "attributes", - (validate.rules).repeated = { - min_items: 0 - items: { - message: {required: true} - } - } + (buf.validate.field).repeated.min_items = 0 ]; } @@ -2725,10 +2697,9 @@ message RelationshipWriteRequest { // Unique identifier for the tenant with specific constraints. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2736,18 +2707,13 @@ message RelationshipWriteRequest { // Metadata for the request. It's required. RelationshipWriteRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // List of tuples for the request. Must have between 1 and 100 items. repeated Tuple tuples = 3 [ json_name = "tuples", - (validate.rules).repeated = { - min_items: 1 - items: { - message: {required: true} - } - } + (buf.validate.field).repeated.min_items = 1 ]; } @@ -2770,10 +2736,9 @@ message RelationshipReadRequest { // tenant_id represents the unique identifier of the tenant for which relationships are read. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2781,29 +2746,28 @@ message RelationshipReadRequest { // metadata holds additional data related to the request. RelationshipReadRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // filter is used to specify criteria for the data that needs to be read. TupleFilter filter = 3 [ json_name = "filter", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // page_size specifies the number of results to return in a single page. // If more results are available, a continuous_token is included in the response. uint32 page_size = 4 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is used in case of paginated reads to get the next page of results. string continuous_token = 5 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -2833,10 +2797,9 @@ message AttributeReadRequest { // tenant_id represents the unique identifier of the tenant from which the attributes are being read. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2844,29 +2807,28 @@ message AttributeReadRequest { // metadata holds additional information related to the request. AttributeReadRequestMetadata metadata = 2 [ json_name = "metadata", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // filter specifies the criteria used to select the attributes that should be returned. AttributeFilter filter = 3 [ json_name = "filter", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // page_size specifies the number of results to return in a single page. // If more results are available, a continuous_token is included in the response. uint32 page_size = 4 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is used in case of paginated reads to get the next page of results. string continuous_token = 5 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } @@ -2896,10 +2858,9 @@ message DataDeleteRequest { // tenant_id represents the unique identifier of the tenant from which the data will be deleted. string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2907,13 +2868,13 @@ message DataDeleteRequest { // tuple_filter specifies the criteria used to select the tuples that should be deleted. TupleFilter tuple_filter = 2 [ json_name = "tuple_filter", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; // attribute_filter specifies the criteria used to select the attributes that should be deleted. AttributeFilter attribute_filter = 3 [ json_name = "attribute_filter", - (validate.rules).message.required = true + (buf.validate.field).required = true ]; } @@ -2931,10 +2892,9 @@ message DataDeleteResponse { message RelationshipDeleteRequest { string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -2955,10 +2915,9 @@ message RelationshipDeleteResponse { message BundleRunRequest { string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -3309,10 +3268,9 @@ service Bundle { message BundleWriteRequest { string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -3329,10 +3287,9 @@ message BundleWriteResponse { message BundleReadRequest { string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -3349,10 +3306,9 @@ message BundleReadResponse { message BundleDeleteRequest { string tenant_id = 1 [ json_name = "tenant_id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" max_bytes: 128 - ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} ]; @@ -3636,20 +3592,16 @@ message TenantCreateRequest { // id is a unique identifier for the tenant. string id = 1 [ json_name = "id", - (validate.rules).string = { + (buf.validate.field).string = { pattern: "[a-zA-Z0-9-,]+" max_bytes: 64 - ignore_empty: false } ]; // name is the name of the tenant. string name = 2 [ json_name = "name", - (validate.rules).string = { - max_bytes: 64 - ignore_empty: false - } + (buf.validate.field).string = {max_bytes: 64} ]; } @@ -3664,7 +3616,7 @@ message TenantDeleteRequest { // id is the unique identifier of the tenant to be deleted. string id = 1 [ json_name = "id", - (validate.rules).string = {ignore_empty: false} + (buf.validate.field).string = {} ]; } @@ -3680,17 +3632,16 @@ message TenantListRequest { // The value should be between 1 and 100. uint32 page_size = 1 [ json_name = "page_size", - (validate.rules).uint32 = { - gte: 1 - ignore_empty: true - } + (buf.validate.field).uint32 = {gte: 1}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; // continuous_token is an optional parameter used for pagination. // It should be the value received in the previous response. string continuous_token = 2 [ json_name = "continuous_token", - (validate.rules).string = {ignore_empty: true} + (buf.validate.field).string = {}, + (buf.validate.field).ignore = IGNORE_IF_ZERO_VALUE ]; } diff --git a/proto/buf.lock b/proto/buf.lock index c7e976072..2bdb6cb3d 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -1,18 +1,12 @@ # Generated by buf. DO NOT EDIT. -version: v1 +version: v2 deps: - - remote: buf.build - owner: envoyproxy - repository: protoc-gen-validate - commit: daf171c6cdb54629b5f51e345a79e4dd - digest: shake256:4ae167d7eed10da5f83a3f5df8c670d249170f11b1f2fd19afda06be2cff4d47dcc95e9e4a15151ecc8ce2d3d3614caf9a04d3ad82fb768a3870dedfa9455f36 - - remote: buf.build - owner: googleapis - repository: googleapis + - name: buf.build/bufbuild/protovalidate + commit: 511051f7f4374c3ca873b53ae68a9288 + digest: b5:a4a2d4d808a25984cced60769c822c5d496ef0b740f56ac0c9e6b97aaa25b86a9332a00ffd74e0cd202be29e91bd3edfb0bf2ba4dacfe48ff2d8217f9986e3c8 + - name: buf.build/googleapis/googleapis commit: 61b203b9a9164be9a834f58c37be6f62 - digest: shake256:e619113001d6e284ee8a92b1561e5d4ea89a47b28bf0410815cb2fa23914df8be9f1a6a98dcf069f5bc2d829a2cfb1ac614863be45cd4f8a5ad8606c5f200224 - - remote: buf.build - owner: grpc-ecosystem - repository: grpc-gateway + digest: b5:7811a98b35bd2e4ae5c3ac73c8b3d9ae429f3a790da15de188dc98fc2b77d6bb10e45711f14903af9553fa9821dff256054f2e4b7795789265bc476bec2f088c + - name: buf.build/grpc-ecosystem/grpc-gateway commit: 4c5ba75caaf84e928b7137ae5c18c26a - digest: shake256:e174ad9408f3e608f6157907153ffec8d310783ee354f821f57178ffbeeb8faa6bb70b41b61099c1783c82fe16210ebd1279bc9c9ee6da5cffba9f0e675b8b99 + digest: b5:c113e62fb3b29289af785866cae062b55ec8ae19ab3f08f3004098928fbca657730a06810b2012951294326b95669547194fa84476b9e9b688d4f8bf77a0691d diff --git a/proto/buf.yaml b/proto/buf.yaml index 18024efc4..bcf2d7ec2 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,14 +1,20 @@ -version: v1 -name: buf.build/permifyco/permify +version: v2 +modules: + - path: . + name: buf.build/permifyco/permify deps: - - buf.build/envoyproxy/protoc-gen-validate:daf171c6cdb54629b5f51e345a79e4dd - - buf.build/grpc-ecosystem/grpc-gateway:4c5ba75caaf84e928b7137ae5c18c26a + - buf.build/bufbuild/protovalidate - buf.build/googleapis/googleapis:61b203b9a9164be9a834f58c37be6f62 -breaking: - ignore_unstable_packages: true + - buf.build/grpc-ecosystem/grpc-gateway:4c5ba75caaf84e928b7137ae5c18c26a lint: - allow_comment_ignores: true except: - - PACKAGE_VERSION_SUFFIX - FIELD_LOWER_SNAKE_CASE - - SERVICE_SUFFIX \ No newline at end of file + - FIELD_NOT_REQUIRED + - PACKAGE_NO_IMPORT_CYCLE + - PACKAGE_VERSION_SUFFIX + - SERVICE_SUFFIX +breaking: + except: + - EXTENSION_NO_DELETE + - FIELD_SAME_DEFAULT + ignore_unstable_packages: true diff --git a/sdk/go/grpc/main.go b/sdk/go/grpc/main.go index 1c8c25425..3b31038bf 100644 --- a/sdk/go/grpc/main.go +++ b/sdk/go/grpc/main.go @@ -4,10 +4,11 @@ import ( "context" "log" - "buf.build/gen/go/permifyco/permify/protocolbuffers/go/base/v1" - pclient "github.com/Permify/permify-go/grpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "buf.build/gen/go/permifyco/permify/protocolbuffers/go/base/v1" + + pclient "github.com/Permify/permify-go/grpc" ) func main() {