From 0ad9a181ca0a509118cc02f028e87fb9f051aa65 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 12:37:06 -0500 Subject: [PATCH 01/37] feat: add generated connect-rpc code --- .git-branches.toml | 112 ++++ .vscode/launch.json | 28 + buf.gen.yaml | 4 + .../authorization.connect.go | 174 ++++++ .../entity_resolution.connect.go | 145 +++++ protocol/go/go.mod | 3 +- protocol/go/go.sum | 5 +- protocol/go/kas/kasconnect/kas.connect.go | 174 ++++++ .../attributesconnect/attributes.connect.go | 555 ++++++++++++++++++ .../key_access_server_registry.connect.go | 272 +++++++++ .../namespacesconnect/namespaces.connect.go | 301 ++++++++++ .../resource_mapping.connect.go | 422 +++++++++++++ .../subject_mapping.connect.go | 422 +++++++++++++ .../unsafe/unsafeconnect/unsafe.connect.go | 371 ++++++++++++ .../wellknown_configuration.connect.go | 115 ++++ 15 files changed, 3101 insertions(+), 2 deletions(-) create mode 100644 .git-branches.toml create mode 100644 .vscode/launch.json create mode 100644 protocol/go/authorization/authorizationconnect/authorization.connect.go create mode 100644 protocol/go/entityresolution/entityresolutionconnect/entity_resolution.connect.go create mode 100644 protocol/go/kas/kasconnect/kas.connect.go create mode 100644 protocol/go/policy/attributes/attributesconnect/attributes.connect.go create mode 100644 protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go create mode 100644 protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go create mode 100644 protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go create mode 100644 protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go create mode 100644 protocol/go/policy/unsafe/unsafeconnect/unsafe.connect.go create mode 100644 protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go diff --git a/.git-branches.toml b/.git-branches.toml new file mode 100644 index 0000000000..f297a2b9bf --- /dev/null +++ b/.git-branches.toml @@ -0,0 +1,112 @@ +# Git Town configuration file +# +# Run "git town config setup" to add additional entries +# to this file after updating Git Town. +# +# The "push-hook" setting determines whether Git Town +# permits or prevents Git hooks while pushing branches. +# Hooks are enabled by default. If your Git hooks are slow, +# you can disable them to speed up branch syncing. +# +# When disabled, Git Town pushes using the "--no-verify" switch. +# More info at https://www.git-town.com/preferences/push-hook. +push-hook = true + +# Should Git Town push the new branches it creates +# immediately to origin even if they are empty? +# +# When enabled, you can run "git push" right away +# but creating new branches is slower and +# it triggers an unnecessary CI run on the empty branch. +# +# When disabled, many Git Town commands execute faster +# and Git Town will create the missing tracking branch +# on the first run of "git town sync". +push-new-branches = false + +# The "create-prototype-branches" setting determines whether Git Town +# always creates prototype branches. +# Prototype branches sync only locally and don't create a tracking branch +# until they are proposed. +# +# More info at https://www.git-town.com/preferences/create-prototype-branches. +create-prototype-branches = false + +# Which method should Git Town use to ship feature branches? +# +# Options: +# +# - api: merge the proposal on your code hosting platform via the code hosting API +# - fast-forward: in your local repo, fast-forward the parent branch to point to the commits on the feature branch +# - squash-merge: in your local repo, squash-merge the feature branch into its parent branch +# +# All options update proposals of child branches and remove the shipped branch locally and remotely. +ship-strategy = "api" + +# Should "git town ship" delete the tracking branch? +# You want to disable this if your code hosting platform +# (GitHub, GitLab, etc) deletes head branches when +# merging pull requests through its UI. +ship-delete-tracking-branch = false + +# Should "git town sync" sync tags with origin? +sync-tags = true + +# Should "git town sync" also fetch updates from the upstream remote? +# +# If an "upstream" remote exists, and this setting is enabled, +# "git town sync" will also update the local main branch +# with commits from the main branch at the upstream remote. +# +# This is useful if the repository you work on is a fork, +# and you want to keep it in sync with the repo it was forked from. +sync-upstream = true + +[branches] + +# The main branch is the branch from which you cut new feature branches, +# and into which you ship feature branches when they are done. +# This branch is often called "main", "master", or "development". +main = "main" + +# Perennial branches are long-lived branches. +# They are never shipped and have no ancestors. +# Typically, perennial branches have names like +# "development", "staging", "qa", "production", etc. +# +# See also the "perennial-regex" setting. +perennials = [] + +# All branches whose name matches this regular expression +# are also considered perennial branches. +# +# If you are not sure, leave this empty. +perennial-regex = "" + +[hosting] + +# Knowing the type of code hosting platform allows Git Town +# to open browser URLs and talk to the code hosting API. +# Most people can leave this on "auto-detect". +# Only change this if your code hosting server uses as custom URL. +platform = "github" + +# When using SSH identities, define the hostname +# of your source code repository. Only change this +# if the auto-detection does not work for you. +# origin-hostname = "" + +[sync-strategy] + +# How should Git Town synchronize feature branches? +# Feature branches are short-lived branches cut from +# the main branch and shipped back into the main branch. +# Typically you develop features and bug fixes on them, +# hence their name. +feature-branches = "merge" + +# How should Git Town synchronize perennial branches? +# Perennial branches have no parent branch. +# The only updates they receive are additional commits +# made to their tracking branch somewhere else. +perennial-branches = "rebase" \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..80071cc8a1 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Attach to Air for debugging + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}", + "env": { + "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true", + "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE": "/var/run/docker.sock" + }, + "showLog": true, + "console": "integratedTerminal" + }, + { + "name": "Attach to Air", + "type": "go", + "debugAdapter": "dlv-dap", + "mode": "remote", + "request": "attach", + "host": "127.0.0.1", + "port": 12345 + } + ] +} \ No newline at end of file diff --git a/buf.gen.yaml b/buf.gen.yaml index 9127207267..13e766c4e8 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -21,3 +21,7 @@ plugins: - remote: buf.build/grpc/go:v1.3.0 out: protocol/go opt: paths=source_relative + - remote: buf.build/connectrpc/go:v1.17.0 + out: protocol/go + opt: + - paths=source_relative diff --git a/protocol/go/authorization/authorizationconnect/authorization.connect.go b/protocol/go/authorization/authorizationconnect/authorization.connect.go new file mode 100644 index 0000000000..dd5efadb4d --- /dev/null +++ b/protocol/go/authorization/authorizationconnect/authorization.connect.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: authorization/authorization.proto + +package authorizationconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + authorization "github.com/opentdf/platform/protocol/go/authorization" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AuthorizationServiceName is the fully-qualified name of the AuthorizationService service. + AuthorizationServiceName = "authorization.AuthorizationService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AuthorizationServiceGetDecisionsProcedure is the fully-qualified name of the + // AuthorizationService's GetDecisions RPC. + AuthorizationServiceGetDecisionsProcedure = "/authorization.AuthorizationService/GetDecisions" + // AuthorizationServiceGetDecisionsByTokenProcedure is the fully-qualified name of the + // AuthorizationService's GetDecisionsByToken RPC. + AuthorizationServiceGetDecisionsByTokenProcedure = "/authorization.AuthorizationService/GetDecisionsByToken" + // AuthorizationServiceGetEntitlementsProcedure is the fully-qualified name of the + // AuthorizationService's GetEntitlements RPC. + AuthorizationServiceGetEntitlementsProcedure = "/authorization.AuthorizationService/GetEntitlements" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + authorizationServiceServiceDescriptor = authorization.File_authorization_authorization_proto.Services().ByName("AuthorizationService") + authorizationServiceGetDecisionsMethodDescriptor = authorizationServiceServiceDescriptor.Methods().ByName("GetDecisions") + authorizationServiceGetDecisionsByTokenMethodDescriptor = authorizationServiceServiceDescriptor.Methods().ByName("GetDecisionsByToken") + authorizationServiceGetEntitlementsMethodDescriptor = authorizationServiceServiceDescriptor.Methods().ByName("GetEntitlements") +) + +// AuthorizationServiceClient is a client for the authorization.AuthorizationService service. +type AuthorizationServiceClient interface { + GetDecisions(context.Context, *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) + GetDecisionsByToken(context.Context, *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) + GetEntitlements(context.Context, *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) +} + +// NewAuthorizationServiceClient constructs a client for the authorization.AuthorizationService +// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for +// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply +// the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAuthorizationServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AuthorizationServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &authorizationServiceClient{ + getDecisions: connect.NewClient[authorization.GetDecisionsRequest, authorization.GetDecisionsResponse]( + httpClient, + baseURL+AuthorizationServiceGetDecisionsProcedure, + connect.WithSchema(authorizationServiceGetDecisionsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getDecisionsByToken: connect.NewClient[authorization.GetDecisionsByTokenRequest, authorization.GetDecisionsByTokenResponse]( + httpClient, + baseURL+AuthorizationServiceGetDecisionsByTokenProcedure, + connect.WithSchema(authorizationServiceGetDecisionsByTokenMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getEntitlements: connect.NewClient[authorization.GetEntitlementsRequest, authorization.GetEntitlementsResponse]( + httpClient, + baseURL+AuthorizationServiceGetEntitlementsProcedure, + connect.WithSchema(authorizationServiceGetEntitlementsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// authorizationServiceClient implements AuthorizationServiceClient. +type authorizationServiceClient struct { + getDecisions *connect.Client[authorization.GetDecisionsRequest, authorization.GetDecisionsResponse] + getDecisionsByToken *connect.Client[authorization.GetDecisionsByTokenRequest, authorization.GetDecisionsByTokenResponse] + getEntitlements *connect.Client[authorization.GetEntitlementsRequest, authorization.GetEntitlementsResponse] +} + +// GetDecisions calls authorization.AuthorizationService.GetDecisions. +func (c *authorizationServiceClient) GetDecisions(ctx context.Context, req *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) { + return c.getDecisions.CallUnary(ctx, req) +} + +// GetDecisionsByToken calls authorization.AuthorizationService.GetDecisionsByToken. +func (c *authorizationServiceClient) GetDecisionsByToken(ctx context.Context, req *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) { + return c.getDecisionsByToken.CallUnary(ctx, req) +} + +// GetEntitlements calls authorization.AuthorizationService.GetEntitlements. +func (c *authorizationServiceClient) GetEntitlements(ctx context.Context, req *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) { + return c.getEntitlements.CallUnary(ctx, req) +} + +// AuthorizationServiceHandler is an implementation of the authorization.AuthorizationService +// service. +type AuthorizationServiceHandler interface { + GetDecisions(context.Context, *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) + GetDecisionsByToken(context.Context, *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) + GetEntitlements(context.Context, *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) +} + +// NewAuthorizationServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAuthorizationServiceHandler(svc AuthorizationServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + authorizationServiceGetDecisionsHandler := connect.NewUnaryHandler( + AuthorizationServiceGetDecisionsProcedure, + svc.GetDecisions, + connect.WithSchema(authorizationServiceGetDecisionsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + authorizationServiceGetDecisionsByTokenHandler := connect.NewUnaryHandler( + AuthorizationServiceGetDecisionsByTokenProcedure, + svc.GetDecisionsByToken, + connect.WithSchema(authorizationServiceGetDecisionsByTokenMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + authorizationServiceGetEntitlementsHandler := connect.NewUnaryHandler( + AuthorizationServiceGetEntitlementsProcedure, + svc.GetEntitlements, + connect.WithSchema(authorizationServiceGetEntitlementsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/authorization.AuthorizationService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AuthorizationServiceGetDecisionsProcedure: + authorizationServiceGetDecisionsHandler.ServeHTTP(w, r) + case AuthorizationServiceGetDecisionsByTokenProcedure: + authorizationServiceGetDecisionsByTokenHandler.ServeHTTP(w, r) + case AuthorizationServiceGetEntitlementsProcedure: + authorizationServiceGetEntitlementsHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAuthorizationServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAuthorizationServiceHandler struct{} + +func (UnimplementedAuthorizationServiceHandler) GetDecisions(context.Context, *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("authorization.AuthorizationService.GetDecisions is not implemented")) +} + +func (UnimplementedAuthorizationServiceHandler) GetDecisionsByToken(context.Context, *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("authorization.AuthorizationService.GetDecisionsByToken is not implemented")) +} + +func (UnimplementedAuthorizationServiceHandler) GetEntitlements(context.Context, *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("authorization.AuthorizationService.GetEntitlements is not implemented")) +} diff --git a/protocol/go/entityresolution/entityresolutionconnect/entity_resolution.connect.go b/protocol/go/entityresolution/entityresolutionconnect/entity_resolution.connect.go new file mode 100644 index 0000000000..05aeae6492 --- /dev/null +++ b/protocol/go/entityresolution/entityresolutionconnect/entity_resolution.connect.go @@ -0,0 +1,145 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: entityresolution/entity_resolution.proto + +package entityresolutionconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + entityresolution "github.com/opentdf/platform/protocol/go/entityresolution" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // EntityResolutionServiceName is the fully-qualified name of the EntityResolutionService service. + EntityResolutionServiceName = "entityresolution.EntityResolutionService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // EntityResolutionServiceResolveEntitiesProcedure is the fully-qualified name of the + // EntityResolutionService's ResolveEntities RPC. + EntityResolutionServiceResolveEntitiesProcedure = "/entityresolution.EntityResolutionService/ResolveEntities" + // EntityResolutionServiceCreateEntityChainFromJwtProcedure is the fully-qualified name of the + // EntityResolutionService's CreateEntityChainFromJwt RPC. + EntityResolutionServiceCreateEntityChainFromJwtProcedure = "/entityresolution.EntityResolutionService/CreateEntityChainFromJwt" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + entityResolutionServiceServiceDescriptor = entityresolution.File_entityresolution_entity_resolution_proto.Services().ByName("EntityResolutionService") + entityResolutionServiceResolveEntitiesMethodDescriptor = entityResolutionServiceServiceDescriptor.Methods().ByName("ResolveEntities") + entityResolutionServiceCreateEntityChainFromJwtMethodDescriptor = entityResolutionServiceServiceDescriptor.Methods().ByName("CreateEntityChainFromJwt") +) + +// EntityResolutionServiceClient is a client for the entityresolution.EntityResolutionService +// service. +type EntityResolutionServiceClient interface { + ResolveEntities(context.Context, *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) + CreateEntityChainFromJwt(context.Context, *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) +} + +// NewEntityResolutionServiceClient constructs a client for the +// entityresolution.EntityResolutionService service. By default, it uses the Connect protocol with +// the binary Protobuf Codec, asks for gzipped responses, and sends uncompressed requests. To use +// the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewEntityResolutionServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) EntityResolutionServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &entityResolutionServiceClient{ + resolveEntities: connect.NewClient[entityresolution.ResolveEntitiesRequest, entityresolution.ResolveEntitiesResponse]( + httpClient, + baseURL+EntityResolutionServiceResolveEntitiesProcedure, + connect.WithSchema(entityResolutionServiceResolveEntitiesMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createEntityChainFromJwt: connect.NewClient[entityresolution.CreateEntityChainFromJwtRequest, entityresolution.CreateEntityChainFromJwtResponse]( + httpClient, + baseURL+EntityResolutionServiceCreateEntityChainFromJwtProcedure, + connect.WithSchema(entityResolutionServiceCreateEntityChainFromJwtMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// entityResolutionServiceClient implements EntityResolutionServiceClient. +type entityResolutionServiceClient struct { + resolveEntities *connect.Client[entityresolution.ResolveEntitiesRequest, entityresolution.ResolveEntitiesResponse] + createEntityChainFromJwt *connect.Client[entityresolution.CreateEntityChainFromJwtRequest, entityresolution.CreateEntityChainFromJwtResponse] +} + +// ResolveEntities calls entityresolution.EntityResolutionService.ResolveEntities. +func (c *entityResolutionServiceClient) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { + return c.resolveEntities.CallUnary(ctx, req) +} + +// CreateEntityChainFromJwt calls entityresolution.EntityResolutionService.CreateEntityChainFromJwt. +func (c *entityResolutionServiceClient) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { + return c.createEntityChainFromJwt.CallUnary(ctx, req) +} + +// EntityResolutionServiceHandler is an implementation of the +// entityresolution.EntityResolutionService service. +type EntityResolutionServiceHandler interface { + ResolveEntities(context.Context, *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) + CreateEntityChainFromJwt(context.Context, *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) +} + +// NewEntityResolutionServiceHandler builds an HTTP handler from the service implementation. It +// returns the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewEntityResolutionServiceHandler(svc EntityResolutionServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + entityResolutionServiceResolveEntitiesHandler := connect.NewUnaryHandler( + EntityResolutionServiceResolveEntitiesProcedure, + svc.ResolveEntities, + connect.WithSchema(entityResolutionServiceResolveEntitiesMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + entityResolutionServiceCreateEntityChainFromJwtHandler := connect.NewUnaryHandler( + EntityResolutionServiceCreateEntityChainFromJwtProcedure, + svc.CreateEntityChainFromJwt, + connect.WithSchema(entityResolutionServiceCreateEntityChainFromJwtMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/entityresolution.EntityResolutionService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case EntityResolutionServiceResolveEntitiesProcedure: + entityResolutionServiceResolveEntitiesHandler.ServeHTTP(w, r) + case EntityResolutionServiceCreateEntityChainFromJwtProcedure: + entityResolutionServiceCreateEntityChainFromJwtHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedEntityResolutionServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedEntityResolutionServiceHandler struct{} + +func (UnimplementedEntityResolutionServiceHandler) ResolveEntities(context.Context, *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("entityresolution.EntityResolutionService.ResolveEntities is not implemented")) +} + +func (UnimplementedEntityResolutionServiceHandler) CreateEntityChainFromJwt(context.Context, *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("entityresolution.EntityResolutionService.CreateEntityChainFromJwt is not implemented")) +} diff --git a/protocol/go/go.mod b/protocol/go/go.mod index 6bf4c6dfca..095c29e6fc 100644 --- a/protocol/go/go.mod +++ b/protocol/go/go.mod @@ -4,10 +4,11 @@ go 1.21 require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 + connectrpc.com/connect v1.17.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 google.golang.org/grpc v1.62.1 - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.34.2 ) require ( diff --git a/protocol/go/go.sum b/protocol/go/go.sum index 273670cc83..12d5c4bb59 100644 --- a/protocol/go/go.sum +++ b/protocol/go/go.sum @@ -1,5 +1,7 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 h1:0nWhrRcnkgw1kwJ7xibIO8bqfOA7pBzBjGCDBxIHch8= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1/go.mod h1:Tgn5bgL220vkFOI0KPStlcClPeOJzAv4uT+V8JXGUnw= +connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= +connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -22,5 +24,6 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go. google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/protocol/go/kas/kasconnect/kas.connect.go b/protocol/go/kas/kasconnect/kas.connect.go new file mode 100644 index 0000000000..7af392004f --- /dev/null +++ b/protocol/go/kas/kasconnect/kas.connect.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: kas/kas.proto + +package kasconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + kas "github.com/opentdf/platform/protocol/go/kas" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AccessServiceName is the fully-qualified name of the AccessService service. + AccessServiceName = "kas.AccessService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AccessServicePublicKeyProcedure is the fully-qualified name of the AccessService's PublicKey RPC. + AccessServicePublicKeyProcedure = "/kas.AccessService/PublicKey" + // AccessServiceLegacyPublicKeyProcedure is the fully-qualified name of the AccessService's + // LegacyPublicKey RPC. + AccessServiceLegacyPublicKeyProcedure = "/kas.AccessService/LegacyPublicKey" + // AccessServiceRewrapProcedure is the fully-qualified name of the AccessService's Rewrap RPC. + AccessServiceRewrapProcedure = "/kas.AccessService/Rewrap" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + accessServiceServiceDescriptor = kas.File_kas_kas_proto.Services().ByName("AccessService") + accessServicePublicKeyMethodDescriptor = accessServiceServiceDescriptor.Methods().ByName("PublicKey") + accessServiceLegacyPublicKeyMethodDescriptor = accessServiceServiceDescriptor.Methods().ByName("LegacyPublicKey") + accessServiceRewrapMethodDescriptor = accessServiceServiceDescriptor.Methods().ByName("Rewrap") +) + +// AccessServiceClient is a client for the kas.AccessService service. +type AccessServiceClient interface { + PublicKey(context.Context, *connect.Request[kas.PublicKeyRequest]) (*connect.Response[kas.PublicKeyResponse], error) + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME + LegacyPublicKey(context.Context, *connect.Request[kas.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) + Rewrap(context.Context, *connect.Request[kas.RewrapRequest]) (*connect.Response[kas.RewrapResponse], error) +} + +// NewAccessServiceClient constructs a client for the kas.AccessService service. By default, it uses +// the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAccessServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AccessServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &accessServiceClient{ + publicKey: connect.NewClient[kas.PublicKeyRequest, kas.PublicKeyResponse]( + httpClient, + baseURL+AccessServicePublicKeyProcedure, + connect.WithSchema(accessServicePublicKeyMethodDescriptor), + connect.WithClientOptions(opts...), + ), + legacyPublicKey: connect.NewClient[kas.LegacyPublicKeyRequest, wrapperspb.StringValue]( + httpClient, + baseURL+AccessServiceLegacyPublicKeyProcedure, + connect.WithSchema(accessServiceLegacyPublicKeyMethodDescriptor), + connect.WithClientOptions(opts...), + ), + rewrap: connect.NewClient[kas.RewrapRequest, kas.RewrapResponse]( + httpClient, + baseURL+AccessServiceRewrapProcedure, + connect.WithSchema(accessServiceRewrapMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// accessServiceClient implements AccessServiceClient. +type accessServiceClient struct { + publicKey *connect.Client[kas.PublicKeyRequest, kas.PublicKeyResponse] + legacyPublicKey *connect.Client[kas.LegacyPublicKeyRequest, wrapperspb.StringValue] + rewrap *connect.Client[kas.RewrapRequest, kas.RewrapResponse] +} + +// PublicKey calls kas.AccessService.PublicKey. +func (c *accessServiceClient) PublicKey(ctx context.Context, req *connect.Request[kas.PublicKeyRequest]) (*connect.Response[kas.PublicKeyResponse], error) { + return c.publicKey.CallUnary(ctx, req) +} + +// LegacyPublicKey calls kas.AccessService.LegacyPublicKey. +func (c *accessServiceClient) LegacyPublicKey(ctx context.Context, req *connect.Request[kas.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) { + return c.legacyPublicKey.CallUnary(ctx, req) +} + +// Rewrap calls kas.AccessService.Rewrap. +func (c *accessServiceClient) Rewrap(ctx context.Context, req *connect.Request[kas.RewrapRequest]) (*connect.Response[kas.RewrapResponse], error) { + return c.rewrap.CallUnary(ctx, req) +} + +// AccessServiceHandler is an implementation of the kas.AccessService service. +type AccessServiceHandler interface { + PublicKey(context.Context, *connect.Request[kas.PublicKeyRequest]) (*connect.Response[kas.PublicKeyResponse], error) + // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME + LegacyPublicKey(context.Context, *connect.Request[kas.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) + Rewrap(context.Context, *connect.Request[kas.RewrapRequest]) (*connect.Response[kas.RewrapResponse], error) +} + +// NewAccessServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAccessServiceHandler(svc AccessServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + accessServicePublicKeyHandler := connect.NewUnaryHandler( + AccessServicePublicKeyProcedure, + svc.PublicKey, + connect.WithSchema(accessServicePublicKeyMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + accessServiceLegacyPublicKeyHandler := connect.NewUnaryHandler( + AccessServiceLegacyPublicKeyProcedure, + svc.LegacyPublicKey, + connect.WithSchema(accessServiceLegacyPublicKeyMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + accessServiceRewrapHandler := connect.NewUnaryHandler( + AccessServiceRewrapProcedure, + svc.Rewrap, + connect.WithSchema(accessServiceRewrapMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/kas.AccessService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AccessServicePublicKeyProcedure: + accessServicePublicKeyHandler.ServeHTTP(w, r) + case AccessServiceLegacyPublicKeyProcedure: + accessServiceLegacyPublicKeyHandler.ServeHTTP(w, r) + case AccessServiceRewrapProcedure: + accessServiceRewrapHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAccessServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAccessServiceHandler struct{} + +func (UnimplementedAccessServiceHandler) PublicKey(context.Context, *connect.Request[kas.PublicKeyRequest]) (*connect.Response[kas.PublicKeyResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("kas.AccessService.PublicKey is not implemented")) +} + +func (UnimplementedAccessServiceHandler) LegacyPublicKey(context.Context, *connect.Request[kas.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("kas.AccessService.LegacyPublicKey is not implemented")) +} + +func (UnimplementedAccessServiceHandler) Rewrap(context.Context, *connect.Request[kas.RewrapRequest]) (*connect.Response[kas.RewrapResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("kas.AccessService.Rewrap is not implemented")) +} diff --git a/protocol/go/policy/attributes/attributesconnect/attributes.connect.go b/protocol/go/policy/attributes/attributesconnect/attributes.connect.go new file mode 100644 index 0000000000..bcb8fb964d --- /dev/null +++ b/protocol/go/policy/attributes/attributesconnect/attributes.connect.go @@ -0,0 +1,555 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/attributes/attributes.proto + +package attributesconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + attributes "github.com/opentdf/platform/protocol/go/policy/attributes" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AttributesServiceName is the fully-qualified name of the AttributesService service. + AttributesServiceName = "policy.attributes.AttributesService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AttributesServiceListAttributesProcedure is the fully-qualified name of the AttributesService's + // ListAttributes RPC. + AttributesServiceListAttributesProcedure = "/policy.attributes.AttributesService/ListAttributes" + // AttributesServiceListAttributeValuesProcedure is the fully-qualified name of the + // AttributesService's ListAttributeValues RPC. + AttributesServiceListAttributeValuesProcedure = "/policy.attributes.AttributesService/ListAttributeValues" + // AttributesServiceGetAttributeProcedure is the fully-qualified name of the AttributesService's + // GetAttribute RPC. + AttributesServiceGetAttributeProcedure = "/policy.attributes.AttributesService/GetAttribute" + // AttributesServiceGetAttributeValuesByFqnsProcedure is the fully-qualified name of the + // AttributesService's GetAttributeValuesByFqns RPC. + AttributesServiceGetAttributeValuesByFqnsProcedure = "/policy.attributes.AttributesService/GetAttributeValuesByFqns" + // AttributesServiceCreateAttributeProcedure is the fully-qualified name of the AttributesService's + // CreateAttribute RPC. + AttributesServiceCreateAttributeProcedure = "/policy.attributes.AttributesService/CreateAttribute" + // AttributesServiceUpdateAttributeProcedure is the fully-qualified name of the AttributesService's + // UpdateAttribute RPC. + AttributesServiceUpdateAttributeProcedure = "/policy.attributes.AttributesService/UpdateAttribute" + // AttributesServiceDeactivateAttributeProcedure is the fully-qualified name of the + // AttributesService's DeactivateAttribute RPC. + AttributesServiceDeactivateAttributeProcedure = "/policy.attributes.AttributesService/DeactivateAttribute" + // AttributesServiceGetAttributeValueProcedure is the fully-qualified name of the + // AttributesService's GetAttributeValue RPC. + AttributesServiceGetAttributeValueProcedure = "/policy.attributes.AttributesService/GetAttributeValue" + // AttributesServiceCreateAttributeValueProcedure is the fully-qualified name of the + // AttributesService's CreateAttributeValue RPC. + AttributesServiceCreateAttributeValueProcedure = "/policy.attributes.AttributesService/CreateAttributeValue" + // AttributesServiceUpdateAttributeValueProcedure is the fully-qualified name of the + // AttributesService's UpdateAttributeValue RPC. + AttributesServiceUpdateAttributeValueProcedure = "/policy.attributes.AttributesService/UpdateAttributeValue" + // AttributesServiceDeactivateAttributeValueProcedure is the fully-qualified name of the + // AttributesService's DeactivateAttributeValue RPC. + AttributesServiceDeactivateAttributeValueProcedure = "/policy.attributes.AttributesService/DeactivateAttributeValue" + // AttributesServiceAssignKeyAccessServerToAttributeProcedure is the fully-qualified name of the + // AttributesService's AssignKeyAccessServerToAttribute RPC. + AttributesServiceAssignKeyAccessServerToAttributeProcedure = "/policy.attributes.AttributesService/AssignKeyAccessServerToAttribute" + // AttributesServiceRemoveKeyAccessServerFromAttributeProcedure is the fully-qualified name of the + // AttributesService's RemoveKeyAccessServerFromAttribute RPC. + AttributesServiceRemoveKeyAccessServerFromAttributeProcedure = "/policy.attributes.AttributesService/RemoveKeyAccessServerFromAttribute" + // AttributesServiceAssignKeyAccessServerToValueProcedure is the fully-qualified name of the + // AttributesService's AssignKeyAccessServerToValue RPC. + AttributesServiceAssignKeyAccessServerToValueProcedure = "/policy.attributes.AttributesService/AssignKeyAccessServerToValue" + // AttributesServiceRemoveKeyAccessServerFromValueProcedure is the fully-qualified name of the + // AttributesService's RemoveKeyAccessServerFromValue RPC. + AttributesServiceRemoveKeyAccessServerFromValueProcedure = "/policy.attributes.AttributesService/RemoveKeyAccessServerFromValue" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + attributesServiceServiceDescriptor = attributes.File_policy_attributes_attributes_proto.Services().ByName("AttributesService") + attributesServiceListAttributesMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("ListAttributes") + attributesServiceListAttributeValuesMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("ListAttributeValues") + attributesServiceGetAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("GetAttribute") + attributesServiceGetAttributeValuesByFqnsMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("GetAttributeValuesByFqns") + attributesServiceCreateAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("CreateAttribute") + attributesServiceUpdateAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("UpdateAttribute") + attributesServiceDeactivateAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("DeactivateAttribute") + attributesServiceGetAttributeValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("GetAttributeValue") + attributesServiceCreateAttributeValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("CreateAttributeValue") + attributesServiceUpdateAttributeValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("UpdateAttributeValue") + attributesServiceDeactivateAttributeValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("DeactivateAttributeValue") + attributesServiceAssignKeyAccessServerToAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("AssignKeyAccessServerToAttribute") + attributesServiceRemoveKeyAccessServerFromAttributeMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("RemoveKeyAccessServerFromAttribute") + attributesServiceAssignKeyAccessServerToValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("AssignKeyAccessServerToValue") + attributesServiceRemoveKeyAccessServerFromValueMethodDescriptor = attributesServiceServiceDescriptor.Methods().ByName("RemoveKeyAccessServerFromValue") +) + +// AttributesServiceClient is a client for the policy.attributes.AttributesService service. +type AttributesServiceClient interface { + // --------------------------------------* + // Attribute RPCs + // --------------------------------------- + ListAttributes(context.Context, *connect.Request[attributes.ListAttributesRequest]) (*connect.Response[attributes.ListAttributesResponse], error) + ListAttributeValues(context.Context, *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) + GetAttribute(context.Context, *connect.Request[attributes.GetAttributeRequest]) (*connect.Response[attributes.GetAttributeResponse], error) + GetAttributeValuesByFqns(context.Context, *connect.Request[attributes.GetAttributeValuesByFqnsRequest]) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) + CreateAttribute(context.Context, *connect.Request[attributes.CreateAttributeRequest]) (*connect.Response[attributes.CreateAttributeResponse], error) + UpdateAttribute(context.Context, *connect.Request[attributes.UpdateAttributeRequest]) (*connect.Response[attributes.UpdateAttributeResponse], error) + DeactivateAttribute(context.Context, *connect.Request[attributes.DeactivateAttributeRequest]) (*connect.Response[attributes.DeactivateAttributeResponse], error) + // --------------------------------------* + // Value RPCs + // --------------------------------------- + GetAttributeValue(context.Context, *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) + CreateAttributeValue(context.Context, *connect.Request[attributes.CreateAttributeValueRequest]) (*connect.Response[attributes.CreateAttributeValueResponse], error) + UpdateAttributeValue(context.Context, *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) + DeactivateAttributeValue(context.Context, *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) + // --------------------------------------* + // Attribute <> Key Access Server RPCs + // --------------------------------------- + AssignKeyAccessServerToAttribute(context.Context, *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) + RemoveKeyAccessServerFromAttribute(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) + AssignKeyAccessServerToValue(context.Context, *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) + RemoveKeyAccessServerFromValue(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) +} + +// NewAttributesServiceClient constructs a client for the policy.attributes.AttributesService +// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for +// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply +// the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAttributesServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AttributesServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &attributesServiceClient{ + listAttributes: connect.NewClient[attributes.ListAttributesRequest, attributes.ListAttributesResponse]( + httpClient, + baseURL+AttributesServiceListAttributesProcedure, + connect.WithSchema(attributesServiceListAttributesMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listAttributeValues: connect.NewClient[attributes.ListAttributeValuesRequest, attributes.ListAttributeValuesResponse]( + httpClient, + baseURL+AttributesServiceListAttributeValuesProcedure, + connect.WithSchema(attributesServiceListAttributeValuesMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getAttribute: connect.NewClient[attributes.GetAttributeRequest, attributes.GetAttributeResponse]( + httpClient, + baseURL+AttributesServiceGetAttributeProcedure, + connect.WithSchema(attributesServiceGetAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getAttributeValuesByFqns: connect.NewClient[attributes.GetAttributeValuesByFqnsRequest, attributes.GetAttributeValuesByFqnsResponse]( + httpClient, + baseURL+AttributesServiceGetAttributeValuesByFqnsProcedure, + connect.WithSchema(attributesServiceGetAttributeValuesByFqnsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createAttribute: connect.NewClient[attributes.CreateAttributeRequest, attributes.CreateAttributeResponse]( + httpClient, + baseURL+AttributesServiceCreateAttributeProcedure, + connect.WithSchema(attributesServiceCreateAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateAttribute: connect.NewClient[attributes.UpdateAttributeRequest, attributes.UpdateAttributeResponse]( + httpClient, + baseURL+AttributesServiceUpdateAttributeProcedure, + connect.WithSchema(attributesServiceUpdateAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deactivateAttribute: connect.NewClient[attributes.DeactivateAttributeRequest, attributes.DeactivateAttributeResponse]( + httpClient, + baseURL+AttributesServiceDeactivateAttributeProcedure, + connect.WithSchema(attributesServiceDeactivateAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getAttributeValue: connect.NewClient[attributes.GetAttributeValueRequest, attributes.GetAttributeValueResponse]( + httpClient, + baseURL+AttributesServiceGetAttributeValueProcedure, + connect.WithSchema(attributesServiceGetAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createAttributeValue: connect.NewClient[attributes.CreateAttributeValueRequest, attributes.CreateAttributeValueResponse]( + httpClient, + baseURL+AttributesServiceCreateAttributeValueProcedure, + connect.WithSchema(attributesServiceCreateAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateAttributeValue: connect.NewClient[attributes.UpdateAttributeValueRequest, attributes.UpdateAttributeValueResponse]( + httpClient, + baseURL+AttributesServiceUpdateAttributeValueProcedure, + connect.WithSchema(attributesServiceUpdateAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deactivateAttributeValue: connect.NewClient[attributes.DeactivateAttributeValueRequest, attributes.DeactivateAttributeValueResponse]( + httpClient, + baseURL+AttributesServiceDeactivateAttributeValueProcedure, + connect.WithSchema(attributesServiceDeactivateAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + assignKeyAccessServerToAttribute: connect.NewClient[attributes.AssignKeyAccessServerToAttributeRequest, attributes.AssignKeyAccessServerToAttributeResponse]( + httpClient, + baseURL+AttributesServiceAssignKeyAccessServerToAttributeProcedure, + connect.WithSchema(attributesServiceAssignKeyAccessServerToAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + removeKeyAccessServerFromAttribute: connect.NewClient[attributes.RemoveKeyAccessServerFromAttributeRequest, attributes.RemoveKeyAccessServerFromAttributeResponse]( + httpClient, + baseURL+AttributesServiceRemoveKeyAccessServerFromAttributeProcedure, + connect.WithSchema(attributesServiceRemoveKeyAccessServerFromAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + assignKeyAccessServerToValue: connect.NewClient[attributes.AssignKeyAccessServerToValueRequest, attributes.AssignKeyAccessServerToValueResponse]( + httpClient, + baseURL+AttributesServiceAssignKeyAccessServerToValueProcedure, + connect.WithSchema(attributesServiceAssignKeyAccessServerToValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + removeKeyAccessServerFromValue: connect.NewClient[attributes.RemoveKeyAccessServerFromValueRequest, attributes.RemoveKeyAccessServerFromValueResponse]( + httpClient, + baseURL+AttributesServiceRemoveKeyAccessServerFromValueProcedure, + connect.WithSchema(attributesServiceRemoveKeyAccessServerFromValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// attributesServiceClient implements AttributesServiceClient. +type attributesServiceClient struct { + listAttributes *connect.Client[attributes.ListAttributesRequest, attributes.ListAttributesResponse] + listAttributeValues *connect.Client[attributes.ListAttributeValuesRequest, attributes.ListAttributeValuesResponse] + getAttribute *connect.Client[attributes.GetAttributeRequest, attributes.GetAttributeResponse] + getAttributeValuesByFqns *connect.Client[attributes.GetAttributeValuesByFqnsRequest, attributes.GetAttributeValuesByFqnsResponse] + createAttribute *connect.Client[attributes.CreateAttributeRequest, attributes.CreateAttributeResponse] + updateAttribute *connect.Client[attributes.UpdateAttributeRequest, attributes.UpdateAttributeResponse] + deactivateAttribute *connect.Client[attributes.DeactivateAttributeRequest, attributes.DeactivateAttributeResponse] + getAttributeValue *connect.Client[attributes.GetAttributeValueRequest, attributes.GetAttributeValueResponse] + createAttributeValue *connect.Client[attributes.CreateAttributeValueRequest, attributes.CreateAttributeValueResponse] + updateAttributeValue *connect.Client[attributes.UpdateAttributeValueRequest, attributes.UpdateAttributeValueResponse] + deactivateAttributeValue *connect.Client[attributes.DeactivateAttributeValueRequest, attributes.DeactivateAttributeValueResponse] + assignKeyAccessServerToAttribute *connect.Client[attributes.AssignKeyAccessServerToAttributeRequest, attributes.AssignKeyAccessServerToAttributeResponse] + removeKeyAccessServerFromAttribute *connect.Client[attributes.RemoveKeyAccessServerFromAttributeRequest, attributes.RemoveKeyAccessServerFromAttributeResponse] + assignKeyAccessServerToValue *connect.Client[attributes.AssignKeyAccessServerToValueRequest, attributes.AssignKeyAccessServerToValueResponse] + removeKeyAccessServerFromValue *connect.Client[attributes.RemoveKeyAccessServerFromValueRequest, attributes.RemoveKeyAccessServerFromValueResponse] +} + +// ListAttributes calls policy.attributes.AttributesService.ListAttributes. +func (c *attributesServiceClient) ListAttributes(ctx context.Context, req *connect.Request[attributes.ListAttributesRequest]) (*connect.Response[attributes.ListAttributesResponse], error) { + return c.listAttributes.CallUnary(ctx, req) +} + +// ListAttributeValues calls policy.attributes.AttributesService.ListAttributeValues. +func (c *attributesServiceClient) ListAttributeValues(ctx context.Context, req *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) { + return c.listAttributeValues.CallUnary(ctx, req) +} + +// GetAttribute calls policy.attributes.AttributesService.GetAttribute. +func (c *attributesServiceClient) GetAttribute(ctx context.Context, req *connect.Request[attributes.GetAttributeRequest]) (*connect.Response[attributes.GetAttributeResponse], error) { + return c.getAttribute.CallUnary(ctx, req) +} + +// GetAttributeValuesByFqns calls policy.attributes.AttributesService.GetAttributeValuesByFqns. +func (c *attributesServiceClient) GetAttributeValuesByFqns(ctx context.Context, req *connect.Request[attributes.GetAttributeValuesByFqnsRequest]) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) { + return c.getAttributeValuesByFqns.CallUnary(ctx, req) +} + +// CreateAttribute calls policy.attributes.AttributesService.CreateAttribute. +func (c *attributesServiceClient) CreateAttribute(ctx context.Context, req *connect.Request[attributes.CreateAttributeRequest]) (*connect.Response[attributes.CreateAttributeResponse], error) { + return c.createAttribute.CallUnary(ctx, req) +} + +// UpdateAttribute calls policy.attributes.AttributesService.UpdateAttribute. +func (c *attributesServiceClient) UpdateAttribute(ctx context.Context, req *connect.Request[attributes.UpdateAttributeRequest]) (*connect.Response[attributes.UpdateAttributeResponse], error) { + return c.updateAttribute.CallUnary(ctx, req) +} + +// DeactivateAttribute calls policy.attributes.AttributesService.DeactivateAttribute. +func (c *attributesServiceClient) DeactivateAttribute(ctx context.Context, req *connect.Request[attributes.DeactivateAttributeRequest]) (*connect.Response[attributes.DeactivateAttributeResponse], error) { + return c.deactivateAttribute.CallUnary(ctx, req) +} + +// GetAttributeValue calls policy.attributes.AttributesService.GetAttributeValue. +func (c *attributesServiceClient) GetAttributeValue(ctx context.Context, req *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { + return c.getAttributeValue.CallUnary(ctx, req) +} + +// CreateAttributeValue calls policy.attributes.AttributesService.CreateAttributeValue. +func (c *attributesServiceClient) CreateAttributeValue(ctx context.Context, req *connect.Request[attributes.CreateAttributeValueRequest]) (*connect.Response[attributes.CreateAttributeValueResponse], error) { + return c.createAttributeValue.CallUnary(ctx, req) +} + +// UpdateAttributeValue calls policy.attributes.AttributesService.UpdateAttributeValue. +func (c *attributesServiceClient) UpdateAttributeValue(ctx context.Context, req *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) { + return c.updateAttributeValue.CallUnary(ctx, req) +} + +// DeactivateAttributeValue calls policy.attributes.AttributesService.DeactivateAttributeValue. +func (c *attributesServiceClient) DeactivateAttributeValue(ctx context.Context, req *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) { + return c.deactivateAttributeValue.CallUnary(ctx, req) +} + +// AssignKeyAccessServerToAttribute calls +// policy.attributes.AttributesService.AssignKeyAccessServerToAttribute. +func (c *attributesServiceClient) AssignKeyAccessServerToAttribute(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) { + return c.assignKeyAccessServerToAttribute.CallUnary(ctx, req) +} + +// RemoveKeyAccessServerFromAttribute calls +// policy.attributes.AttributesService.RemoveKeyAccessServerFromAttribute. +func (c *attributesServiceClient) RemoveKeyAccessServerFromAttribute(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) { + return c.removeKeyAccessServerFromAttribute.CallUnary(ctx, req) +} + +// AssignKeyAccessServerToValue calls +// policy.attributes.AttributesService.AssignKeyAccessServerToValue. +func (c *attributesServiceClient) AssignKeyAccessServerToValue(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) { + return c.assignKeyAccessServerToValue.CallUnary(ctx, req) +} + +// RemoveKeyAccessServerFromValue calls +// policy.attributes.AttributesService.RemoveKeyAccessServerFromValue. +func (c *attributesServiceClient) RemoveKeyAccessServerFromValue(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) { + return c.removeKeyAccessServerFromValue.CallUnary(ctx, req) +} + +// AttributesServiceHandler is an implementation of the policy.attributes.AttributesService service. +type AttributesServiceHandler interface { + // --------------------------------------* + // Attribute RPCs + // --------------------------------------- + ListAttributes(context.Context, *connect.Request[attributes.ListAttributesRequest]) (*connect.Response[attributes.ListAttributesResponse], error) + ListAttributeValues(context.Context, *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) + GetAttribute(context.Context, *connect.Request[attributes.GetAttributeRequest]) (*connect.Response[attributes.GetAttributeResponse], error) + GetAttributeValuesByFqns(context.Context, *connect.Request[attributes.GetAttributeValuesByFqnsRequest]) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) + CreateAttribute(context.Context, *connect.Request[attributes.CreateAttributeRequest]) (*connect.Response[attributes.CreateAttributeResponse], error) + UpdateAttribute(context.Context, *connect.Request[attributes.UpdateAttributeRequest]) (*connect.Response[attributes.UpdateAttributeResponse], error) + DeactivateAttribute(context.Context, *connect.Request[attributes.DeactivateAttributeRequest]) (*connect.Response[attributes.DeactivateAttributeResponse], error) + // --------------------------------------* + // Value RPCs + // --------------------------------------- + GetAttributeValue(context.Context, *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) + CreateAttributeValue(context.Context, *connect.Request[attributes.CreateAttributeValueRequest]) (*connect.Response[attributes.CreateAttributeValueResponse], error) + UpdateAttributeValue(context.Context, *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) + DeactivateAttributeValue(context.Context, *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) + // --------------------------------------* + // Attribute <> Key Access Server RPCs + // --------------------------------------- + AssignKeyAccessServerToAttribute(context.Context, *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) + RemoveKeyAccessServerFromAttribute(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) + AssignKeyAccessServerToValue(context.Context, *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) + RemoveKeyAccessServerFromValue(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) +} + +// NewAttributesServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAttributesServiceHandler(svc AttributesServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + attributesServiceListAttributesHandler := connect.NewUnaryHandler( + AttributesServiceListAttributesProcedure, + svc.ListAttributes, + connect.WithSchema(attributesServiceListAttributesMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceListAttributeValuesHandler := connect.NewUnaryHandler( + AttributesServiceListAttributeValuesProcedure, + svc.ListAttributeValues, + connect.WithSchema(attributesServiceListAttributeValuesMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceGetAttributeHandler := connect.NewUnaryHandler( + AttributesServiceGetAttributeProcedure, + svc.GetAttribute, + connect.WithSchema(attributesServiceGetAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceGetAttributeValuesByFqnsHandler := connect.NewUnaryHandler( + AttributesServiceGetAttributeValuesByFqnsProcedure, + svc.GetAttributeValuesByFqns, + connect.WithSchema(attributesServiceGetAttributeValuesByFqnsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceCreateAttributeHandler := connect.NewUnaryHandler( + AttributesServiceCreateAttributeProcedure, + svc.CreateAttribute, + connect.WithSchema(attributesServiceCreateAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceUpdateAttributeHandler := connect.NewUnaryHandler( + AttributesServiceUpdateAttributeProcedure, + svc.UpdateAttribute, + connect.WithSchema(attributesServiceUpdateAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceDeactivateAttributeHandler := connect.NewUnaryHandler( + AttributesServiceDeactivateAttributeProcedure, + svc.DeactivateAttribute, + connect.WithSchema(attributesServiceDeactivateAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceGetAttributeValueHandler := connect.NewUnaryHandler( + AttributesServiceGetAttributeValueProcedure, + svc.GetAttributeValue, + connect.WithSchema(attributesServiceGetAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceCreateAttributeValueHandler := connect.NewUnaryHandler( + AttributesServiceCreateAttributeValueProcedure, + svc.CreateAttributeValue, + connect.WithSchema(attributesServiceCreateAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceUpdateAttributeValueHandler := connect.NewUnaryHandler( + AttributesServiceUpdateAttributeValueProcedure, + svc.UpdateAttributeValue, + connect.WithSchema(attributesServiceUpdateAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceDeactivateAttributeValueHandler := connect.NewUnaryHandler( + AttributesServiceDeactivateAttributeValueProcedure, + svc.DeactivateAttributeValue, + connect.WithSchema(attributesServiceDeactivateAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceAssignKeyAccessServerToAttributeHandler := connect.NewUnaryHandler( + AttributesServiceAssignKeyAccessServerToAttributeProcedure, + svc.AssignKeyAccessServerToAttribute, + connect.WithSchema(attributesServiceAssignKeyAccessServerToAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceRemoveKeyAccessServerFromAttributeHandler := connect.NewUnaryHandler( + AttributesServiceRemoveKeyAccessServerFromAttributeProcedure, + svc.RemoveKeyAccessServerFromAttribute, + connect.WithSchema(attributesServiceRemoveKeyAccessServerFromAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceAssignKeyAccessServerToValueHandler := connect.NewUnaryHandler( + AttributesServiceAssignKeyAccessServerToValueProcedure, + svc.AssignKeyAccessServerToValue, + connect.WithSchema(attributesServiceAssignKeyAccessServerToValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + attributesServiceRemoveKeyAccessServerFromValueHandler := connect.NewUnaryHandler( + AttributesServiceRemoveKeyAccessServerFromValueProcedure, + svc.RemoveKeyAccessServerFromValue, + connect.WithSchema(attributesServiceRemoveKeyAccessServerFromValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.attributes.AttributesService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AttributesServiceListAttributesProcedure: + attributesServiceListAttributesHandler.ServeHTTP(w, r) + case AttributesServiceListAttributeValuesProcedure: + attributesServiceListAttributeValuesHandler.ServeHTTP(w, r) + case AttributesServiceGetAttributeProcedure: + attributesServiceGetAttributeHandler.ServeHTTP(w, r) + case AttributesServiceGetAttributeValuesByFqnsProcedure: + attributesServiceGetAttributeValuesByFqnsHandler.ServeHTTP(w, r) + case AttributesServiceCreateAttributeProcedure: + attributesServiceCreateAttributeHandler.ServeHTTP(w, r) + case AttributesServiceUpdateAttributeProcedure: + attributesServiceUpdateAttributeHandler.ServeHTTP(w, r) + case AttributesServiceDeactivateAttributeProcedure: + attributesServiceDeactivateAttributeHandler.ServeHTTP(w, r) + case AttributesServiceGetAttributeValueProcedure: + attributesServiceGetAttributeValueHandler.ServeHTTP(w, r) + case AttributesServiceCreateAttributeValueProcedure: + attributesServiceCreateAttributeValueHandler.ServeHTTP(w, r) + case AttributesServiceUpdateAttributeValueProcedure: + attributesServiceUpdateAttributeValueHandler.ServeHTTP(w, r) + case AttributesServiceDeactivateAttributeValueProcedure: + attributesServiceDeactivateAttributeValueHandler.ServeHTTP(w, r) + case AttributesServiceAssignKeyAccessServerToAttributeProcedure: + attributesServiceAssignKeyAccessServerToAttributeHandler.ServeHTTP(w, r) + case AttributesServiceRemoveKeyAccessServerFromAttributeProcedure: + attributesServiceRemoveKeyAccessServerFromAttributeHandler.ServeHTTP(w, r) + case AttributesServiceAssignKeyAccessServerToValueProcedure: + attributesServiceAssignKeyAccessServerToValueHandler.ServeHTTP(w, r) + case AttributesServiceRemoveKeyAccessServerFromValueProcedure: + attributesServiceRemoveKeyAccessServerFromValueHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAttributesServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAttributesServiceHandler struct{} + +func (UnimplementedAttributesServiceHandler) ListAttributes(context.Context, *connect.Request[attributes.ListAttributesRequest]) (*connect.Response[attributes.ListAttributesResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.ListAttributes is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) ListAttributeValues(context.Context, *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.ListAttributeValues is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) GetAttribute(context.Context, *connect.Request[attributes.GetAttributeRequest]) (*connect.Response[attributes.GetAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.GetAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) GetAttributeValuesByFqns(context.Context, *connect.Request[attributes.GetAttributeValuesByFqnsRequest]) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.GetAttributeValuesByFqns is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) CreateAttribute(context.Context, *connect.Request[attributes.CreateAttributeRequest]) (*connect.Response[attributes.CreateAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.CreateAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) UpdateAttribute(context.Context, *connect.Request[attributes.UpdateAttributeRequest]) (*connect.Response[attributes.UpdateAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.UpdateAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) DeactivateAttribute(context.Context, *connect.Request[attributes.DeactivateAttributeRequest]) (*connect.Response[attributes.DeactivateAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.DeactivateAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) GetAttributeValue(context.Context, *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.GetAttributeValue is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) CreateAttributeValue(context.Context, *connect.Request[attributes.CreateAttributeValueRequest]) (*connect.Response[attributes.CreateAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.CreateAttributeValue is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) UpdateAttributeValue(context.Context, *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.UpdateAttributeValue is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) DeactivateAttributeValue(context.Context, *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.DeactivateAttributeValue is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) AssignKeyAccessServerToAttribute(context.Context, *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.AssignKeyAccessServerToAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) RemoveKeyAccessServerFromAttribute(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.RemoveKeyAccessServerFromAttribute is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) AssignKeyAccessServerToValue(context.Context, *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.AssignKeyAccessServerToValue is not implemented")) +} + +func (UnimplementedAttributesServiceHandler) RemoveKeyAccessServerFromValue(context.Context, *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.attributes.AttributesService.RemoveKeyAccessServerFromValue is not implemented")) +} diff --git a/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go b/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go new file mode 100644 index 0000000000..3cfc542bcb --- /dev/null +++ b/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go @@ -0,0 +1,272 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/kasregistry/key_access_server_registry.proto + +package kasregistryconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + kasregistry "github.com/opentdf/platform/protocol/go/policy/kasregistry" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // KeyAccessServerRegistryServiceName is the fully-qualified name of the + // KeyAccessServerRegistryService service. + KeyAccessServerRegistryServiceName = "policy.kasregistry.KeyAccessServerRegistryService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // KeyAccessServerRegistryServiceListKeyAccessServersProcedure is the fully-qualified name of the + // KeyAccessServerRegistryService's ListKeyAccessServers RPC. + KeyAccessServerRegistryServiceListKeyAccessServersProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/ListKeyAccessServers" + // KeyAccessServerRegistryServiceGetKeyAccessServerProcedure is the fully-qualified name of the + // KeyAccessServerRegistryService's GetKeyAccessServer RPC. + KeyAccessServerRegistryServiceGetKeyAccessServerProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/GetKeyAccessServer" + // KeyAccessServerRegistryServiceCreateKeyAccessServerProcedure is the fully-qualified name of the + // KeyAccessServerRegistryService's CreateKeyAccessServer RPC. + KeyAccessServerRegistryServiceCreateKeyAccessServerProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/CreateKeyAccessServer" + // KeyAccessServerRegistryServiceUpdateKeyAccessServerProcedure is the fully-qualified name of the + // KeyAccessServerRegistryService's UpdateKeyAccessServer RPC. + KeyAccessServerRegistryServiceUpdateKeyAccessServerProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/UpdateKeyAccessServer" + // KeyAccessServerRegistryServiceDeleteKeyAccessServerProcedure is the fully-qualified name of the + // KeyAccessServerRegistryService's DeleteKeyAccessServer RPC. + KeyAccessServerRegistryServiceDeleteKeyAccessServerProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/DeleteKeyAccessServer" + // KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure is the fully-qualified name of + // the KeyAccessServerRegistryService's ListKeyAccessServerGrants RPC. + KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure = "/policy.kasregistry.KeyAccessServerRegistryService/ListKeyAccessServerGrants" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + keyAccessServerRegistryServiceServiceDescriptor = kasregistry.File_policy_kasregistry_key_access_server_registry_proto.Services().ByName("KeyAccessServerRegistryService") + keyAccessServerRegistryServiceListKeyAccessServersMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("ListKeyAccessServers") + keyAccessServerRegistryServiceGetKeyAccessServerMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("GetKeyAccessServer") + keyAccessServerRegistryServiceCreateKeyAccessServerMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("CreateKeyAccessServer") + keyAccessServerRegistryServiceUpdateKeyAccessServerMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("UpdateKeyAccessServer") + keyAccessServerRegistryServiceDeleteKeyAccessServerMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("DeleteKeyAccessServer") + keyAccessServerRegistryServiceListKeyAccessServerGrantsMethodDescriptor = keyAccessServerRegistryServiceServiceDescriptor.Methods().ByName("ListKeyAccessServerGrants") +) + +// KeyAccessServerRegistryServiceClient is a client for the +// policy.kasregistry.KeyAccessServerRegistryService service. +type KeyAccessServerRegistryServiceClient interface { + ListKeyAccessServers(context.Context, *connect.Request[kasregistry.ListKeyAccessServersRequest]) (*connect.Response[kasregistry.ListKeyAccessServersResponse], error) + GetKeyAccessServer(context.Context, *connect.Request[kasregistry.GetKeyAccessServerRequest]) (*connect.Response[kasregistry.GetKeyAccessServerResponse], error) + CreateKeyAccessServer(context.Context, *connect.Request[kasregistry.CreateKeyAccessServerRequest]) (*connect.Response[kasregistry.CreateKeyAccessServerResponse], error) + UpdateKeyAccessServer(context.Context, *connect.Request[kasregistry.UpdateKeyAccessServerRequest]) (*connect.Response[kasregistry.UpdateKeyAccessServerResponse], error) + DeleteKeyAccessServer(context.Context, *connect.Request[kasregistry.DeleteKeyAccessServerRequest]) (*connect.Response[kasregistry.DeleteKeyAccessServerResponse], error) + ListKeyAccessServerGrants(context.Context, *connect.Request[kasregistry.ListKeyAccessServerGrantsRequest]) (*connect.Response[kasregistry.ListKeyAccessServerGrantsResponse], error) +} + +// NewKeyAccessServerRegistryServiceClient constructs a client for the +// policy.kasregistry.KeyAccessServerRegistryService service. By default, it uses the Connect +// protocol with the binary Protobuf Codec, asks for gzipped responses, and sends uncompressed +// requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewKeyAccessServerRegistryServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) KeyAccessServerRegistryServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &keyAccessServerRegistryServiceClient{ + listKeyAccessServers: connect.NewClient[kasregistry.ListKeyAccessServersRequest, kasregistry.ListKeyAccessServersResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceListKeyAccessServersProcedure, + connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServersMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getKeyAccessServer: connect.NewClient[kasregistry.GetKeyAccessServerRequest, kasregistry.GetKeyAccessServerResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceGetKeyAccessServerProcedure, + connect.WithSchema(keyAccessServerRegistryServiceGetKeyAccessServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createKeyAccessServer: connect.NewClient[kasregistry.CreateKeyAccessServerRequest, kasregistry.CreateKeyAccessServerResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceCreateKeyAccessServerProcedure, + connect.WithSchema(keyAccessServerRegistryServiceCreateKeyAccessServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateKeyAccessServer: connect.NewClient[kasregistry.UpdateKeyAccessServerRequest, kasregistry.UpdateKeyAccessServerResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceUpdateKeyAccessServerProcedure, + connect.WithSchema(keyAccessServerRegistryServiceUpdateKeyAccessServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deleteKeyAccessServer: connect.NewClient[kasregistry.DeleteKeyAccessServerRequest, kasregistry.DeleteKeyAccessServerResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceDeleteKeyAccessServerProcedure, + connect.WithSchema(keyAccessServerRegistryServiceDeleteKeyAccessServerMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listKeyAccessServerGrants: connect.NewClient[kasregistry.ListKeyAccessServerGrantsRequest, kasregistry.ListKeyAccessServerGrantsResponse]( + httpClient, + baseURL+KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure, + connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServerGrantsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// keyAccessServerRegistryServiceClient implements KeyAccessServerRegistryServiceClient. +type keyAccessServerRegistryServiceClient struct { + listKeyAccessServers *connect.Client[kasregistry.ListKeyAccessServersRequest, kasregistry.ListKeyAccessServersResponse] + getKeyAccessServer *connect.Client[kasregistry.GetKeyAccessServerRequest, kasregistry.GetKeyAccessServerResponse] + createKeyAccessServer *connect.Client[kasregistry.CreateKeyAccessServerRequest, kasregistry.CreateKeyAccessServerResponse] + updateKeyAccessServer *connect.Client[kasregistry.UpdateKeyAccessServerRequest, kasregistry.UpdateKeyAccessServerResponse] + deleteKeyAccessServer *connect.Client[kasregistry.DeleteKeyAccessServerRequest, kasregistry.DeleteKeyAccessServerResponse] + listKeyAccessServerGrants *connect.Client[kasregistry.ListKeyAccessServerGrantsRequest, kasregistry.ListKeyAccessServerGrantsResponse] +} + +// ListKeyAccessServers calls +// policy.kasregistry.KeyAccessServerRegistryService.ListKeyAccessServers. +func (c *keyAccessServerRegistryServiceClient) ListKeyAccessServers(ctx context.Context, req *connect.Request[kasregistry.ListKeyAccessServersRequest]) (*connect.Response[kasregistry.ListKeyAccessServersResponse], error) { + return c.listKeyAccessServers.CallUnary(ctx, req) +} + +// GetKeyAccessServer calls policy.kasregistry.KeyAccessServerRegistryService.GetKeyAccessServer. +func (c *keyAccessServerRegistryServiceClient) GetKeyAccessServer(ctx context.Context, req *connect.Request[kasregistry.GetKeyAccessServerRequest]) (*connect.Response[kasregistry.GetKeyAccessServerResponse], error) { + return c.getKeyAccessServer.CallUnary(ctx, req) +} + +// CreateKeyAccessServer calls +// policy.kasregistry.KeyAccessServerRegistryService.CreateKeyAccessServer. +func (c *keyAccessServerRegistryServiceClient) CreateKeyAccessServer(ctx context.Context, req *connect.Request[kasregistry.CreateKeyAccessServerRequest]) (*connect.Response[kasregistry.CreateKeyAccessServerResponse], error) { + return c.createKeyAccessServer.CallUnary(ctx, req) +} + +// UpdateKeyAccessServer calls +// policy.kasregistry.KeyAccessServerRegistryService.UpdateKeyAccessServer. +func (c *keyAccessServerRegistryServiceClient) UpdateKeyAccessServer(ctx context.Context, req *connect.Request[kasregistry.UpdateKeyAccessServerRequest]) (*connect.Response[kasregistry.UpdateKeyAccessServerResponse], error) { + return c.updateKeyAccessServer.CallUnary(ctx, req) +} + +// DeleteKeyAccessServer calls +// policy.kasregistry.KeyAccessServerRegistryService.DeleteKeyAccessServer. +func (c *keyAccessServerRegistryServiceClient) DeleteKeyAccessServer(ctx context.Context, req *connect.Request[kasregistry.DeleteKeyAccessServerRequest]) (*connect.Response[kasregistry.DeleteKeyAccessServerResponse], error) { + return c.deleteKeyAccessServer.CallUnary(ctx, req) +} + +// ListKeyAccessServerGrants calls +// policy.kasregistry.KeyAccessServerRegistryService.ListKeyAccessServerGrants. +func (c *keyAccessServerRegistryServiceClient) ListKeyAccessServerGrants(ctx context.Context, req *connect.Request[kasregistry.ListKeyAccessServerGrantsRequest]) (*connect.Response[kasregistry.ListKeyAccessServerGrantsResponse], error) { + return c.listKeyAccessServerGrants.CallUnary(ctx, req) +} + +// KeyAccessServerRegistryServiceHandler is an implementation of the +// policy.kasregistry.KeyAccessServerRegistryService service. +type KeyAccessServerRegistryServiceHandler interface { + ListKeyAccessServers(context.Context, *connect.Request[kasregistry.ListKeyAccessServersRequest]) (*connect.Response[kasregistry.ListKeyAccessServersResponse], error) + GetKeyAccessServer(context.Context, *connect.Request[kasregistry.GetKeyAccessServerRequest]) (*connect.Response[kasregistry.GetKeyAccessServerResponse], error) + CreateKeyAccessServer(context.Context, *connect.Request[kasregistry.CreateKeyAccessServerRequest]) (*connect.Response[kasregistry.CreateKeyAccessServerResponse], error) + UpdateKeyAccessServer(context.Context, *connect.Request[kasregistry.UpdateKeyAccessServerRequest]) (*connect.Response[kasregistry.UpdateKeyAccessServerResponse], error) + DeleteKeyAccessServer(context.Context, *connect.Request[kasregistry.DeleteKeyAccessServerRequest]) (*connect.Response[kasregistry.DeleteKeyAccessServerResponse], error) + ListKeyAccessServerGrants(context.Context, *connect.Request[kasregistry.ListKeyAccessServerGrantsRequest]) (*connect.Response[kasregistry.ListKeyAccessServerGrantsResponse], error) +} + +// NewKeyAccessServerRegistryServiceHandler builds an HTTP handler from the service implementation. +// It returns the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewKeyAccessServerRegistryServiceHandler(svc KeyAccessServerRegistryServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + keyAccessServerRegistryServiceListKeyAccessServersHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceListKeyAccessServersProcedure, + svc.ListKeyAccessServers, + connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServersMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + keyAccessServerRegistryServiceGetKeyAccessServerHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceGetKeyAccessServerProcedure, + svc.GetKeyAccessServer, + connect.WithSchema(keyAccessServerRegistryServiceGetKeyAccessServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + keyAccessServerRegistryServiceCreateKeyAccessServerHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceCreateKeyAccessServerProcedure, + svc.CreateKeyAccessServer, + connect.WithSchema(keyAccessServerRegistryServiceCreateKeyAccessServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + keyAccessServerRegistryServiceUpdateKeyAccessServerHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceUpdateKeyAccessServerProcedure, + svc.UpdateKeyAccessServer, + connect.WithSchema(keyAccessServerRegistryServiceUpdateKeyAccessServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + keyAccessServerRegistryServiceDeleteKeyAccessServerHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceDeleteKeyAccessServerProcedure, + svc.DeleteKeyAccessServer, + connect.WithSchema(keyAccessServerRegistryServiceDeleteKeyAccessServerMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + keyAccessServerRegistryServiceListKeyAccessServerGrantsHandler := connect.NewUnaryHandler( + KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure, + svc.ListKeyAccessServerGrants, + connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServerGrantsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.kasregistry.KeyAccessServerRegistryService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case KeyAccessServerRegistryServiceListKeyAccessServersProcedure: + keyAccessServerRegistryServiceListKeyAccessServersHandler.ServeHTTP(w, r) + case KeyAccessServerRegistryServiceGetKeyAccessServerProcedure: + keyAccessServerRegistryServiceGetKeyAccessServerHandler.ServeHTTP(w, r) + case KeyAccessServerRegistryServiceCreateKeyAccessServerProcedure: + keyAccessServerRegistryServiceCreateKeyAccessServerHandler.ServeHTTP(w, r) + case KeyAccessServerRegistryServiceUpdateKeyAccessServerProcedure: + keyAccessServerRegistryServiceUpdateKeyAccessServerHandler.ServeHTTP(w, r) + case KeyAccessServerRegistryServiceDeleteKeyAccessServerProcedure: + keyAccessServerRegistryServiceDeleteKeyAccessServerHandler.ServeHTTP(w, r) + case KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure: + keyAccessServerRegistryServiceListKeyAccessServerGrantsHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedKeyAccessServerRegistryServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedKeyAccessServerRegistryServiceHandler struct{} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) ListKeyAccessServers(context.Context, *connect.Request[kasregistry.ListKeyAccessServersRequest]) (*connect.Response[kasregistry.ListKeyAccessServersResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.ListKeyAccessServers is not implemented")) +} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) GetKeyAccessServer(context.Context, *connect.Request[kasregistry.GetKeyAccessServerRequest]) (*connect.Response[kasregistry.GetKeyAccessServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.GetKeyAccessServer is not implemented")) +} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) CreateKeyAccessServer(context.Context, *connect.Request[kasregistry.CreateKeyAccessServerRequest]) (*connect.Response[kasregistry.CreateKeyAccessServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.CreateKeyAccessServer is not implemented")) +} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) UpdateKeyAccessServer(context.Context, *connect.Request[kasregistry.UpdateKeyAccessServerRequest]) (*connect.Response[kasregistry.UpdateKeyAccessServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.UpdateKeyAccessServer is not implemented")) +} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) DeleteKeyAccessServer(context.Context, *connect.Request[kasregistry.DeleteKeyAccessServerRequest]) (*connect.Response[kasregistry.DeleteKeyAccessServerResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.DeleteKeyAccessServer is not implemented")) +} + +func (UnimplementedKeyAccessServerRegistryServiceHandler) ListKeyAccessServerGrants(context.Context, *connect.Request[kasregistry.ListKeyAccessServerGrantsRequest]) (*connect.Response[kasregistry.ListKeyAccessServerGrantsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.kasregistry.KeyAccessServerRegistryService.ListKeyAccessServerGrants is not implemented")) +} diff --git a/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go b/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go new file mode 100644 index 0000000000..8df0903b60 --- /dev/null +++ b/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go @@ -0,0 +1,301 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/namespaces/namespaces.proto + +package namespacesconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + namespaces "github.com/opentdf/platform/protocol/go/policy/namespaces" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // NamespaceServiceName is the fully-qualified name of the NamespaceService service. + NamespaceServiceName = "policy.namespaces.NamespaceService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // NamespaceServiceGetNamespaceProcedure is the fully-qualified name of the NamespaceService's + // GetNamespace RPC. + NamespaceServiceGetNamespaceProcedure = "/policy.namespaces.NamespaceService/GetNamespace" + // NamespaceServiceListNamespacesProcedure is the fully-qualified name of the NamespaceService's + // ListNamespaces RPC. + NamespaceServiceListNamespacesProcedure = "/policy.namespaces.NamespaceService/ListNamespaces" + // NamespaceServiceCreateNamespaceProcedure is the fully-qualified name of the NamespaceService's + // CreateNamespace RPC. + NamespaceServiceCreateNamespaceProcedure = "/policy.namespaces.NamespaceService/CreateNamespace" + // NamespaceServiceUpdateNamespaceProcedure is the fully-qualified name of the NamespaceService's + // UpdateNamespace RPC. + NamespaceServiceUpdateNamespaceProcedure = "/policy.namespaces.NamespaceService/UpdateNamespace" + // NamespaceServiceDeactivateNamespaceProcedure is the fully-qualified name of the + // NamespaceService's DeactivateNamespace RPC. + NamespaceServiceDeactivateNamespaceProcedure = "/policy.namespaces.NamespaceService/DeactivateNamespace" + // NamespaceServiceAssignKeyAccessServerToNamespaceProcedure is the fully-qualified name of the + // NamespaceService's AssignKeyAccessServerToNamespace RPC. + NamespaceServiceAssignKeyAccessServerToNamespaceProcedure = "/policy.namespaces.NamespaceService/AssignKeyAccessServerToNamespace" + // NamespaceServiceRemoveKeyAccessServerFromNamespaceProcedure is the fully-qualified name of the + // NamespaceService's RemoveKeyAccessServerFromNamespace RPC. + NamespaceServiceRemoveKeyAccessServerFromNamespaceProcedure = "/policy.namespaces.NamespaceService/RemoveKeyAccessServerFromNamespace" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + namespaceServiceServiceDescriptor = namespaces.File_policy_namespaces_namespaces_proto.Services().ByName("NamespaceService") + namespaceServiceGetNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("GetNamespace") + namespaceServiceListNamespacesMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("ListNamespaces") + namespaceServiceCreateNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("CreateNamespace") + namespaceServiceUpdateNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("UpdateNamespace") + namespaceServiceDeactivateNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("DeactivateNamespace") + namespaceServiceAssignKeyAccessServerToNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("AssignKeyAccessServerToNamespace") + namespaceServiceRemoveKeyAccessServerFromNamespaceMethodDescriptor = namespaceServiceServiceDescriptor.Methods().ByName("RemoveKeyAccessServerFromNamespace") +) + +// NamespaceServiceClient is a client for the policy.namespaces.NamespaceService service. +type NamespaceServiceClient interface { + GetNamespace(context.Context, *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) + ListNamespaces(context.Context, *connect.Request[namespaces.ListNamespacesRequest]) (*connect.Response[namespaces.ListNamespacesResponse], error) + CreateNamespace(context.Context, *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) + UpdateNamespace(context.Context, *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) + DeactivateNamespace(context.Context, *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) + // --------------------------------------* + // Namespace <> Key Access Server RPCs + // --------------------------------------- + AssignKeyAccessServerToNamespace(context.Context, *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) + RemoveKeyAccessServerFromNamespace(context.Context, *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) +} + +// NewNamespaceServiceClient constructs a client for the policy.namespaces.NamespaceService service. +// By default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped +// responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewNamespaceServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) NamespaceServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &namespaceServiceClient{ + getNamespace: connect.NewClient[namespaces.GetNamespaceRequest, namespaces.GetNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceGetNamespaceProcedure, + connect.WithSchema(namespaceServiceGetNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listNamespaces: connect.NewClient[namespaces.ListNamespacesRequest, namespaces.ListNamespacesResponse]( + httpClient, + baseURL+NamespaceServiceListNamespacesProcedure, + connect.WithSchema(namespaceServiceListNamespacesMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createNamespace: connect.NewClient[namespaces.CreateNamespaceRequest, namespaces.CreateNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceCreateNamespaceProcedure, + connect.WithSchema(namespaceServiceCreateNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateNamespace: connect.NewClient[namespaces.UpdateNamespaceRequest, namespaces.UpdateNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceUpdateNamespaceProcedure, + connect.WithSchema(namespaceServiceUpdateNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deactivateNamespace: connect.NewClient[namespaces.DeactivateNamespaceRequest, namespaces.DeactivateNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceDeactivateNamespaceProcedure, + connect.WithSchema(namespaceServiceDeactivateNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + assignKeyAccessServerToNamespace: connect.NewClient[namespaces.AssignKeyAccessServerToNamespaceRequest, namespaces.AssignKeyAccessServerToNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceAssignKeyAccessServerToNamespaceProcedure, + connect.WithSchema(namespaceServiceAssignKeyAccessServerToNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + removeKeyAccessServerFromNamespace: connect.NewClient[namespaces.RemoveKeyAccessServerFromNamespaceRequest, namespaces.RemoveKeyAccessServerFromNamespaceResponse]( + httpClient, + baseURL+NamespaceServiceRemoveKeyAccessServerFromNamespaceProcedure, + connect.WithSchema(namespaceServiceRemoveKeyAccessServerFromNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// namespaceServiceClient implements NamespaceServiceClient. +type namespaceServiceClient struct { + getNamespace *connect.Client[namespaces.GetNamespaceRequest, namespaces.GetNamespaceResponse] + listNamespaces *connect.Client[namespaces.ListNamespacesRequest, namespaces.ListNamespacesResponse] + createNamespace *connect.Client[namespaces.CreateNamespaceRequest, namespaces.CreateNamespaceResponse] + updateNamespace *connect.Client[namespaces.UpdateNamespaceRequest, namespaces.UpdateNamespaceResponse] + deactivateNamespace *connect.Client[namespaces.DeactivateNamespaceRequest, namespaces.DeactivateNamespaceResponse] + assignKeyAccessServerToNamespace *connect.Client[namespaces.AssignKeyAccessServerToNamespaceRequest, namespaces.AssignKeyAccessServerToNamespaceResponse] + removeKeyAccessServerFromNamespace *connect.Client[namespaces.RemoveKeyAccessServerFromNamespaceRequest, namespaces.RemoveKeyAccessServerFromNamespaceResponse] +} + +// GetNamespace calls policy.namespaces.NamespaceService.GetNamespace. +func (c *namespaceServiceClient) GetNamespace(ctx context.Context, req *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { + return c.getNamespace.CallUnary(ctx, req) +} + +// ListNamespaces calls policy.namespaces.NamespaceService.ListNamespaces. +func (c *namespaceServiceClient) ListNamespaces(ctx context.Context, req *connect.Request[namespaces.ListNamespacesRequest]) (*connect.Response[namespaces.ListNamespacesResponse], error) { + return c.listNamespaces.CallUnary(ctx, req) +} + +// CreateNamespace calls policy.namespaces.NamespaceService.CreateNamespace. +func (c *namespaceServiceClient) CreateNamespace(ctx context.Context, req *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) { + return c.createNamespace.CallUnary(ctx, req) +} + +// UpdateNamespace calls policy.namespaces.NamespaceService.UpdateNamespace. +func (c *namespaceServiceClient) UpdateNamespace(ctx context.Context, req *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) { + return c.updateNamespace.CallUnary(ctx, req) +} + +// DeactivateNamespace calls policy.namespaces.NamespaceService.DeactivateNamespace. +func (c *namespaceServiceClient) DeactivateNamespace(ctx context.Context, req *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) { + return c.deactivateNamespace.CallUnary(ctx, req) +} + +// AssignKeyAccessServerToNamespace calls +// policy.namespaces.NamespaceService.AssignKeyAccessServerToNamespace. +func (c *namespaceServiceClient) AssignKeyAccessServerToNamespace(ctx context.Context, req *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) { + return c.assignKeyAccessServerToNamespace.CallUnary(ctx, req) +} + +// RemoveKeyAccessServerFromNamespace calls +// policy.namespaces.NamespaceService.RemoveKeyAccessServerFromNamespace. +func (c *namespaceServiceClient) RemoveKeyAccessServerFromNamespace(ctx context.Context, req *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) { + return c.removeKeyAccessServerFromNamespace.CallUnary(ctx, req) +} + +// NamespaceServiceHandler is an implementation of the policy.namespaces.NamespaceService service. +type NamespaceServiceHandler interface { + GetNamespace(context.Context, *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) + ListNamespaces(context.Context, *connect.Request[namespaces.ListNamespacesRequest]) (*connect.Response[namespaces.ListNamespacesResponse], error) + CreateNamespace(context.Context, *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) + UpdateNamespace(context.Context, *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) + DeactivateNamespace(context.Context, *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) + // --------------------------------------* + // Namespace <> Key Access Server RPCs + // --------------------------------------- + AssignKeyAccessServerToNamespace(context.Context, *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) + RemoveKeyAccessServerFromNamespace(context.Context, *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) +} + +// NewNamespaceServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewNamespaceServiceHandler(svc NamespaceServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + namespaceServiceGetNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceGetNamespaceProcedure, + svc.GetNamespace, + connect.WithSchema(namespaceServiceGetNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceListNamespacesHandler := connect.NewUnaryHandler( + NamespaceServiceListNamespacesProcedure, + svc.ListNamespaces, + connect.WithSchema(namespaceServiceListNamespacesMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceCreateNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceCreateNamespaceProcedure, + svc.CreateNamespace, + connect.WithSchema(namespaceServiceCreateNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceUpdateNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceUpdateNamespaceProcedure, + svc.UpdateNamespace, + connect.WithSchema(namespaceServiceUpdateNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceDeactivateNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceDeactivateNamespaceProcedure, + svc.DeactivateNamespace, + connect.WithSchema(namespaceServiceDeactivateNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceAssignKeyAccessServerToNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceAssignKeyAccessServerToNamespaceProcedure, + svc.AssignKeyAccessServerToNamespace, + connect.WithSchema(namespaceServiceAssignKeyAccessServerToNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + namespaceServiceRemoveKeyAccessServerFromNamespaceHandler := connect.NewUnaryHandler( + NamespaceServiceRemoveKeyAccessServerFromNamespaceProcedure, + svc.RemoveKeyAccessServerFromNamespace, + connect.WithSchema(namespaceServiceRemoveKeyAccessServerFromNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.namespaces.NamespaceService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case NamespaceServiceGetNamespaceProcedure: + namespaceServiceGetNamespaceHandler.ServeHTTP(w, r) + case NamespaceServiceListNamespacesProcedure: + namespaceServiceListNamespacesHandler.ServeHTTP(w, r) + case NamespaceServiceCreateNamespaceProcedure: + namespaceServiceCreateNamespaceHandler.ServeHTTP(w, r) + case NamespaceServiceUpdateNamespaceProcedure: + namespaceServiceUpdateNamespaceHandler.ServeHTTP(w, r) + case NamespaceServiceDeactivateNamespaceProcedure: + namespaceServiceDeactivateNamespaceHandler.ServeHTTP(w, r) + case NamespaceServiceAssignKeyAccessServerToNamespaceProcedure: + namespaceServiceAssignKeyAccessServerToNamespaceHandler.ServeHTTP(w, r) + case NamespaceServiceRemoveKeyAccessServerFromNamespaceProcedure: + namespaceServiceRemoveKeyAccessServerFromNamespaceHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedNamespaceServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedNamespaceServiceHandler struct{} + +func (UnimplementedNamespaceServiceHandler) GetNamespace(context.Context, *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.GetNamespace is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) ListNamespaces(context.Context, *connect.Request[namespaces.ListNamespacesRequest]) (*connect.Response[namespaces.ListNamespacesResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.ListNamespaces is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) CreateNamespace(context.Context, *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.CreateNamespace is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) UpdateNamespace(context.Context, *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.UpdateNamespace is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) DeactivateNamespace(context.Context, *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.DeactivateNamespace is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) AssignKeyAccessServerToNamespace(context.Context, *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.AssignKeyAccessServerToNamespace is not implemented")) +} + +func (UnimplementedNamespaceServiceHandler) RemoveKeyAccessServerFromNamespace(context.Context, *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.namespaces.NamespaceService.RemoveKeyAccessServerFromNamespace is not implemented")) +} diff --git a/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go b/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go new file mode 100644 index 0000000000..415ba7fa15 --- /dev/null +++ b/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go @@ -0,0 +1,422 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/resourcemapping/resource_mapping.proto + +package resourcemappingconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + resourcemapping "github.com/opentdf/platform/protocol/go/policy/resourcemapping" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // ResourceMappingServiceName is the fully-qualified name of the ResourceMappingService service. + ResourceMappingServiceName = "policy.resourcemapping.ResourceMappingService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // ResourceMappingServiceListResourceMappingGroupsProcedure is the fully-qualified name of the + // ResourceMappingService's ListResourceMappingGroups RPC. + ResourceMappingServiceListResourceMappingGroupsProcedure = "/policy.resourcemapping.ResourceMappingService/ListResourceMappingGroups" + // ResourceMappingServiceGetResourceMappingGroupProcedure is the fully-qualified name of the + // ResourceMappingService's GetResourceMappingGroup RPC. + ResourceMappingServiceGetResourceMappingGroupProcedure = "/policy.resourcemapping.ResourceMappingService/GetResourceMappingGroup" + // ResourceMappingServiceCreateResourceMappingGroupProcedure is the fully-qualified name of the + // ResourceMappingService's CreateResourceMappingGroup RPC. + ResourceMappingServiceCreateResourceMappingGroupProcedure = "/policy.resourcemapping.ResourceMappingService/CreateResourceMappingGroup" + // ResourceMappingServiceUpdateResourceMappingGroupProcedure is the fully-qualified name of the + // ResourceMappingService's UpdateResourceMappingGroup RPC. + ResourceMappingServiceUpdateResourceMappingGroupProcedure = "/policy.resourcemapping.ResourceMappingService/UpdateResourceMappingGroup" + // ResourceMappingServiceDeleteResourceMappingGroupProcedure is the fully-qualified name of the + // ResourceMappingService's DeleteResourceMappingGroup RPC. + ResourceMappingServiceDeleteResourceMappingGroupProcedure = "/policy.resourcemapping.ResourceMappingService/DeleteResourceMappingGroup" + // ResourceMappingServiceListResourceMappingsProcedure is the fully-qualified name of the + // ResourceMappingService's ListResourceMappings RPC. + ResourceMappingServiceListResourceMappingsProcedure = "/policy.resourcemapping.ResourceMappingService/ListResourceMappings" + // ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure is the fully-qualified name of the + // ResourceMappingService's ListResourceMappingsByGroupFqns RPC. + ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure = "/policy.resourcemapping.ResourceMappingService/ListResourceMappingsByGroupFqns" + // ResourceMappingServiceGetResourceMappingProcedure is the fully-qualified name of the + // ResourceMappingService's GetResourceMapping RPC. + ResourceMappingServiceGetResourceMappingProcedure = "/policy.resourcemapping.ResourceMappingService/GetResourceMapping" + // ResourceMappingServiceCreateResourceMappingProcedure is the fully-qualified name of the + // ResourceMappingService's CreateResourceMapping RPC. + ResourceMappingServiceCreateResourceMappingProcedure = "/policy.resourcemapping.ResourceMappingService/CreateResourceMapping" + // ResourceMappingServiceUpdateResourceMappingProcedure is the fully-qualified name of the + // ResourceMappingService's UpdateResourceMapping RPC. + ResourceMappingServiceUpdateResourceMappingProcedure = "/policy.resourcemapping.ResourceMappingService/UpdateResourceMapping" + // ResourceMappingServiceDeleteResourceMappingProcedure is the fully-qualified name of the + // ResourceMappingService's DeleteResourceMapping RPC. + ResourceMappingServiceDeleteResourceMappingProcedure = "/policy.resourcemapping.ResourceMappingService/DeleteResourceMapping" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + resourceMappingServiceServiceDescriptor = resourcemapping.File_policy_resourcemapping_resource_mapping_proto.Services().ByName("ResourceMappingService") + resourceMappingServiceListResourceMappingGroupsMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("ListResourceMappingGroups") + resourceMappingServiceGetResourceMappingGroupMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("GetResourceMappingGroup") + resourceMappingServiceCreateResourceMappingGroupMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("CreateResourceMappingGroup") + resourceMappingServiceUpdateResourceMappingGroupMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("UpdateResourceMappingGroup") + resourceMappingServiceDeleteResourceMappingGroupMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("DeleteResourceMappingGroup") + resourceMappingServiceListResourceMappingsMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("ListResourceMappings") + resourceMappingServiceListResourceMappingsByGroupFqnsMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("ListResourceMappingsByGroupFqns") + resourceMappingServiceGetResourceMappingMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("GetResourceMapping") + resourceMappingServiceCreateResourceMappingMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("CreateResourceMapping") + resourceMappingServiceUpdateResourceMappingMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("UpdateResourceMapping") + resourceMappingServiceDeleteResourceMappingMethodDescriptor = resourceMappingServiceServiceDescriptor.Methods().ByName("DeleteResourceMapping") +) + +// ResourceMappingServiceClient is a client for the policy.resourcemapping.ResourceMappingService +// service. +type ResourceMappingServiceClient interface { + ListResourceMappingGroups(context.Context, *connect.Request[resourcemapping.ListResourceMappingGroupsRequest]) (*connect.Response[resourcemapping.ListResourceMappingGroupsResponse], error) + GetResourceMappingGroup(context.Context, *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) + CreateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) + UpdateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) + DeleteResourceMappingGroup(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) + ListResourceMappings(context.Context, *connect.Request[resourcemapping.ListResourceMappingsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsResponse], error) + ListResourceMappingsByGroupFqns(context.Context, *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) + GetResourceMapping(context.Context, *connect.Request[resourcemapping.GetResourceMappingRequest]) (*connect.Response[resourcemapping.GetResourceMappingResponse], error) + CreateResourceMapping(context.Context, *connect.Request[resourcemapping.CreateResourceMappingRequest]) (*connect.Response[resourcemapping.CreateResourceMappingResponse], error) + UpdateResourceMapping(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingResponse], error) + DeleteResourceMapping(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingResponse], error) +} + +// NewResourceMappingServiceClient constructs a client for the +// policy.resourcemapping.ResourceMappingService service. By default, it uses the Connect protocol +// with the binary Protobuf Codec, asks for gzipped responses, and sends uncompressed requests. To +// use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or connect.WithGRPCWeb() +// options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewResourceMappingServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ResourceMappingServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &resourceMappingServiceClient{ + listResourceMappingGroups: connect.NewClient[resourcemapping.ListResourceMappingGroupsRequest, resourcemapping.ListResourceMappingGroupsResponse]( + httpClient, + baseURL+ResourceMappingServiceListResourceMappingGroupsProcedure, + connect.WithSchema(resourceMappingServiceListResourceMappingGroupsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getResourceMappingGroup: connect.NewClient[resourcemapping.GetResourceMappingGroupRequest, resourcemapping.GetResourceMappingGroupResponse]( + httpClient, + baseURL+ResourceMappingServiceGetResourceMappingGroupProcedure, + connect.WithSchema(resourceMappingServiceGetResourceMappingGroupMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createResourceMappingGroup: connect.NewClient[resourcemapping.CreateResourceMappingGroupRequest, resourcemapping.CreateResourceMappingGroupResponse]( + httpClient, + baseURL+ResourceMappingServiceCreateResourceMappingGroupProcedure, + connect.WithSchema(resourceMappingServiceCreateResourceMappingGroupMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateResourceMappingGroup: connect.NewClient[resourcemapping.UpdateResourceMappingGroupRequest, resourcemapping.UpdateResourceMappingGroupResponse]( + httpClient, + baseURL+ResourceMappingServiceUpdateResourceMappingGroupProcedure, + connect.WithSchema(resourceMappingServiceUpdateResourceMappingGroupMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deleteResourceMappingGroup: connect.NewClient[resourcemapping.DeleteResourceMappingGroupRequest, resourcemapping.DeleteResourceMappingGroupResponse]( + httpClient, + baseURL+ResourceMappingServiceDeleteResourceMappingGroupProcedure, + connect.WithSchema(resourceMappingServiceDeleteResourceMappingGroupMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listResourceMappings: connect.NewClient[resourcemapping.ListResourceMappingsRequest, resourcemapping.ListResourceMappingsResponse]( + httpClient, + baseURL+ResourceMappingServiceListResourceMappingsProcedure, + connect.WithSchema(resourceMappingServiceListResourceMappingsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listResourceMappingsByGroupFqns: connect.NewClient[resourcemapping.ListResourceMappingsByGroupFqnsRequest, resourcemapping.ListResourceMappingsByGroupFqnsResponse]( + httpClient, + baseURL+ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure, + connect.WithSchema(resourceMappingServiceListResourceMappingsByGroupFqnsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getResourceMapping: connect.NewClient[resourcemapping.GetResourceMappingRequest, resourcemapping.GetResourceMappingResponse]( + httpClient, + baseURL+ResourceMappingServiceGetResourceMappingProcedure, + connect.WithSchema(resourceMappingServiceGetResourceMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createResourceMapping: connect.NewClient[resourcemapping.CreateResourceMappingRequest, resourcemapping.CreateResourceMappingResponse]( + httpClient, + baseURL+ResourceMappingServiceCreateResourceMappingProcedure, + connect.WithSchema(resourceMappingServiceCreateResourceMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateResourceMapping: connect.NewClient[resourcemapping.UpdateResourceMappingRequest, resourcemapping.UpdateResourceMappingResponse]( + httpClient, + baseURL+ResourceMappingServiceUpdateResourceMappingProcedure, + connect.WithSchema(resourceMappingServiceUpdateResourceMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deleteResourceMapping: connect.NewClient[resourcemapping.DeleteResourceMappingRequest, resourcemapping.DeleteResourceMappingResponse]( + httpClient, + baseURL+ResourceMappingServiceDeleteResourceMappingProcedure, + connect.WithSchema(resourceMappingServiceDeleteResourceMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// resourceMappingServiceClient implements ResourceMappingServiceClient. +type resourceMappingServiceClient struct { + listResourceMappingGroups *connect.Client[resourcemapping.ListResourceMappingGroupsRequest, resourcemapping.ListResourceMappingGroupsResponse] + getResourceMappingGroup *connect.Client[resourcemapping.GetResourceMappingGroupRequest, resourcemapping.GetResourceMappingGroupResponse] + createResourceMappingGroup *connect.Client[resourcemapping.CreateResourceMappingGroupRequest, resourcemapping.CreateResourceMappingGroupResponse] + updateResourceMappingGroup *connect.Client[resourcemapping.UpdateResourceMappingGroupRequest, resourcemapping.UpdateResourceMappingGroupResponse] + deleteResourceMappingGroup *connect.Client[resourcemapping.DeleteResourceMappingGroupRequest, resourcemapping.DeleteResourceMappingGroupResponse] + listResourceMappings *connect.Client[resourcemapping.ListResourceMappingsRequest, resourcemapping.ListResourceMappingsResponse] + listResourceMappingsByGroupFqns *connect.Client[resourcemapping.ListResourceMappingsByGroupFqnsRequest, resourcemapping.ListResourceMappingsByGroupFqnsResponse] + getResourceMapping *connect.Client[resourcemapping.GetResourceMappingRequest, resourcemapping.GetResourceMappingResponse] + createResourceMapping *connect.Client[resourcemapping.CreateResourceMappingRequest, resourcemapping.CreateResourceMappingResponse] + updateResourceMapping *connect.Client[resourcemapping.UpdateResourceMappingRequest, resourcemapping.UpdateResourceMappingResponse] + deleteResourceMapping *connect.Client[resourcemapping.DeleteResourceMappingRequest, resourcemapping.DeleteResourceMappingResponse] +} + +// ListResourceMappingGroups calls +// policy.resourcemapping.ResourceMappingService.ListResourceMappingGroups. +func (c *resourceMappingServiceClient) ListResourceMappingGroups(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingGroupsRequest]) (*connect.Response[resourcemapping.ListResourceMappingGroupsResponse], error) { + return c.listResourceMappingGroups.CallUnary(ctx, req) +} + +// GetResourceMappingGroup calls +// policy.resourcemapping.ResourceMappingService.GetResourceMappingGroup. +func (c *resourceMappingServiceClient) GetResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) { + return c.getResourceMappingGroup.CallUnary(ctx, req) +} + +// CreateResourceMappingGroup calls +// policy.resourcemapping.ResourceMappingService.CreateResourceMappingGroup. +func (c *resourceMappingServiceClient) CreateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) { + return c.createResourceMappingGroup.CallUnary(ctx, req) +} + +// UpdateResourceMappingGroup calls +// policy.resourcemapping.ResourceMappingService.UpdateResourceMappingGroup. +func (c *resourceMappingServiceClient) UpdateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) { + return c.updateResourceMappingGroup.CallUnary(ctx, req) +} + +// DeleteResourceMappingGroup calls +// policy.resourcemapping.ResourceMappingService.DeleteResourceMappingGroup. +func (c *resourceMappingServiceClient) DeleteResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) { + return c.deleteResourceMappingGroup.CallUnary(ctx, req) +} + +// ListResourceMappings calls policy.resourcemapping.ResourceMappingService.ListResourceMappings. +func (c *resourceMappingServiceClient) ListResourceMappings(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsResponse], error) { + return c.listResourceMappings.CallUnary(ctx, req) +} + +// ListResourceMappingsByGroupFqns calls +// policy.resourcemapping.ResourceMappingService.ListResourceMappingsByGroupFqns. +func (c *resourceMappingServiceClient) ListResourceMappingsByGroupFqns(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) { + return c.listResourceMappingsByGroupFqns.CallUnary(ctx, req) +} + +// GetResourceMapping calls policy.resourcemapping.ResourceMappingService.GetResourceMapping. +func (c *resourceMappingServiceClient) GetResourceMapping(ctx context.Context, req *connect.Request[resourcemapping.GetResourceMappingRequest]) (*connect.Response[resourcemapping.GetResourceMappingResponse], error) { + return c.getResourceMapping.CallUnary(ctx, req) +} + +// CreateResourceMapping calls policy.resourcemapping.ResourceMappingService.CreateResourceMapping. +func (c *resourceMappingServiceClient) CreateResourceMapping(ctx context.Context, req *connect.Request[resourcemapping.CreateResourceMappingRequest]) (*connect.Response[resourcemapping.CreateResourceMappingResponse], error) { + return c.createResourceMapping.CallUnary(ctx, req) +} + +// UpdateResourceMapping calls policy.resourcemapping.ResourceMappingService.UpdateResourceMapping. +func (c *resourceMappingServiceClient) UpdateResourceMapping(ctx context.Context, req *connect.Request[resourcemapping.UpdateResourceMappingRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingResponse], error) { + return c.updateResourceMapping.CallUnary(ctx, req) +} + +// DeleteResourceMapping calls policy.resourcemapping.ResourceMappingService.DeleteResourceMapping. +func (c *resourceMappingServiceClient) DeleteResourceMapping(ctx context.Context, req *connect.Request[resourcemapping.DeleteResourceMappingRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingResponse], error) { + return c.deleteResourceMapping.CallUnary(ctx, req) +} + +// ResourceMappingServiceHandler is an implementation of the +// policy.resourcemapping.ResourceMappingService service. +type ResourceMappingServiceHandler interface { + ListResourceMappingGroups(context.Context, *connect.Request[resourcemapping.ListResourceMappingGroupsRequest]) (*connect.Response[resourcemapping.ListResourceMappingGroupsResponse], error) + GetResourceMappingGroup(context.Context, *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) + CreateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) + UpdateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) + DeleteResourceMappingGroup(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) + ListResourceMappings(context.Context, *connect.Request[resourcemapping.ListResourceMappingsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsResponse], error) + ListResourceMappingsByGroupFqns(context.Context, *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) + GetResourceMapping(context.Context, *connect.Request[resourcemapping.GetResourceMappingRequest]) (*connect.Response[resourcemapping.GetResourceMappingResponse], error) + CreateResourceMapping(context.Context, *connect.Request[resourcemapping.CreateResourceMappingRequest]) (*connect.Response[resourcemapping.CreateResourceMappingResponse], error) + UpdateResourceMapping(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingResponse], error) + DeleteResourceMapping(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingResponse], error) +} + +// NewResourceMappingServiceHandler builds an HTTP handler from the service implementation. It +// returns the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewResourceMappingServiceHandler(svc ResourceMappingServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + resourceMappingServiceListResourceMappingGroupsHandler := connect.NewUnaryHandler( + ResourceMappingServiceListResourceMappingGroupsProcedure, + svc.ListResourceMappingGroups, + connect.WithSchema(resourceMappingServiceListResourceMappingGroupsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceGetResourceMappingGroupHandler := connect.NewUnaryHandler( + ResourceMappingServiceGetResourceMappingGroupProcedure, + svc.GetResourceMappingGroup, + connect.WithSchema(resourceMappingServiceGetResourceMappingGroupMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceCreateResourceMappingGroupHandler := connect.NewUnaryHandler( + ResourceMappingServiceCreateResourceMappingGroupProcedure, + svc.CreateResourceMappingGroup, + connect.WithSchema(resourceMappingServiceCreateResourceMappingGroupMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceUpdateResourceMappingGroupHandler := connect.NewUnaryHandler( + ResourceMappingServiceUpdateResourceMappingGroupProcedure, + svc.UpdateResourceMappingGroup, + connect.WithSchema(resourceMappingServiceUpdateResourceMappingGroupMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceDeleteResourceMappingGroupHandler := connect.NewUnaryHandler( + ResourceMappingServiceDeleteResourceMappingGroupProcedure, + svc.DeleteResourceMappingGroup, + connect.WithSchema(resourceMappingServiceDeleteResourceMappingGroupMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceListResourceMappingsHandler := connect.NewUnaryHandler( + ResourceMappingServiceListResourceMappingsProcedure, + svc.ListResourceMappings, + connect.WithSchema(resourceMappingServiceListResourceMappingsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceListResourceMappingsByGroupFqnsHandler := connect.NewUnaryHandler( + ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure, + svc.ListResourceMappingsByGroupFqns, + connect.WithSchema(resourceMappingServiceListResourceMappingsByGroupFqnsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceGetResourceMappingHandler := connect.NewUnaryHandler( + ResourceMappingServiceGetResourceMappingProcedure, + svc.GetResourceMapping, + connect.WithSchema(resourceMappingServiceGetResourceMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceCreateResourceMappingHandler := connect.NewUnaryHandler( + ResourceMappingServiceCreateResourceMappingProcedure, + svc.CreateResourceMapping, + connect.WithSchema(resourceMappingServiceCreateResourceMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceUpdateResourceMappingHandler := connect.NewUnaryHandler( + ResourceMappingServiceUpdateResourceMappingProcedure, + svc.UpdateResourceMapping, + connect.WithSchema(resourceMappingServiceUpdateResourceMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + resourceMappingServiceDeleteResourceMappingHandler := connect.NewUnaryHandler( + ResourceMappingServiceDeleteResourceMappingProcedure, + svc.DeleteResourceMapping, + connect.WithSchema(resourceMappingServiceDeleteResourceMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.resourcemapping.ResourceMappingService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case ResourceMappingServiceListResourceMappingGroupsProcedure: + resourceMappingServiceListResourceMappingGroupsHandler.ServeHTTP(w, r) + case ResourceMappingServiceGetResourceMappingGroupProcedure: + resourceMappingServiceGetResourceMappingGroupHandler.ServeHTTP(w, r) + case ResourceMappingServiceCreateResourceMappingGroupProcedure: + resourceMappingServiceCreateResourceMappingGroupHandler.ServeHTTP(w, r) + case ResourceMappingServiceUpdateResourceMappingGroupProcedure: + resourceMappingServiceUpdateResourceMappingGroupHandler.ServeHTTP(w, r) + case ResourceMappingServiceDeleteResourceMappingGroupProcedure: + resourceMappingServiceDeleteResourceMappingGroupHandler.ServeHTTP(w, r) + case ResourceMappingServiceListResourceMappingsProcedure: + resourceMappingServiceListResourceMappingsHandler.ServeHTTP(w, r) + case ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure: + resourceMappingServiceListResourceMappingsByGroupFqnsHandler.ServeHTTP(w, r) + case ResourceMappingServiceGetResourceMappingProcedure: + resourceMappingServiceGetResourceMappingHandler.ServeHTTP(w, r) + case ResourceMappingServiceCreateResourceMappingProcedure: + resourceMappingServiceCreateResourceMappingHandler.ServeHTTP(w, r) + case ResourceMappingServiceUpdateResourceMappingProcedure: + resourceMappingServiceUpdateResourceMappingHandler.ServeHTTP(w, r) + case ResourceMappingServiceDeleteResourceMappingProcedure: + resourceMappingServiceDeleteResourceMappingHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedResourceMappingServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedResourceMappingServiceHandler struct{} + +func (UnimplementedResourceMappingServiceHandler) ListResourceMappingGroups(context.Context, *connect.Request[resourcemapping.ListResourceMappingGroupsRequest]) (*connect.Response[resourcemapping.ListResourceMappingGroupsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.ListResourceMappingGroups is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) GetResourceMappingGroup(context.Context, *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.GetResourceMappingGroup is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) CreateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.CreateResourceMappingGroup is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) UpdateResourceMappingGroup(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.UpdateResourceMappingGroup is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) DeleteResourceMappingGroup(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.DeleteResourceMappingGroup is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) ListResourceMappings(context.Context, *connect.Request[resourcemapping.ListResourceMappingsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.ListResourceMappings is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) ListResourceMappingsByGroupFqns(context.Context, *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.ListResourceMappingsByGroupFqns is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) GetResourceMapping(context.Context, *connect.Request[resourcemapping.GetResourceMappingRequest]) (*connect.Response[resourcemapping.GetResourceMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.GetResourceMapping is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) CreateResourceMapping(context.Context, *connect.Request[resourcemapping.CreateResourceMappingRequest]) (*connect.Response[resourcemapping.CreateResourceMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.CreateResourceMapping is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) UpdateResourceMapping(context.Context, *connect.Request[resourcemapping.UpdateResourceMappingRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.UpdateResourceMapping is not implemented")) +} + +func (UnimplementedResourceMappingServiceHandler) DeleteResourceMapping(context.Context, *connect.Request[resourcemapping.DeleteResourceMappingRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.resourcemapping.ResourceMappingService.DeleteResourceMapping is not implemented")) +} diff --git a/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go new file mode 100644 index 0000000000..6cdbf3b7d7 --- /dev/null +++ b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go @@ -0,0 +1,422 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/subjectmapping/subject_mapping.proto + +package subjectmappingconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + subjectmapping "github.com/opentdf/platform/protocol/go/policy/subjectmapping" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // SubjectMappingServiceName is the fully-qualified name of the SubjectMappingService service. + SubjectMappingServiceName = "policy.subjectmapping.SubjectMappingService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // SubjectMappingServiceMatchSubjectMappingsProcedure is the fully-qualified name of the + // SubjectMappingService's MatchSubjectMappings RPC. + SubjectMappingServiceMatchSubjectMappingsProcedure = "/policy.subjectmapping.SubjectMappingService/MatchSubjectMappings" + // SubjectMappingServiceListSubjectMappingsProcedure is the fully-qualified name of the + // SubjectMappingService's ListSubjectMappings RPC. + SubjectMappingServiceListSubjectMappingsProcedure = "/policy.subjectmapping.SubjectMappingService/ListSubjectMappings" + // SubjectMappingServiceGetSubjectMappingProcedure is the fully-qualified name of the + // SubjectMappingService's GetSubjectMapping RPC. + SubjectMappingServiceGetSubjectMappingProcedure = "/policy.subjectmapping.SubjectMappingService/GetSubjectMapping" + // SubjectMappingServiceCreateSubjectMappingProcedure is the fully-qualified name of the + // SubjectMappingService's CreateSubjectMapping RPC. + SubjectMappingServiceCreateSubjectMappingProcedure = "/policy.subjectmapping.SubjectMappingService/CreateSubjectMapping" + // SubjectMappingServiceUpdateSubjectMappingProcedure is the fully-qualified name of the + // SubjectMappingService's UpdateSubjectMapping RPC. + SubjectMappingServiceUpdateSubjectMappingProcedure = "/policy.subjectmapping.SubjectMappingService/UpdateSubjectMapping" + // SubjectMappingServiceDeleteSubjectMappingProcedure is the fully-qualified name of the + // SubjectMappingService's DeleteSubjectMapping RPC. + SubjectMappingServiceDeleteSubjectMappingProcedure = "/policy.subjectmapping.SubjectMappingService/DeleteSubjectMapping" + // SubjectMappingServiceListSubjectConditionSetsProcedure is the fully-qualified name of the + // SubjectMappingService's ListSubjectConditionSets RPC. + SubjectMappingServiceListSubjectConditionSetsProcedure = "/policy.subjectmapping.SubjectMappingService/ListSubjectConditionSets" + // SubjectMappingServiceGetSubjectConditionSetProcedure is the fully-qualified name of the + // SubjectMappingService's GetSubjectConditionSet RPC. + SubjectMappingServiceGetSubjectConditionSetProcedure = "/policy.subjectmapping.SubjectMappingService/GetSubjectConditionSet" + // SubjectMappingServiceCreateSubjectConditionSetProcedure is the fully-qualified name of the + // SubjectMappingService's CreateSubjectConditionSet RPC. + SubjectMappingServiceCreateSubjectConditionSetProcedure = "/policy.subjectmapping.SubjectMappingService/CreateSubjectConditionSet" + // SubjectMappingServiceUpdateSubjectConditionSetProcedure is the fully-qualified name of the + // SubjectMappingService's UpdateSubjectConditionSet RPC. + SubjectMappingServiceUpdateSubjectConditionSetProcedure = "/policy.subjectmapping.SubjectMappingService/UpdateSubjectConditionSet" + // SubjectMappingServiceDeleteSubjectConditionSetProcedure is the fully-qualified name of the + // SubjectMappingService's DeleteSubjectConditionSet RPC. + SubjectMappingServiceDeleteSubjectConditionSetProcedure = "/policy.subjectmapping.SubjectMappingService/DeleteSubjectConditionSet" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + subjectMappingServiceServiceDescriptor = subjectmapping.File_policy_subjectmapping_subject_mapping_proto.Services().ByName("SubjectMappingService") + subjectMappingServiceMatchSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("MatchSubjectMappings") + subjectMappingServiceListSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectMappings") + subjectMappingServiceGetSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectMapping") + subjectMappingServiceCreateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectMapping") + subjectMappingServiceUpdateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectMapping") + subjectMappingServiceDeleteSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectMapping") + subjectMappingServiceListSubjectConditionSetsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectConditionSets") + subjectMappingServiceGetSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectConditionSet") + subjectMappingServiceCreateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectConditionSet") + subjectMappingServiceUpdateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectConditionSet") + subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectConditionSet") +) + +// SubjectMappingServiceClient is a client for the policy.subjectmapping.SubjectMappingService +// service. +type SubjectMappingServiceClient interface { + // Find matching Subject Mappings for a given Subject + MatchSubjectMappings(context.Context, *connect.Request[subjectmapping.MatchSubjectMappingsRequest]) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) + ListSubjectMappings(context.Context, *connect.Request[subjectmapping.ListSubjectMappingsRequest]) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) + GetSubjectMapping(context.Context, *connect.Request[subjectmapping.GetSubjectMappingRequest]) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) + CreateSubjectMapping(context.Context, *connect.Request[subjectmapping.CreateSubjectMappingRequest]) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) + UpdateSubjectMapping(context.Context, *connect.Request[subjectmapping.UpdateSubjectMappingRequest]) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) + DeleteSubjectMapping(context.Context, *connect.Request[subjectmapping.DeleteSubjectMappingRequest]) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) + ListSubjectConditionSets(context.Context, *connect.Request[subjectmapping.ListSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) + GetSubjectConditionSet(context.Context, *connect.Request[subjectmapping.GetSubjectConditionSetRequest]) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) + CreateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) + UpdateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) + DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) +} + +// NewSubjectMappingServiceClient constructs a client for the +// policy.subjectmapping.SubjectMappingService service. By default, it uses the Connect protocol +// with the binary Protobuf Codec, asks for gzipped responses, and sends uncompressed requests. To +// use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or connect.WithGRPCWeb() +// options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewSubjectMappingServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) SubjectMappingServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &subjectMappingServiceClient{ + matchSubjectMappings: connect.NewClient[subjectmapping.MatchSubjectMappingsRequest, subjectmapping.MatchSubjectMappingsResponse]( + httpClient, + baseURL+SubjectMappingServiceMatchSubjectMappingsProcedure, + connect.WithSchema(subjectMappingServiceMatchSubjectMappingsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listSubjectMappings: connect.NewClient[subjectmapping.ListSubjectMappingsRequest, subjectmapping.ListSubjectMappingsResponse]( + httpClient, + baseURL+SubjectMappingServiceListSubjectMappingsProcedure, + connect.WithSchema(subjectMappingServiceListSubjectMappingsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getSubjectMapping: connect.NewClient[subjectmapping.GetSubjectMappingRequest, subjectmapping.GetSubjectMappingResponse]( + httpClient, + baseURL+SubjectMappingServiceGetSubjectMappingProcedure, + connect.WithSchema(subjectMappingServiceGetSubjectMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createSubjectMapping: connect.NewClient[subjectmapping.CreateSubjectMappingRequest, subjectmapping.CreateSubjectMappingResponse]( + httpClient, + baseURL+SubjectMappingServiceCreateSubjectMappingProcedure, + connect.WithSchema(subjectMappingServiceCreateSubjectMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateSubjectMapping: connect.NewClient[subjectmapping.UpdateSubjectMappingRequest, subjectmapping.UpdateSubjectMappingResponse]( + httpClient, + baseURL+SubjectMappingServiceUpdateSubjectMappingProcedure, + connect.WithSchema(subjectMappingServiceUpdateSubjectMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deleteSubjectMapping: connect.NewClient[subjectmapping.DeleteSubjectMappingRequest, subjectmapping.DeleteSubjectMappingResponse]( + httpClient, + baseURL+SubjectMappingServiceDeleteSubjectMappingProcedure, + connect.WithSchema(subjectMappingServiceDeleteSubjectMappingMethodDescriptor), + connect.WithClientOptions(opts...), + ), + listSubjectConditionSets: connect.NewClient[subjectmapping.ListSubjectConditionSetsRequest, subjectmapping.ListSubjectConditionSetsResponse]( + httpClient, + baseURL+SubjectMappingServiceListSubjectConditionSetsProcedure, + connect.WithSchema(subjectMappingServiceListSubjectConditionSetsMethodDescriptor), + connect.WithClientOptions(opts...), + ), + getSubjectConditionSet: connect.NewClient[subjectmapping.GetSubjectConditionSetRequest, subjectmapping.GetSubjectConditionSetResponse]( + httpClient, + baseURL+SubjectMappingServiceGetSubjectConditionSetProcedure, + connect.WithSchema(subjectMappingServiceGetSubjectConditionSetMethodDescriptor), + connect.WithClientOptions(opts...), + ), + createSubjectConditionSet: connect.NewClient[subjectmapping.CreateSubjectConditionSetRequest, subjectmapping.CreateSubjectConditionSetResponse]( + httpClient, + baseURL+SubjectMappingServiceCreateSubjectConditionSetProcedure, + connect.WithSchema(subjectMappingServiceCreateSubjectConditionSetMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateSubjectConditionSet: connect.NewClient[subjectmapping.UpdateSubjectConditionSetRequest, subjectmapping.UpdateSubjectConditionSetResponse]( + httpClient, + baseURL+SubjectMappingServiceUpdateSubjectConditionSetProcedure, + connect.WithSchema(subjectMappingServiceUpdateSubjectConditionSetMethodDescriptor), + connect.WithClientOptions(opts...), + ), + deleteSubjectConditionSet: connect.NewClient[subjectmapping.DeleteSubjectConditionSetRequest, subjectmapping.DeleteSubjectConditionSetResponse]( + httpClient, + baseURL+SubjectMappingServiceDeleteSubjectConditionSetProcedure, + connect.WithSchema(subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// subjectMappingServiceClient implements SubjectMappingServiceClient. +type subjectMappingServiceClient struct { + matchSubjectMappings *connect.Client[subjectmapping.MatchSubjectMappingsRequest, subjectmapping.MatchSubjectMappingsResponse] + listSubjectMappings *connect.Client[subjectmapping.ListSubjectMappingsRequest, subjectmapping.ListSubjectMappingsResponse] + getSubjectMapping *connect.Client[subjectmapping.GetSubjectMappingRequest, subjectmapping.GetSubjectMappingResponse] + createSubjectMapping *connect.Client[subjectmapping.CreateSubjectMappingRequest, subjectmapping.CreateSubjectMappingResponse] + updateSubjectMapping *connect.Client[subjectmapping.UpdateSubjectMappingRequest, subjectmapping.UpdateSubjectMappingResponse] + deleteSubjectMapping *connect.Client[subjectmapping.DeleteSubjectMappingRequest, subjectmapping.DeleteSubjectMappingResponse] + listSubjectConditionSets *connect.Client[subjectmapping.ListSubjectConditionSetsRequest, subjectmapping.ListSubjectConditionSetsResponse] + getSubjectConditionSet *connect.Client[subjectmapping.GetSubjectConditionSetRequest, subjectmapping.GetSubjectConditionSetResponse] + createSubjectConditionSet *connect.Client[subjectmapping.CreateSubjectConditionSetRequest, subjectmapping.CreateSubjectConditionSetResponse] + updateSubjectConditionSet *connect.Client[subjectmapping.UpdateSubjectConditionSetRequest, subjectmapping.UpdateSubjectConditionSetResponse] + deleteSubjectConditionSet *connect.Client[subjectmapping.DeleteSubjectConditionSetRequest, subjectmapping.DeleteSubjectConditionSetResponse] +} + +// MatchSubjectMappings calls policy.subjectmapping.SubjectMappingService.MatchSubjectMappings. +func (c *subjectMappingServiceClient) MatchSubjectMappings(ctx context.Context, req *connect.Request[subjectmapping.MatchSubjectMappingsRequest]) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) { + return c.matchSubjectMappings.CallUnary(ctx, req) +} + +// ListSubjectMappings calls policy.subjectmapping.SubjectMappingService.ListSubjectMappings. +func (c *subjectMappingServiceClient) ListSubjectMappings(ctx context.Context, req *connect.Request[subjectmapping.ListSubjectMappingsRequest]) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) { + return c.listSubjectMappings.CallUnary(ctx, req) +} + +// GetSubjectMapping calls policy.subjectmapping.SubjectMappingService.GetSubjectMapping. +func (c *subjectMappingServiceClient) GetSubjectMapping(ctx context.Context, req *connect.Request[subjectmapping.GetSubjectMappingRequest]) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) { + return c.getSubjectMapping.CallUnary(ctx, req) +} + +// CreateSubjectMapping calls policy.subjectmapping.SubjectMappingService.CreateSubjectMapping. +func (c *subjectMappingServiceClient) CreateSubjectMapping(ctx context.Context, req *connect.Request[subjectmapping.CreateSubjectMappingRequest]) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) { + return c.createSubjectMapping.CallUnary(ctx, req) +} + +// UpdateSubjectMapping calls policy.subjectmapping.SubjectMappingService.UpdateSubjectMapping. +func (c *subjectMappingServiceClient) UpdateSubjectMapping(ctx context.Context, req *connect.Request[subjectmapping.UpdateSubjectMappingRequest]) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) { + return c.updateSubjectMapping.CallUnary(ctx, req) +} + +// DeleteSubjectMapping calls policy.subjectmapping.SubjectMappingService.DeleteSubjectMapping. +func (c *subjectMappingServiceClient) DeleteSubjectMapping(ctx context.Context, req *connect.Request[subjectmapping.DeleteSubjectMappingRequest]) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) { + return c.deleteSubjectMapping.CallUnary(ctx, req) +} + +// ListSubjectConditionSets calls +// policy.subjectmapping.SubjectMappingService.ListSubjectConditionSets. +func (c *subjectMappingServiceClient) ListSubjectConditionSets(ctx context.Context, req *connect.Request[subjectmapping.ListSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) { + return c.listSubjectConditionSets.CallUnary(ctx, req) +} + +// GetSubjectConditionSet calls policy.subjectmapping.SubjectMappingService.GetSubjectConditionSet. +func (c *subjectMappingServiceClient) GetSubjectConditionSet(ctx context.Context, req *connect.Request[subjectmapping.GetSubjectConditionSetRequest]) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) { + return c.getSubjectConditionSet.CallUnary(ctx, req) +} + +// CreateSubjectConditionSet calls +// policy.subjectmapping.SubjectMappingService.CreateSubjectConditionSet. +func (c *subjectMappingServiceClient) CreateSubjectConditionSet(ctx context.Context, req *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) { + return c.createSubjectConditionSet.CallUnary(ctx, req) +} + +// UpdateSubjectConditionSet calls +// policy.subjectmapping.SubjectMappingService.UpdateSubjectConditionSet. +func (c *subjectMappingServiceClient) UpdateSubjectConditionSet(ctx context.Context, req *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) { + return c.updateSubjectConditionSet.CallUnary(ctx, req) +} + +// DeleteSubjectConditionSet calls +// policy.subjectmapping.SubjectMappingService.DeleteSubjectConditionSet. +func (c *subjectMappingServiceClient) DeleteSubjectConditionSet(ctx context.Context, req *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { + return c.deleteSubjectConditionSet.CallUnary(ctx, req) +} + +// SubjectMappingServiceHandler is an implementation of the +// policy.subjectmapping.SubjectMappingService service. +type SubjectMappingServiceHandler interface { + // Find matching Subject Mappings for a given Subject + MatchSubjectMappings(context.Context, *connect.Request[subjectmapping.MatchSubjectMappingsRequest]) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) + ListSubjectMappings(context.Context, *connect.Request[subjectmapping.ListSubjectMappingsRequest]) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) + GetSubjectMapping(context.Context, *connect.Request[subjectmapping.GetSubjectMappingRequest]) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) + CreateSubjectMapping(context.Context, *connect.Request[subjectmapping.CreateSubjectMappingRequest]) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) + UpdateSubjectMapping(context.Context, *connect.Request[subjectmapping.UpdateSubjectMappingRequest]) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) + DeleteSubjectMapping(context.Context, *connect.Request[subjectmapping.DeleteSubjectMappingRequest]) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) + ListSubjectConditionSets(context.Context, *connect.Request[subjectmapping.ListSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) + GetSubjectConditionSet(context.Context, *connect.Request[subjectmapping.GetSubjectConditionSetRequest]) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) + CreateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) + UpdateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) + DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) +} + +// NewSubjectMappingServiceHandler builds an HTTP handler from the service implementation. It +// returns the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewSubjectMappingServiceHandler(svc SubjectMappingServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + subjectMappingServiceMatchSubjectMappingsHandler := connect.NewUnaryHandler( + SubjectMappingServiceMatchSubjectMappingsProcedure, + svc.MatchSubjectMappings, + connect.WithSchema(subjectMappingServiceMatchSubjectMappingsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceListSubjectMappingsHandler := connect.NewUnaryHandler( + SubjectMappingServiceListSubjectMappingsProcedure, + svc.ListSubjectMappings, + connect.WithSchema(subjectMappingServiceListSubjectMappingsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceGetSubjectMappingHandler := connect.NewUnaryHandler( + SubjectMappingServiceGetSubjectMappingProcedure, + svc.GetSubjectMapping, + connect.WithSchema(subjectMappingServiceGetSubjectMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceCreateSubjectMappingHandler := connect.NewUnaryHandler( + SubjectMappingServiceCreateSubjectMappingProcedure, + svc.CreateSubjectMapping, + connect.WithSchema(subjectMappingServiceCreateSubjectMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceUpdateSubjectMappingHandler := connect.NewUnaryHandler( + SubjectMappingServiceUpdateSubjectMappingProcedure, + svc.UpdateSubjectMapping, + connect.WithSchema(subjectMappingServiceUpdateSubjectMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceDeleteSubjectMappingHandler := connect.NewUnaryHandler( + SubjectMappingServiceDeleteSubjectMappingProcedure, + svc.DeleteSubjectMapping, + connect.WithSchema(subjectMappingServiceDeleteSubjectMappingMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceListSubjectConditionSetsHandler := connect.NewUnaryHandler( + SubjectMappingServiceListSubjectConditionSetsProcedure, + svc.ListSubjectConditionSets, + connect.WithSchema(subjectMappingServiceListSubjectConditionSetsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceGetSubjectConditionSetHandler := connect.NewUnaryHandler( + SubjectMappingServiceGetSubjectConditionSetProcedure, + svc.GetSubjectConditionSet, + connect.WithSchema(subjectMappingServiceGetSubjectConditionSetMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceCreateSubjectConditionSetHandler := connect.NewUnaryHandler( + SubjectMappingServiceCreateSubjectConditionSetProcedure, + svc.CreateSubjectConditionSet, + connect.WithSchema(subjectMappingServiceCreateSubjectConditionSetMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceUpdateSubjectConditionSetHandler := connect.NewUnaryHandler( + SubjectMappingServiceUpdateSubjectConditionSetProcedure, + svc.UpdateSubjectConditionSet, + connect.WithSchema(subjectMappingServiceUpdateSubjectConditionSetMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + subjectMappingServiceDeleteSubjectConditionSetHandler := connect.NewUnaryHandler( + SubjectMappingServiceDeleteSubjectConditionSetProcedure, + svc.DeleteSubjectConditionSet, + connect.WithSchema(subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.subjectmapping.SubjectMappingService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case SubjectMappingServiceMatchSubjectMappingsProcedure: + subjectMappingServiceMatchSubjectMappingsHandler.ServeHTTP(w, r) + case SubjectMappingServiceListSubjectMappingsProcedure: + subjectMappingServiceListSubjectMappingsHandler.ServeHTTP(w, r) + case SubjectMappingServiceGetSubjectMappingProcedure: + subjectMappingServiceGetSubjectMappingHandler.ServeHTTP(w, r) + case SubjectMappingServiceCreateSubjectMappingProcedure: + subjectMappingServiceCreateSubjectMappingHandler.ServeHTTP(w, r) + case SubjectMappingServiceUpdateSubjectMappingProcedure: + subjectMappingServiceUpdateSubjectMappingHandler.ServeHTTP(w, r) + case SubjectMappingServiceDeleteSubjectMappingProcedure: + subjectMappingServiceDeleteSubjectMappingHandler.ServeHTTP(w, r) + case SubjectMappingServiceListSubjectConditionSetsProcedure: + subjectMappingServiceListSubjectConditionSetsHandler.ServeHTTP(w, r) + case SubjectMappingServiceGetSubjectConditionSetProcedure: + subjectMappingServiceGetSubjectConditionSetHandler.ServeHTTP(w, r) + case SubjectMappingServiceCreateSubjectConditionSetProcedure: + subjectMappingServiceCreateSubjectConditionSetHandler.ServeHTTP(w, r) + case SubjectMappingServiceUpdateSubjectConditionSetProcedure: + subjectMappingServiceUpdateSubjectConditionSetHandler.ServeHTTP(w, r) + case SubjectMappingServiceDeleteSubjectConditionSetProcedure: + subjectMappingServiceDeleteSubjectConditionSetHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedSubjectMappingServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedSubjectMappingServiceHandler struct{} + +func (UnimplementedSubjectMappingServiceHandler) MatchSubjectMappings(context.Context, *connect.Request[subjectmapping.MatchSubjectMappingsRequest]) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.MatchSubjectMappings is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) ListSubjectMappings(context.Context, *connect.Request[subjectmapping.ListSubjectMappingsRequest]) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.ListSubjectMappings is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) GetSubjectMapping(context.Context, *connect.Request[subjectmapping.GetSubjectMappingRequest]) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.GetSubjectMapping is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) CreateSubjectMapping(context.Context, *connect.Request[subjectmapping.CreateSubjectMappingRequest]) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.CreateSubjectMapping is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) UpdateSubjectMapping(context.Context, *connect.Request[subjectmapping.UpdateSubjectMappingRequest]) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.UpdateSubjectMapping is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) DeleteSubjectMapping(context.Context, *connect.Request[subjectmapping.DeleteSubjectMappingRequest]) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.DeleteSubjectMapping is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) ListSubjectConditionSets(context.Context, *connect.Request[subjectmapping.ListSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.ListSubjectConditionSets is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) GetSubjectConditionSet(context.Context, *connect.Request[subjectmapping.GetSubjectConditionSetRequest]) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.GetSubjectConditionSet is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) CreateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.CreateSubjectConditionSet is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) UpdateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.UpdateSubjectConditionSet is not implemented")) +} + +func (UnimplementedSubjectMappingServiceHandler) DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.DeleteSubjectConditionSet is not implemented")) +} diff --git a/protocol/go/policy/unsafe/unsafeconnect/unsafe.connect.go b/protocol/go/policy/unsafe/unsafeconnect/unsafe.connect.go new file mode 100644 index 0000000000..db1b9cdf56 --- /dev/null +++ b/protocol/go/policy/unsafe/unsafeconnect/unsafe.connect.go @@ -0,0 +1,371 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: policy/unsafe/unsafe.proto + +package unsafeconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + unsafe "github.com/opentdf/platform/protocol/go/policy/unsafe" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // UnsafeServiceName is the fully-qualified name of the UnsafeService service. + UnsafeServiceName = "policy.unsafe.UnsafeService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // UnsafeServiceUnsafeUpdateNamespaceProcedure is the fully-qualified name of the UnsafeService's + // UnsafeUpdateNamespace RPC. + UnsafeServiceUnsafeUpdateNamespaceProcedure = "/policy.unsafe.UnsafeService/UnsafeUpdateNamespace" + // UnsafeServiceUnsafeReactivateNamespaceProcedure is the fully-qualified name of the + // UnsafeService's UnsafeReactivateNamespace RPC. + UnsafeServiceUnsafeReactivateNamespaceProcedure = "/policy.unsafe.UnsafeService/UnsafeReactivateNamespace" + // UnsafeServiceUnsafeDeleteNamespaceProcedure is the fully-qualified name of the UnsafeService's + // UnsafeDeleteNamespace RPC. + UnsafeServiceUnsafeDeleteNamespaceProcedure = "/policy.unsafe.UnsafeService/UnsafeDeleteNamespace" + // UnsafeServiceUnsafeUpdateAttributeProcedure is the fully-qualified name of the UnsafeService's + // UnsafeUpdateAttribute RPC. + UnsafeServiceUnsafeUpdateAttributeProcedure = "/policy.unsafe.UnsafeService/UnsafeUpdateAttribute" + // UnsafeServiceUnsafeReactivateAttributeProcedure is the fully-qualified name of the + // UnsafeService's UnsafeReactivateAttribute RPC. + UnsafeServiceUnsafeReactivateAttributeProcedure = "/policy.unsafe.UnsafeService/UnsafeReactivateAttribute" + // UnsafeServiceUnsafeDeleteAttributeProcedure is the fully-qualified name of the UnsafeService's + // UnsafeDeleteAttribute RPC. + UnsafeServiceUnsafeDeleteAttributeProcedure = "/policy.unsafe.UnsafeService/UnsafeDeleteAttribute" + // UnsafeServiceUnsafeUpdateAttributeValueProcedure is the fully-qualified name of the + // UnsafeService's UnsafeUpdateAttributeValue RPC. + UnsafeServiceUnsafeUpdateAttributeValueProcedure = "/policy.unsafe.UnsafeService/UnsafeUpdateAttributeValue" + // UnsafeServiceUnsafeReactivateAttributeValueProcedure is the fully-qualified name of the + // UnsafeService's UnsafeReactivateAttributeValue RPC. + UnsafeServiceUnsafeReactivateAttributeValueProcedure = "/policy.unsafe.UnsafeService/UnsafeReactivateAttributeValue" + // UnsafeServiceUnsafeDeleteAttributeValueProcedure is the fully-qualified name of the + // UnsafeService's UnsafeDeleteAttributeValue RPC. + UnsafeServiceUnsafeDeleteAttributeValueProcedure = "/policy.unsafe.UnsafeService/UnsafeDeleteAttributeValue" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + unsafeServiceServiceDescriptor = unsafe.File_policy_unsafe_unsafe_proto.Services().ByName("UnsafeService") + unsafeServiceUnsafeUpdateNamespaceMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeUpdateNamespace") + unsafeServiceUnsafeReactivateNamespaceMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeReactivateNamespace") + unsafeServiceUnsafeDeleteNamespaceMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeDeleteNamespace") + unsafeServiceUnsafeUpdateAttributeMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeUpdateAttribute") + unsafeServiceUnsafeReactivateAttributeMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeReactivateAttribute") + unsafeServiceUnsafeDeleteAttributeMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeDeleteAttribute") + unsafeServiceUnsafeUpdateAttributeValueMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeUpdateAttributeValue") + unsafeServiceUnsafeReactivateAttributeValueMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeReactivateAttributeValue") + unsafeServiceUnsafeDeleteAttributeValueMethodDescriptor = unsafeServiceServiceDescriptor.Methods().ByName("UnsafeDeleteAttributeValue") +) + +// UnsafeServiceClient is a client for the policy.unsafe.UnsafeService service. +type UnsafeServiceClient interface { + // --------------------------------------* + // Namespace RPCs + // --------------------------------------- + UnsafeUpdateNamespace(context.Context, *connect.Request[unsafe.UnsafeUpdateNamespaceRequest]) (*connect.Response[unsafe.UnsafeUpdateNamespaceResponse], error) + UnsafeReactivateNamespace(context.Context, *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) + UnsafeDeleteNamespace(context.Context, *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) + // --------------------------------------* + // Attribute RPCs + // --------------------------------------- + UnsafeUpdateAttribute(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeResponse], error) + UnsafeReactivateAttribute(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) + UnsafeDeleteAttribute(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) + // --------------------------------------* + // Value RPCs + // --------------------------------------- + UnsafeUpdateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeValueResponse], error) + UnsafeReactivateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) + UnsafeDeleteAttributeValue(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) +} + +// NewUnsafeServiceClient constructs a client for the policy.unsafe.UnsafeService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewUnsafeServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) UnsafeServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &unsafeServiceClient{ + unsafeUpdateNamespace: connect.NewClient[unsafe.UnsafeUpdateNamespaceRequest, unsafe.UnsafeUpdateNamespaceResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeUpdateNamespaceProcedure, + connect.WithSchema(unsafeServiceUnsafeUpdateNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeReactivateNamespace: connect.NewClient[unsafe.UnsafeReactivateNamespaceRequest, unsafe.UnsafeReactivateNamespaceResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeReactivateNamespaceProcedure, + connect.WithSchema(unsafeServiceUnsafeReactivateNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeDeleteNamespace: connect.NewClient[unsafe.UnsafeDeleteNamespaceRequest, unsafe.UnsafeDeleteNamespaceResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeDeleteNamespaceProcedure, + connect.WithSchema(unsafeServiceUnsafeDeleteNamespaceMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeUpdateAttribute: connect.NewClient[unsafe.UnsafeUpdateAttributeRequest, unsafe.UnsafeUpdateAttributeResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeUpdateAttributeProcedure, + connect.WithSchema(unsafeServiceUnsafeUpdateAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeReactivateAttribute: connect.NewClient[unsafe.UnsafeReactivateAttributeRequest, unsafe.UnsafeReactivateAttributeResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeReactivateAttributeProcedure, + connect.WithSchema(unsafeServiceUnsafeReactivateAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeDeleteAttribute: connect.NewClient[unsafe.UnsafeDeleteAttributeRequest, unsafe.UnsafeDeleteAttributeResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeDeleteAttributeProcedure, + connect.WithSchema(unsafeServiceUnsafeDeleteAttributeMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeUpdateAttributeValue: connect.NewClient[unsafe.UnsafeUpdateAttributeValueRequest, unsafe.UnsafeUpdateAttributeValueResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeUpdateAttributeValueProcedure, + connect.WithSchema(unsafeServiceUnsafeUpdateAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeReactivateAttributeValue: connect.NewClient[unsafe.UnsafeReactivateAttributeValueRequest, unsafe.UnsafeReactivateAttributeValueResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeReactivateAttributeValueProcedure, + connect.WithSchema(unsafeServiceUnsafeReactivateAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + unsafeDeleteAttributeValue: connect.NewClient[unsafe.UnsafeDeleteAttributeValueRequest, unsafe.UnsafeDeleteAttributeValueResponse]( + httpClient, + baseURL+UnsafeServiceUnsafeDeleteAttributeValueProcedure, + connect.WithSchema(unsafeServiceUnsafeDeleteAttributeValueMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// unsafeServiceClient implements UnsafeServiceClient. +type unsafeServiceClient struct { + unsafeUpdateNamespace *connect.Client[unsafe.UnsafeUpdateNamespaceRequest, unsafe.UnsafeUpdateNamespaceResponse] + unsafeReactivateNamespace *connect.Client[unsafe.UnsafeReactivateNamespaceRequest, unsafe.UnsafeReactivateNamespaceResponse] + unsafeDeleteNamespace *connect.Client[unsafe.UnsafeDeleteNamespaceRequest, unsafe.UnsafeDeleteNamespaceResponse] + unsafeUpdateAttribute *connect.Client[unsafe.UnsafeUpdateAttributeRequest, unsafe.UnsafeUpdateAttributeResponse] + unsafeReactivateAttribute *connect.Client[unsafe.UnsafeReactivateAttributeRequest, unsafe.UnsafeReactivateAttributeResponse] + unsafeDeleteAttribute *connect.Client[unsafe.UnsafeDeleteAttributeRequest, unsafe.UnsafeDeleteAttributeResponse] + unsafeUpdateAttributeValue *connect.Client[unsafe.UnsafeUpdateAttributeValueRequest, unsafe.UnsafeUpdateAttributeValueResponse] + unsafeReactivateAttributeValue *connect.Client[unsafe.UnsafeReactivateAttributeValueRequest, unsafe.UnsafeReactivateAttributeValueResponse] + unsafeDeleteAttributeValue *connect.Client[unsafe.UnsafeDeleteAttributeValueRequest, unsafe.UnsafeDeleteAttributeValueResponse] +} + +// UnsafeUpdateNamespace calls policy.unsafe.UnsafeService.UnsafeUpdateNamespace. +func (c *unsafeServiceClient) UnsafeUpdateNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateNamespaceRequest]) (*connect.Response[unsafe.UnsafeUpdateNamespaceResponse], error) { + return c.unsafeUpdateNamespace.CallUnary(ctx, req) +} + +// UnsafeReactivateNamespace calls policy.unsafe.UnsafeService.UnsafeReactivateNamespace. +func (c *unsafeServiceClient) UnsafeReactivateNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) { + return c.unsafeReactivateNamespace.CallUnary(ctx, req) +} + +// UnsafeDeleteNamespace calls policy.unsafe.UnsafeService.UnsafeDeleteNamespace. +func (c *unsafeServiceClient) UnsafeDeleteNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) { + return c.unsafeDeleteNamespace.CallUnary(ctx, req) +} + +// UnsafeUpdateAttribute calls policy.unsafe.UnsafeService.UnsafeUpdateAttribute. +func (c *unsafeServiceClient) UnsafeUpdateAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateAttributeRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeResponse], error) { + return c.unsafeUpdateAttribute.CallUnary(ctx, req) +} + +// UnsafeReactivateAttribute calls policy.unsafe.UnsafeService.UnsafeReactivateAttribute. +func (c *unsafeServiceClient) UnsafeReactivateAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) { + return c.unsafeReactivateAttribute.CallUnary(ctx, req) +} + +// UnsafeDeleteAttribute calls policy.unsafe.UnsafeService.UnsafeDeleteAttribute. +func (c *unsafeServiceClient) UnsafeDeleteAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) { + return c.unsafeDeleteAttribute.CallUnary(ctx, req) +} + +// UnsafeUpdateAttributeValue calls policy.unsafe.UnsafeService.UnsafeUpdateAttributeValue. +func (c *unsafeServiceClient) UnsafeUpdateAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeValueResponse], error) { + return c.unsafeUpdateAttributeValue.CallUnary(ctx, req) +} + +// UnsafeReactivateAttributeValue calls policy.unsafe.UnsafeService.UnsafeReactivateAttributeValue. +func (c *unsafeServiceClient) UnsafeReactivateAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) { + return c.unsafeReactivateAttributeValue.CallUnary(ctx, req) +} + +// UnsafeDeleteAttributeValue calls policy.unsafe.UnsafeService.UnsafeDeleteAttributeValue. +func (c *unsafeServiceClient) UnsafeDeleteAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) { + return c.unsafeDeleteAttributeValue.CallUnary(ctx, req) +} + +// UnsafeServiceHandler is an implementation of the policy.unsafe.UnsafeService service. +type UnsafeServiceHandler interface { + // --------------------------------------* + // Namespace RPCs + // --------------------------------------- + UnsafeUpdateNamespace(context.Context, *connect.Request[unsafe.UnsafeUpdateNamespaceRequest]) (*connect.Response[unsafe.UnsafeUpdateNamespaceResponse], error) + UnsafeReactivateNamespace(context.Context, *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) + UnsafeDeleteNamespace(context.Context, *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) + // --------------------------------------* + // Attribute RPCs + // --------------------------------------- + UnsafeUpdateAttribute(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeResponse], error) + UnsafeReactivateAttribute(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) + UnsafeDeleteAttribute(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) + // --------------------------------------* + // Value RPCs + // --------------------------------------- + UnsafeUpdateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeValueResponse], error) + UnsafeReactivateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) + UnsafeDeleteAttributeValue(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) +} + +// NewUnsafeServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewUnsafeServiceHandler(svc UnsafeServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + unsafeServiceUnsafeUpdateNamespaceHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeUpdateNamespaceProcedure, + svc.UnsafeUpdateNamespace, + connect.WithSchema(unsafeServiceUnsafeUpdateNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeReactivateNamespaceHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeReactivateNamespaceProcedure, + svc.UnsafeReactivateNamespace, + connect.WithSchema(unsafeServiceUnsafeReactivateNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeDeleteNamespaceHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeDeleteNamespaceProcedure, + svc.UnsafeDeleteNamespace, + connect.WithSchema(unsafeServiceUnsafeDeleteNamespaceMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeUpdateAttributeHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeUpdateAttributeProcedure, + svc.UnsafeUpdateAttribute, + connect.WithSchema(unsafeServiceUnsafeUpdateAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeReactivateAttributeHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeReactivateAttributeProcedure, + svc.UnsafeReactivateAttribute, + connect.WithSchema(unsafeServiceUnsafeReactivateAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeDeleteAttributeHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeDeleteAttributeProcedure, + svc.UnsafeDeleteAttribute, + connect.WithSchema(unsafeServiceUnsafeDeleteAttributeMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeUpdateAttributeValueHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeUpdateAttributeValueProcedure, + svc.UnsafeUpdateAttributeValue, + connect.WithSchema(unsafeServiceUnsafeUpdateAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeReactivateAttributeValueHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeReactivateAttributeValueProcedure, + svc.UnsafeReactivateAttributeValue, + connect.WithSchema(unsafeServiceUnsafeReactivateAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + unsafeServiceUnsafeDeleteAttributeValueHandler := connect.NewUnaryHandler( + UnsafeServiceUnsafeDeleteAttributeValueProcedure, + svc.UnsafeDeleteAttributeValue, + connect.WithSchema(unsafeServiceUnsafeDeleteAttributeValueMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/policy.unsafe.UnsafeService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case UnsafeServiceUnsafeUpdateNamespaceProcedure: + unsafeServiceUnsafeUpdateNamespaceHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeReactivateNamespaceProcedure: + unsafeServiceUnsafeReactivateNamespaceHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeDeleteNamespaceProcedure: + unsafeServiceUnsafeDeleteNamespaceHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeUpdateAttributeProcedure: + unsafeServiceUnsafeUpdateAttributeHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeReactivateAttributeProcedure: + unsafeServiceUnsafeReactivateAttributeHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeDeleteAttributeProcedure: + unsafeServiceUnsafeDeleteAttributeHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeUpdateAttributeValueProcedure: + unsafeServiceUnsafeUpdateAttributeValueHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeReactivateAttributeValueProcedure: + unsafeServiceUnsafeReactivateAttributeValueHandler.ServeHTTP(w, r) + case UnsafeServiceUnsafeDeleteAttributeValueProcedure: + unsafeServiceUnsafeDeleteAttributeValueHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedUnsafeServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedUnsafeServiceHandler struct{} + +func (UnimplementedUnsafeServiceHandler) UnsafeUpdateNamespace(context.Context, *connect.Request[unsafe.UnsafeUpdateNamespaceRequest]) (*connect.Response[unsafe.UnsafeUpdateNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeUpdateNamespace is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeReactivateNamespace(context.Context, *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeReactivateNamespace is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeDeleteNamespace(context.Context, *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeDeleteNamespace is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeUpdateAttribute(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeUpdateAttribute is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeReactivateAttribute(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeReactivateAttribute is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeDeleteAttribute(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeDeleteAttribute is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeUpdateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeUpdateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeUpdateAttributeValue is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeReactivateAttributeValue(context.Context, *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeReactivateAttributeValue is not implemented")) +} + +func (UnimplementedUnsafeServiceHandler) UnsafeDeleteAttributeValue(context.Context, *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.unsafe.UnsafeService.UnsafeDeleteAttributeValue is not implemented")) +} diff --git a/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go b/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go new file mode 100644 index 0000000000..ac0b4ae299 --- /dev/null +++ b/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go @@ -0,0 +1,115 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: wellknownconfiguration/wellknown_configuration.proto + +package wellknownconfigurationconnect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + wellknownconfiguration "github.com/opentdf/platform/protocol/go/wellknownconfiguration" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // WellKnownServiceName is the fully-qualified name of the WellKnownService service. + WellKnownServiceName = "wellknownconfiguration.WellKnownService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // WellKnownServiceGetWellKnownConfigurationProcedure is the fully-qualified name of the + // WellKnownService's GetWellKnownConfiguration RPC. + WellKnownServiceGetWellKnownConfigurationProcedure = "/wellknownconfiguration.WellKnownService/GetWellKnownConfiguration" +) + +// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. +var ( + wellKnownServiceServiceDescriptor = wellknownconfiguration.File_wellknownconfiguration_wellknown_configuration_proto.Services().ByName("WellKnownService") + wellKnownServiceGetWellKnownConfigurationMethodDescriptor = wellKnownServiceServiceDescriptor.Methods().ByName("GetWellKnownConfiguration") +) + +// WellKnownServiceClient is a client for the wellknownconfiguration.WellKnownService service. +type WellKnownServiceClient interface { + GetWellKnownConfiguration(context.Context, *connect.Request[wellknownconfiguration.GetWellKnownConfigurationRequest]) (*connect.Response[wellknownconfiguration.GetWellKnownConfigurationResponse], error) +} + +// NewWellKnownServiceClient constructs a client for the wellknownconfiguration.WellKnownService +// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for +// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply +// the connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewWellKnownServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) WellKnownServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &wellKnownServiceClient{ + getWellKnownConfiguration: connect.NewClient[wellknownconfiguration.GetWellKnownConfigurationRequest, wellknownconfiguration.GetWellKnownConfigurationResponse]( + httpClient, + baseURL+WellKnownServiceGetWellKnownConfigurationProcedure, + connect.WithSchema(wellKnownServiceGetWellKnownConfigurationMethodDescriptor), + connect.WithClientOptions(opts...), + ), + } +} + +// wellKnownServiceClient implements WellKnownServiceClient. +type wellKnownServiceClient struct { + getWellKnownConfiguration *connect.Client[wellknownconfiguration.GetWellKnownConfigurationRequest, wellknownconfiguration.GetWellKnownConfigurationResponse] +} + +// GetWellKnownConfiguration calls +// wellknownconfiguration.WellKnownService.GetWellKnownConfiguration. +func (c *wellKnownServiceClient) GetWellKnownConfiguration(ctx context.Context, req *connect.Request[wellknownconfiguration.GetWellKnownConfigurationRequest]) (*connect.Response[wellknownconfiguration.GetWellKnownConfigurationResponse], error) { + return c.getWellKnownConfiguration.CallUnary(ctx, req) +} + +// WellKnownServiceHandler is an implementation of the wellknownconfiguration.WellKnownService +// service. +type WellKnownServiceHandler interface { + GetWellKnownConfiguration(context.Context, *connect.Request[wellknownconfiguration.GetWellKnownConfigurationRequest]) (*connect.Response[wellknownconfiguration.GetWellKnownConfigurationResponse], error) +} + +// NewWellKnownServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewWellKnownServiceHandler(svc WellKnownServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + wellKnownServiceGetWellKnownConfigurationHandler := connect.NewUnaryHandler( + WellKnownServiceGetWellKnownConfigurationProcedure, + svc.GetWellKnownConfiguration, + connect.WithSchema(wellKnownServiceGetWellKnownConfigurationMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + return "/wellknownconfiguration.WellKnownService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case WellKnownServiceGetWellKnownConfigurationProcedure: + wellKnownServiceGetWellKnownConfigurationHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedWellKnownServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedWellKnownServiceHandler struct{} + +func (UnimplementedWellKnownServiceHandler) GetWellKnownConfiguration(context.Context, *connect.Request[wellknownconfiguration.GetWellKnownConfigurationRequest]) (*connect.Response[wellknownconfiguration.GetWellKnownConfigurationResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("wellknownconfiguration.WellKnownService.GetWellKnownConfiguration is not implemented")) +} From a9f75915fba518967a9440fc507ff4267b8f8240 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 12:44:18 -0500 Subject: [PATCH 02/37] feat: move from fasthttp in-memory listener to memhttp implementation --- service/go.mod | 2 +- service/go.sum | 4 - service/internal/server/memhttp/listener.go | 59 +++++++++ service/internal/server/memhttp/memhttp.go | 138 ++++++++++++++++++++ service/internal/server/memhttp/option.go | 47 +++++++ service/internal/server/server.go | 12 +- 6 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 service/internal/server/memhttp/listener.go create mode 100644 service/internal/server/memhttp/memhttp.go create mode 100644 service/internal/server/memhttp/option.go diff --git a/service/go.mod b/service/go.mod index b8ef0ef9ed..5ec2bcc398 100644 --- a/service/go.mod +++ b/service/go.mod @@ -28,7 +28,6 @@ require ( github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 - github.com/valyala/fasthttp v1.52.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 google.golang.org/grpc v1.66.0 google.golang.org/protobuf v1.34.2 @@ -39,6 +38,7 @@ require ( github.com/Microsoft/hcsshim v0.12.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/casbin/govaluate v1.1.0 // indirect diff --git a/service/go.sum b/service/go.sum index c669975a0e..eba42394a7 100644 --- a/service/go.sum +++ b/service/go.sum @@ -367,10 +367,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tursodatabase/libsql-client-go v0.0.0-20231216154754-8383a53d618f h1:teZ0Pj1Wp3Wk0JObKBiKZqgxhYwLeJhVAyj6DRgmQtY= github.com/tursodatabase/libsql-client-go v0.0.0-20231216154754-8383a53d618f/go.mod h1:UMde0InJz9I0Le/1YIR4xsB0E2vb01MrDY6k/eNdfkg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= -github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= github.com/vertica/vertica-sql-go v1.3.3 h1:fL+FKEAEy5ONmsvya2WH5T8bhkvY27y/Ik3ReR2T+Qw= github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/service/internal/server/memhttp/listener.go b/service/internal/server/memhttp/listener.go new file mode 100644 index 0000000000..1ec303ddba --- /dev/null +++ b/service/internal/server/memhttp/listener.go @@ -0,0 +1,59 @@ +package memhttp + +import ( + "context" + "errors" + "net" + "sync" +) + +type memoryListener struct { + conns chan net.Conn + once sync.Once + closed chan struct{} +} + +// Accept implements net.Listener. +func (l *memoryListener) Accept() (net.Conn, error) { + select { + case conn := <-l.conns: + return conn, nil + case <-l.closed: + return nil, errors.New("listener closed") + } +} + +// Close implements net.Listener. +func (l *memoryListener) Close() error { + l.once.Do(func() { + close(l.closed) + }) + return nil +} + +// Addr implements net.Listener. +func (l *memoryListener) Addr() net.Addr { + return &memoryAddr{} +} + +// DialContext is the type expected by http.Transport.DialContext. +func (l *memoryListener) DialContext(ctx context.Context, _, _ string) (net.Conn, error) { + server, client := net.Pipe() + select { + case <-l.closed: + return nil, errors.New("listener closed") + case l.conns <- server: + return client, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +type memoryAddr struct{} + +// Network implements net.Addr. +func (*memoryAddr) Network() string { return "memory" } + +// String implements io.Stringer, returning a value that matches the +// certificates used by net/http/httptest. +func (*memoryAddr) String() string { return "opentdf.io" } diff --git a/service/internal/server/memhttp/memhttp.go b/service/internal/server/memhttp/memhttp.go new file mode 100644 index 0000000000..5f053e27cc --- /dev/null +++ b/service/internal/server/memhttp/memhttp.go @@ -0,0 +1,138 @@ +// Package memhttp provides an in-memory HTTP server and client. For +// testing-specific adapters, see the memhttptest subpackage. +package memhttp + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net" + "net/http" + "time" + + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" +) + +// Server is a net/http server that uses in-memory pipes instead of TCP. By +// default, it has TLS enabled and supports HTTP/2. It otherwise uses the same +// configuration as the zero value of [http.Server]. +type Server struct { + server *http.Server + Listener *memoryListener + url string + serveErr chan error + cleanupContext func() (context.Context, context.CancelFunc) +} + +// New constructs and starts a Server. +func New(handler http.Handler, opts ...Option) *Server { + var cfg config + WithCleanupTimeout(5 * time.Second).apply(&cfg) //nolint:mnd // Specific to cleanup timeout. + for _, opt := range opts { + opt.apply(&cfg) + } + mlis := &memoryListener{ + conns: make(chan net.Conn), + closed: make(chan struct{}), + } + + var lis net.Listener = mlis + + http2Server := &http2.Server{} + + handler = h2c.NewHandler(handler, http2Server) + + server := &http.Server{ + Handler: handler, + ReadHeaderTimeout: 5 * time.Second, //nolint:mnd // Specific to read header timeout. + } + + serveErr := make(chan error, 1) + go func() { + serveErr <- server.Serve(lis) + }() + + return &Server{ + server: server, + Listener: mlis, + url: fmt.Sprintf("http://%s", mlis.Addr().String()), + serveErr: serveErr, + cleanupContext: cfg.CleanupContext, + } +} + +// Transport returns an [http2.Transport] configured to use in-memory pipes +// rather than TCP, disable automatic compression, trust the server's TLS +// certificate (if any), and use HTTP/2 (if the server supports it). +// +// Callers may reconfigure the returned Transport without affecting other +// transports or clients. +func (s *Server) Transport() *http2.Transport { + transport := &http2.Transport{ + DialTLSContext: func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) { + return s.Listener.DialContext(ctx, network, addr) + }, + AllowHTTP: true, + } + + return transport +} + +// Client returns an [http.Client] configured to use in-memory pipes rather +// than TCP, disable automatic compression, trust the server's TLS certificate +// (if any), and use HTTP/2 (if the server supports it). +// +// Callers may reconfigure the returned client without affecting other clients. +func (s *Server) Client() *http.Client { + return &http.Client{Transport: s.Transport()} +} + +// URL returns the server's URL. +func (s *Server) URL() string { + return s.url +} + +// Close immediately shuts down the server. To shut down the server without +// interrupting in-flight requests, use Shutdown. +func (s *Server) Close() error { + if err := s.server.Close(); err != nil { + return err + } + return s.listenErr() +} + +// Shutdown gracefully shuts down the server, without interrupting any active +// connections. See [http.Server.Shutdown] for details. +func (s *Server) Shutdown(ctx context.Context) error { + if err := s.server.Shutdown(ctx); err != nil { + return err + } + return s.listenErr() +} + +// Cleanup calls Shutdown with a five second timeout. To customize the timeout, +// use WithCleanupTimeout. +// +// Cleanup is primarily intended for use in tests. If you find yourself using +// it, you may want to use the memhttptest package instead. +func (s *Server) Cleanup() error { + ctx, cancel := s.cleanupContext() + defer cancel() + return s.Shutdown(ctx) +} + +// RegisterOnShutdown registers a function to call on Shutdown. It's often used +// to cleanly shut down connections that have been hijacked. See +// [http.Server.RegisterOnShutdown] for details. +func (s *Server) RegisterOnShutdown(f func()) { + s.server.RegisterOnShutdown(f) +} + +func (s *Server) listenErr() error { + if err := <-s.serveErr; err != nil && !errors.Is(err, http.ErrServerClosed) { + return err + } + return nil +} diff --git a/service/internal/server/memhttp/option.go b/service/internal/server/memhttp/option.go new file mode 100644 index 0000000000..6b9666efac --- /dev/null +++ b/service/internal/server/memhttp/option.go @@ -0,0 +1,47 @@ +package memhttp + +import ( + "context" + "log" + "time" +) + +type config struct { + CleanupContext func() (context.Context, context.CancelFunc) + ErrorLog *log.Logger +} + +// An Option configures a Server. +type Option interface { + apply(*config) +} + +type optionFunc func(*config) + +func (f optionFunc) apply(cfg *config) { f(cfg) } + +// WithOptions composes multiple Options into one. +func WithOptions(opts ...Option) Option { + return optionFunc(func(cfg *config) { + for _, opt := range opts { + opt.apply(cfg) + } + }) +} + +// WithCleanupTimeout customizes the default five-second timeout for the +// server's Cleanup method. It's most useful with the memhttptest subpackage. +func WithCleanupTimeout(d time.Duration) Option { + return optionFunc(func(cfg *config) { + cfg.CleanupContext = func() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.Background(), d) + } + }) +} + +// WithErrorLog sets [http.Server.ErrorLog]. +func WithErrorLog(l *log.Logger) Option { + return optionFunc(func(cfg *config) { + cfg.ErrorLog = l + }) +} diff --git a/service/internal/server/server.go b/service/internal/server/server.go index d66461b6a5..70660d71da 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -21,9 +21,9 @@ import ( sdkAudit "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/security" + "github.com/opentdf/platform/service/internal/server/memhttp" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" - "github.com/valyala/fasthttp/fasthttputil" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "google.golang.org/grpc" @@ -122,7 +122,7 @@ https://github.com/heroku/x/blob/master/grpc/grpcserver/inprocess.go https://github.com/valyala/fasthttp/blob/master/fasthttputil/inmemory_listener.go */ type inProcessServer struct { - ln *fasthttputil.InmemoryListener + ln *memhttp.Server srv *grpc.Server maxCallRecvMsgSize int @@ -158,7 +158,7 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err return nil, fmt.Errorf("failed to create grpc server: %w", err) } grpcIPCServer := &inProcessServer{ - ln: fasthttputil.NewInmemoryListener(), + ln: memhttp.New(nil), srv: newGrpcInProcessServer(), maxCallRecvMsgSize: config.GRPC.MaxCallRecvMsgSizeBytes, maxCallSendMsgSize: config.GRPC.MaxCallSendMsgSizeBytes, @@ -407,8 +407,8 @@ func (s inProcessServer) Conn() *grpc.ClientConn { grpc.MaxCallRecvMsgSize(s.maxCallRecvMsgSize), grpc.MaxCallSendMsgSize(s.maxCallSendMsgSize), ), - grpc.WithContextDialer(func(_ context.Context, _ string) (net.Conn, error) { - conn, err := s.ln.Dial() + grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) { + conn, err := s.ln.Listener.DialContext(ctx, "inprocess", "") if err != nil { return nil, fmt.Errorf("failed to dial in process grpc server: %w", err) } @@ -424,7 +424,7 @@ func (s inProcessServer) Conn() *grpc.ClientConn { func (s OpenTDFServer) startInProcessGrpcServer() { s.logger.Info("starting in process grpc server") - if err := s.GRPCInProcess.srv.Serve(s.GRPCInProcess.ln); err != nil { + if err := s.GRPCInProcess.srv.Serve(s.GRPCInProcess.ln.Listener); err != nil { s.logger.Error("failed to serve in process grpc", slog.String("error", err.Error())) panic(err) } From 0e8a8101e31cc0c19414918ea5e3c9ba84cc15d7 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 15:13:20 -0500 Subject: [PATCH 03/37] fix memhttp impl with grpc server --- service/internal/server/server.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/service/internal/server/server.go b/service/internal/server/server.go index 70660d71da..f923730e76 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -157,9 +157,12 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err if err != nil { return nil, fmt.Errorf("failed to create grpc server: %w", err) } + + grpcInProcessServer := newGrpcInProcessServer() + grpcIPCServer := &inProcessServer{ - ln: memhttp.New(nil), - srv: newGrpcInProcessServer(), + ln: memhttp.New(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { grpcInProcessServer.ServeHTTP(w, r) })), + srv: grpcInProcessServer, maxCallRecvMsgSize: config.GRPC.MaxCallRecvMsgSizeBytes, maxCallSendMsgSize: config.GRPC.MaxCallSendMsgSizeBytes, } From bf35ce6b522de7d8c4562977a137b9fdc9014216 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 18:16:31 -0500 Subject: [PATCH 04/37] feat: update service registry in preperation for connectrpc migration --- service/authorization/authorization.go | 132 +++++++++--------- .../claims/claims_entity_resolution.go | 11 +- service/entityresolution/entityresolution.go | 42 +++--- .../keycloak/keycloak_entity_resolution.go | 10 +- service/health/health.go | 34 ++--- service/kas/kas.go | 122 ++++++++-------- service/pkg/server/options.go | 8 +- service/pkg/server/services.go | 16 +-- service/pkg/server/services_test.go | 41 +++--- service/pkg/server/start.go | 4 +- service/pkg/server/start_test.go | 21 ++- .../pkg/serviceregistry/serviceregistry.go | 128 +++++++++++------ service/policy/attributes/attributes.go | 20 +-- .../kasregistry/key_access_server_registry.go | 22 +-- service/policy/namespaces/namespaces.go | 32 ++--- service/policy/policy.go | 24 ++-- .../resourcemapping/resource_mapping.go | 22 +-- .../policy/subjectmapping/subject_mapping.go | 22 +-- service/policy/unsafe/unsafe.go | 21 +-- .../wellknown_configuration.go | 20 +-- 20 files changed, 404 insertions(+), 348 deletions(-) diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go index 049e0a96af..8031fa7805 100644 --- a/service/authorization/authorization.go +++ b/service/authorization/authorization.go @@ -54,92 +54,90 @@ type CustomRego struct { Query string `mapstructure:"query" json:"query" default:"data.opentdf.entitlements.attributes"` } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - Namespace: "authorization", - ServiceDesc: &authorization.AuthorizationService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - var ( - err error - entitlementRego []byte - authZCfg = new(Config) - ) - - logger := srp.Logger - - // default ERS endpoint - as := &AuthorizationService{sdk: srp.SDK, logger: logger} - if err := srp.RegisterReadinessCheck("authorization", as.IsReady); err != nil { - logger.Error("failed to register authorization readiness check", slog.String("error", err.Error())) - } +func NewRegistration() *serviceregistry.Service[AuthorizationService] { + return &serviceregistry.Service[AuthorizationService]{ + ServiceOptions: serviceregistry.ServiceOptions[AuthorizationService]{ + Namespace: "authorization", + ServiceDesc: &authorization.AuthorizationService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*AuthorizationService, serviceregistry.HandlerServer) { + var ( + err error + entitlementRego []byte + authZCfg = new(Config) + ) - if err := defaults.Set(authZCfg); err != nil { - panic(fmt.Errorf("failed to set defaults for authorization service config: %w", err)) - } + logger := srp.Logger - // Only decode config if it exists - if srp.Config != nil { - if err := mapstructure.Decode(srp.Config, &authZCfg); err != nil { - panic(fmt.Errorf("invalid auth svc cfg [%v] %w", srp.Config, err)) + // default ERS endpoint + as := &AuthorizationService{sdk: srp.SDK, logger: logger} + if err := srp.RegisterReadinessCheck("authorization", as.IsReady); err != nil { + logger.Error("failed to register authorization readiness check", slog.String("error", err.Error())) } - } - // Validate Config - validate := validator.New(validator.WithRequiredStructEnabled()) - if err := validate.Struct(authZCfg); err != nil { - var invalidValidationError *validator.InvalidValidationError - if errors.As(err, &invalidValidationError) { - logger.Error("error validating authorization service config", slog.String("error", err.Error())) - panic(fmt.Errorf("error validating authorization service config: %w", err)) + if err := defaults.Set(authZCfg); err != nil { + panic(fmt.Errorf("failed to set defaults for authorization service config: %w", err)) + } + + // Only decode config if it exists + if srp.Config != nil { + if err := mapstructure.Decode(srp.Config, &authZCfg); err != nil { + panic(fmt.Errorf("invalid auth svc cfg [%v] %w", srp.Config, err)) + } } - var validationErrors validator.ValidationErrors - if errors.As(err, &validationErrors) { - for _, err := range validationErrors { + // Validate Config + validate := validator.New(validator.WithRequiredStructEnabled()) + if err := validate.Struct(authZCfg); err != nil { + var invalidValidationError *validator.InvalidValidationError + if errors.As(err, &invalidValidationError) { logger.Error("error validating authorization service config", slog.String("error", err.Error())) panic(fmt.Errorf("error validating authorization service config: %w", err)) } + + var validationErrors validator.ValidationErrors + if errors.As(err, &validationErrors) { + for _, err := range validationErrors { + logger.Error("error validating authorization service config", slog.String("error", err.Error())) + panic(fmt.Errorf("error validating authorization service config: %w", err)) + } + } } - } - logger.Debug("authorization service config", slog.Any("config", *authZCfg)) + logger.Debug("authorization service config", slog.Any("config", *authZCfg)) - // Build Rego PreparedEvalQuery + // Build Rego PreparedEvalQuery - // Load rego from embedded file or custom path - if authZCfg.Rego.Path != "" { - entitlementRego, err = os.ReadFile(authZCfg.Rego.Path) - if err != nil { - panic(fmt.Errorf("failed to read custom entitlements.rego file: %w", err)) - } - } else { - entitlementRego, err = policies.EntitlementsRego.ReadFile("entitlements/entitlements.rego") - if err != nil { - panic(fmt.Errorf("failed to read entitlements.rego file: %w", err)) + // Load rego from embedded file or custom path + if authZCfg.Rego.Path != "" { + entitlementRego, err = os.ReadFile(authZCfg.Rego.Path) + if err != nil { + panic(fmt.Errorf("failed to read custom entitlements.rego file: %w", err)) + } + } else { + entitlementRego, err = policies.EntitlementsRego.ReadFile("entitlements/entitlements.rego") + if err != nil { + panic(fmt.Errorf("failed to read entitlements.rego file: %w", err)) + } } - } - // Register builtin - subjectmappingbuiltin.SubjectMappingBuiltin() + // Register builtin + subjectmappingbuiltin.SubjectMappingBuiltin() - as.eval, err = rego.New( - rego.Query(authZCfg.Rego.Query), - rego.Module("entitlements.rego", string(entitlementRego)), - rego.StrictBuiltinErrors(true), - ).PrepareForEval(context.Background()) - if err != nil { - panic(fmt.Errorf("failed to prepare entitlements.rego for eval: %w", err)) - } + as.eval, err = rego.New( + rego.Query(authZCfg.Rego.Query), + rego.Module("entitlements.rego", string(entitlementRego)), + rego.StrictBuiltinErrors(true), + ).PrepareForEval(context.Background()) + if err != nil { + panic(fmt.Errorf("failed to prepare entitlements.rego for eval: %w", err)) + } - as.config = *authZCfg + as.config = *authZCfg - return as, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - authServer, okAuth := server.(authorization.AuthorizationServiceServer) - if !okAuth { - return fmt.Errorf("failed to assert server type to authorization.AuthorizationServiceServer") + return as, func(ctx context.Context, mux *runtime.ServeMux) error { + return authorization.RegisterAuthorizationServiceHandlerServer(ctx, mux, as) } - return authorization.RegisterAuthorizationServiceHandlerServer(ctx, mux, authServer) - } + }, }, } } diff --git a/service/entityresolution/claims/claims_entity_resolution.go b/service/entityresolution/claims/claims_entity_resolution.go index cde559cc2b..6fea8a8d6f 100644 --- a/service/entityresolution/claims/claims_entity_resolution.go +++ b/service/entityresolution/claims/claims_entity_resolution.go @@ -22,10 +22,11 @@ type ClaimsEntityResolutionService struct { logger *logger.Logger } -func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) (any, serviceregistry.HandlerServer) { - return &ClaimsEntityResolutionService{logger: logger}, - func(ctx context.Context, mux *runtime.ServeMux, server any) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, server.(entityresolution.EntityResolutionServiceServer)) //nolint:forcetypeassert // allow type assert, following other services +func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) (ClaimsEntityResolutionService, serviceregistry.HandlerServer) { + claimsSVC := ClaimsEntityResolutionService{logger: logger} + return claimsSVC, + func(ctx context.Context, mux *runtime.ServeMux) error { + return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, claimsSVC) //nolint:forcetypeassert // allow type assert, following other services } } @@ -64,7 +65,7 @@ func EntityResolution(_ context.Context, var resolvedEntities []*entityresolution.EntityRepresentation for idx, ident := range payload { - var entityStruct = &structpb.Struct{} + entityStruct := &structpb.Struct{} switch ident.GetEntityType().(type) { case *authorization.Entity_Claims: claims := ident.GetClaims() diff --git a/service/entityresolution/entityresolution.go b/service/entityresolution/entityresolution.go index 9fd6c81e28..44537c8009 100644 --- a/service/entityresolution/entityresolution.go +++ b/service/entityresolution/entityresolution.go @@ -12,25 +12,35 @@ type ERSConfig struct { Mode string `mapstructure:"mode" json:"mode"` } -const KeycloakMode = "keycloak" -const ClaimsMode = "claims" +const ( + KeycloakMode = "keycloak" + ClaimsMode = "claims" +) + +type EntityResolution struct { + entityresolution.EntityResolutionServiceServer +} -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - Namespace: "entityresolution", - ServiceDesc: &entityresolution.EntityResolutionService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - var inputConfig ERSConfig +func NewRegistration() *serviceregistry.Service[EntityResolution] { + return &serviceregistry.Service[EntityResolution]{ + ServiceOptions: serviceregistry.ServiceOptions[EntityResolution]{ + Namespace: "entityresolution", + ServiceDesc: &entityresolution.EntityResolutionService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*EntityResolution, serviceregistry.HandlerServer) { + var inputConfig ERSConfig - if err := mapstructure.Decode(srp.Config, &inputConfig); err != nil { - panic(err) - } - if inputConfig.Mode == ClaimsMode { - return claims.RegisterClaimsERS(srp.Config, srp.Logger) - } + if err := mapstructure.Decode(srp.Config, &inputConfig); err != nil { + panic(err) + } + if inputConfig.Mode == ClaimsMode { + claimsSVC, claimsHandler := claims.RegisterClaimsERS(srp.Config, srp.Logger) + return &EntityResolution{EntityResolutionServiceServer: claimsSVC}, claimsHandler + } - // Default to keyclaok ERS - return keycloak.RegisterKeycloakERS(srp.Config, srp.Logger) + // Default to keyclaok ERS + kcSVC, kcHandler := keycloak.RegisterKeycloakERS(srp.Config, srp.Logger) + return &EntityResolution{EntityResolutionServiceServer: kcSVC}, kcHandler + }, }, } } diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index a2a9b484cd..5c0617a214 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -52,16 +52,16 @@ type KeycloakConfig struct { InferID InferredIdentityConfig `mapstructure:"inferid,omitempty" json:"inferid,omitempty"` } -func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Logger) (any, serviceregistry.HandlerServer) { +func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Logger) (*KeycloakEntityResolutionService, serviceregistry.HandlerServer) { var inputIdpConfig KeycloakConfig if err := mapstructure.Decode(config, &inputIdpConfig); err != nil { panic(err) } logger.Debug("entity_resolution configuration", "config", inputIdpConfig) - - return &KeycloakEntityResolutionService{idpConfig: inputIdpConfig, logger: logger}, - func(ctx context.Context, mux *runtime.ServeMux, server any) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, server.(entityresolution.EntityResolutionServiceServer)) //nolint:forcetypeassert // allow type assert, following other services + keycloakSVC := &KeycloakEntityResolutionService{idpConfig: inputIdpConfig, logger: logger} + return keycloakSVC, + func(ctx context.Context, mux *runtime.ServeMux) error { + return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, keycloakSVC) //nolint:forcetypeassert // allow type assert, following other services } } diff --git a/service/health/health.go b/service/health/health.go index a8e53c4a12..053da5dffc 100644 --- a/service/health/health.go +++ b/service/health/health.go @@ -12,29 +12,29 @@ import ( "google.golang.org/grpc/status" ) -var ( - serviceHealthChecks = make(map[string]func(context.Context) error) -) +var serviceHealthChecks = make(map[string]func(context.Context) error) type HealthService struct { //nolint:revive // HealthService is a valid name for this struct healthpb.UnimplementedHealthServer logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - Namespace: "health", - ServiceDesc: &healthpb.Health_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - err := srp.WellKnownConfig("health", map[string]any{ - "endpoint": "/healthz", - }) - if err != nil { - srp.Logger.Error("failed to set well-known config", slog.String("error", err.Error())) - } - return &HealthService{logger: srp.Logger}, func(_ context.Context, _ *runtime.ServeMux, _ any) error { - return nil - } +func NewRegistration() *serviceregistry.Service[HealthService] { + return &serviceregistry.Service[HealthService]{ + ServiceOptions: serviceregistry.ServiceOptions[HealthService]{ + Namespace: "health", + ServiceDesc: &healthpb.Health_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*HealthService, serviceregistry.HandlerServer) { + err := srp.WellKnownConfig("health", map[string]any{ + "endpoint": "/healthz", + }) + if err != nil { + srp.Logger.Error("failed to set well-known config", slog.String("error", err.Error())) + } + return &HealthService{logger: srp.Logger}, func(_ context.Context, _ *runtime.ServeMux) error { + return nil + } + }, }, } } diff --git a/service/kas/kas.go b/service/kas/kas.go index 8cb3c14963..280a068ec1 100644 --- a/service/kas/kas.go +++ b/service/kas/kas.go @@ -15,77 +15,75 @@ import ( "github.com/opentdf/platform/service/pkg/serviceregistry" ) -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - Namespace: "kas", - ServiceDesc: &kaspb.AccessService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - // FIXME msg="mismatched key access url" keyAccessURL=http://localhost:9000 kasURL=https://:9000 - hostWithPort := srp.OTDF.HTTPServer.Addr - if strings.HasPrefix(hostWithPort, ":") { - hostWithPort = "localhost" + hostWithPort - } - kasURLString := "http://" + hostWithPort - kasURI, err := url.Parse(kasURLString) - if err != nil { - panic(fmt.Errorf("invalid kas address [%s] %w", kasURLString, err)) - } +func NewRegistration() *serviceregistry.Service[access.Provider] { + return &serviceregistry.Service[access.Provider]{ + ServiceOptions: serviceregistry.ServiceOptions[access.Provider]{ + Namespace: "kas", + ServiceDesc: &kaspb.AccessService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*access.Provider, serviceregistry.HandlerServer) { + // FIXME msg="mismatched key access url" keyAccessURL=http://localhost:9000 kasURL=https://:9000 + hostWithPort := srp.OTDF.HTTPServer.Addr + if strings.HasPrefix(hostWithPort, ":") { + hostWithPort = "localhost" + hostWithPort + } + kasURLString := "http://" + hostWithPort + kasURI, err := url.Parse(kasURLString) + if err != nil { + panic(fmt.Errorf("invalid kas address [%s] %w", kasURLString, err)) + } - var kasCfg access.KASConfig - if err := mapstructure.Decode(srp.Config, &kasCfg); err != nil { - panic(fmt.Errorf("invalid kas cfg [%v] %w", srp.Config, err)) - } + var kasCfg access.KASConfig + if err := mapstructure.Decode(srp.Config, &kasCfg); err != nil { + panic(fmt.Errorf("invalid kas cfg [%v] %w", srp.Config, err)) + } - switch { - case kasCfg.ECCertID != "" && len(kasCfg.Keyring) > 0: - panic("invalid kas cfg: please specify keyring or eccertid, not both") - case len(kasCfg.Keyring) == 0: - deprecatedOrDefault := func(kid, alg string) { - if kid == "" { - kid = srp.OTDF.CryptoProvider.FindKID(alg) + switch { + case kasCfg.ECCertID != "" && len(kasCfg.Keyring) > 0: + panic("invalid kas cfg: please specify keyring or eccertid, not both") + case len(kasCfg.Keyring) == 0: + deprecatedOrDefault := func(kid, alg string) { + if kid == "" { + kid = srp.OTDF.CryptoProvider.FindKID(alg) + } + if kid == "" { + srp.Logger.Warn("no known key for alg", "algorithm", alg) + return + } + kasCfg.Keyring = append(kasCfg.Keyring, access.CurrentKeyFor{ + Algorithm: alg, + KID: kid, + }) + kasCfg.Keyring = append(kasCfg.Keyring, access.CurrentKeyFor{ + Algorithm: alg, + KID: kid, + Legacy: true, + }) } - if kid == "" { - srp.Logger.Warn("no known key for alg", "algorithm", alg) - return - } - kasCfg.Keyring = append(kasCfg.Keyring, access.CurrentKeyFor{ - Algorithm: alg, - KID: kid, - }) - kasCfg.Keyring = append(kasCfg.Keyring, access.CurrentKeyFor{ - Algorithm: alg, - KID: kid, - Legacy: true, - }) + deprecatedOrDefault(kasCfg.ECCertID, security.AlgorithmECP256R1) + deprecatedOrDefault(kasCfg.RSACertID, security.AlgorithmRSA2048) + default: + kasCfg.Keyring = append(kasCfg.Keyring, inferLegacyKeys(kasCfg.Keyring)...) } - deprecatedOrDefault(kasCfg.ECCertID, security.AlgorithmECP256R1) - deprecatedOrDefault(kasCfg.RSACertID, security.AlgorithmRSA2048) - default: - kasCfg.Keyring = append(kasCfg.Keyring, inferLegacyKeys(kasCfg.Keyring)...) - } - p := access.Provider{ - URI: *kasURI, - AttributeSvc: nil, - CryptoProvider: srp.OTDF.CryptoProvider, - SDK: srp.SDK, - Logger: srp.Logger, - KASConfig: kasCfg, - } + p := access.Provider{ + URI: *kasURI, + AttributeSvc: nil, + CryptoProvider: srp.OTDF.CryptoProvider, + SDK: srp.SDK, + Logger: srp.Logger, + KASConfig: kasCfg, + } - srp.Logger.Debug("kas config", "config", kasCfg) + srp.Logger.Debug("kas config", "config", kasCfg) - if err := srp.RegisterReadinessCheck("kas", p.IsReady); err != nil { - srp.Logger.Error("failed to register kas readiness check", slog.String("error", err.Error())) - } + if err := srp.RegisterReadinessCheck("kas", p.IsReady); err != nil { + srp.Logger.Error("failed to register kas readiness check", slog.String("error", err.Error())) + } - return &p, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - kas, ok := server.(*access.Provider) - if !ok { - panic("invalid kas server object") + return &p, func(ctx context.Context, mux *runtime.ServeMux) error { + return kaspb.RegisterAccessServiceHandlerServer(ctx, mux, &p) } - return kaspb.RegisterAccessServiceHandlerServer(ctx, mux, kas) - } + }, }, } } diff --git a/service/pkg/server/options.go b/service/pkg/server/options.go index 75eed19eec..6a44e268fd 100644 --- a/service/pkg/server/options.go +++ b/service/pkg/server/options.go @@ -12,8 +12,8 @@ type StartConfig struct { WaitForShutdownSignal bool PublicRoutes []string authzDefaultPolicyExtension [][]string - extraCoreServices []serviceregistry.Registration - extraServices []serviceregistry.Registration + extraCoreServices []serviceregistry.IService + extraServices []serviceregistry.IService } // Deprecated: Use WithConfigKey @@ -73,7 +73,7 @@ func WithAuthZDefaultPolicyExtension(policies [][]string) StartOptions { // WithCoreServices option adds additional core services to the platform // It takes a variadic parameter of type serviceregistry.Registration, which represents the core services to be added. -func WithCoreServices(services ...serviceregistry.Registration) StartOptions { +func WithCoreServices(services ...serviceregistry.IService) StartOptions { return func(c StartConfig) StartConfig { c.extraCoreServices = append(c.extraCoreServices, services...) return c @@ -83,7 +83,7 @@ func WithCoreServices(services ...serviceregistry.Registration) StartOptions { // WithServices option adds additional services to the platform. // This will set the mode for these services to the namespace name. // It takes a variadic parameter of type serviceregistry.Registration, which represents the services to be added. -func WithServices(services ...serviceregistry.Registration) StartOptions { +func WithServices(services ...serviceregistry.IService) StartOptions { return func(c StartConfig) StartConfig { c.extraServices = append(c.extraServices, services...) return c diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index 6941609a86..a21e736174 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -39,7 +39,7 @@ const ( // registerEssentialServices registers the essential services to the given service registry. // It takes a serviceregistry.Registry as input and returns an error if registration fails. func registerEssentialServices(reg serviceregistry.Registry) error { - essentialServices := []serviceregistry.Registration{ + essentialServices := []serviceregistry.IService{ health.NewRegistration(), } // Register the essential services @@ -55,7 +55,7 @@ func registerEssentialServices(reg serviceregistry.Registry) error { // It returns the list of registered services and any error encountered during registration. func registerCoreServices(reg serviceregistry.Registry, mode []string) ([]string, error) { var ( - services []serviceregistry.Registration + services []serviceregistry.IService registeredServices []string ) @@ -63,7 +63,7 @@ func registerCoreServices(reg serviceregistry.Registry, mode []string) ([]string switch m { case "all": registeredServices = append(registeredServices, []string{servicePolicy, serviceAuthorization, serviceKAS, serviceWellKnown, serviceEntityResolution}...) - services = append(services, []serviceregistry.Registration{ + services = append(services, []serviceregistry.IService{ authorization.NewRegistration(), kas.NewRegistration(), wellknown.NewRegistration(), @@ -72,7 +72,7 @@ func registerCoreServices(reg serviceregistry.Registry, mode []string) ([]string services = append(services, policy.NewRegistrations()...) case "core": registeredServices = append(registeredServices, []string{servicePolicy, serviceAuthorization, serviceWellKnown}...) - services = append(services, []serviceregistry.Registration{ + services = append(services, []serviceregistry.IService{ entityresolution.NewRegistration(), authorization.NewRegistration(), wellknown.NewRegistration(), @@ -142,17 +142,17 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS for _, svc := range namespace.Services { // Get new db client if it is required and not already created - if svc.DB.Required && svcDBClient == nil { + if svc.IsDBRequired() && svcDBClient == nil { logger.Debug("creating database client", slog.String("namespace", ns)) var err error - svcDBClient, err = newServiceDBClient(ctx, cfg.Logger, cfg.DB, ns, svc.DB.Migrations) + svcDBClient, err = newServiceDBClient(ctx, cfg.Logger, cfg.DB, ns, svc.DBMigrations()) if err != nil { return err } } err = svc.Start(ctx, serviceregistry.RegistrationParams{ - Config: cfg.Services[svc.Namespace], + Config: cfg.Services[svc.GetNamespace()], Logger: svcLogger, DBClient: svcDBClient, SDK: client, @@ -182,7 +182,7 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS logger.Info( "service running", slog.String("namespace", ns), - slog.String("service", svc.ServiceDesc.ServiceName), + slog.String("service", svc.GetServiceDesc().ServiceName), slog.Group("database", slog.Any("required", svcDBClient != nil), slog.Any("migrationStatus", determineStatusOfMigration(svcDBClient)), diff --git a/service/pkg/server/services_test.go b/service/pkg/server/services_test.go index ee50ab6fcb..1f9037f400 100644 --- a/service/pkg/server/services_test.go +++ b/service/pkg/server/services_test.go @@ -22,17 +22,17 @@ type mockTestServiceOptions struct { serviceName string serviceHandlerType any serviceObject any - serviceHandler func(ctx context.Context, mux *runtime.ServeMux, server any) error + serviceHandler func(ctx context.Context, mux *runtime.ServeMux) error dbRegister serviceregistry.DBRegister } -func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.Registration, *spyTestService) { +func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.IService, *spyTestService) { spy := &spyTestService{} mockTestServiceDefaults := mockTestServiceOptions{ namespace: "test", serviceName: "TestService", serviceHandlerType: (*interface{})(nil), - serviceHandler: func(_ context.Context, _ *runtime.ServeMux, _ any) error { + serviceHandler: func(_ context.Context, _ *runtime.ServeMux) error { return nil }, } @@ -52,21 +52,28 @@ func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.Regis serviceHandler = opts.serviceHandler } - return serviceregistry.Registration{ - Namespace: namespace, - ServiceDesc: &grpc.ServiceDesc{ - ServiceName: serviceName, - HandlerType: serviceHandlerType, + return &serviceregistry.Service[TestService]{ + ServiceOptions: serviceregistry.ServiceOptions[TestService]{ + Namespace: namespace, + ServiceDesc: &grpc.ServiceDesc{ + ServiceName: serviceName, + HandlerType: serviceHandlerType, + }, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*TestService, serviceregistry.HandlerServer) { + var ts *TestService + var ok bool + if ts, ok = opts.serviceObject.(*TestService); !ok { + panic("serviceObject is not a TestService") + } + return ts, func(ctx context.Context, mux *runtime.ServeMux) error { + spy.wasCalled = true + spy.callParams = append(spy.callParams, srp, ctx, mux, ts) + return serviceHandler(ctx, mux) + } + }, + + DB: opts.dbRegister, }, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return opts.serviceObject, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - spy.wasCalled = true - spy.callParams = append(spy.callParams, srp, ctx, mux, server) - return serviceHandler(ctx, mux, server) - } - }, - - DB: opts.dbRegister, }, spy } diff --git a/service/pkg/server/start.go b/service/pkg/server/start.go index 1b3af7c8bc..8a82dec64e 100644 --- a/service/pkg/server/start.go +++ b/service/pkg/server/start.go @@ -126,9 +126,9 @@ func Start(f ...StartOptions) error { if len(startConfig.extraServices) > 0 { logger.Debug("registering extra services") for _, service := range startConfig.extraServices { - err := svcRegistry.RegisterService(service, service.Namespace) + err := svcRegistry.RegisterService(service, service.GetNamespace()) if err != nil { - logger.Error("could not register extra service", slog.String("namespace", service.Namespace), slog.String("error", err.Error())) + logger.Error("could not register extra service", slog.String("namespace", service.GetNamespace()), slog.String("error", err.Error())) return fmt.Errorf("could not register extra service: %w", err) } } diff --git a/service/pkg/server/start_test.go b/service/pkg/server/start_test.go index 0d6a6c51c5..5ab8ed3144 100644 --- a/service/pkg/server/start_test.go +++ b/service/pkg/server/start_test.go @@ -2,15 +2,13 @@ package server import ( "context" - "fmt" "io" + "log/slog" "net/http" "net/http/httptest" "testing" "time" - "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/config" @@ -22,8 +20,10 @@ import ( "github.com/stretchr/testify/suite" ) -type TestServiceService interface{} -type TestService struct{} +type ( + TestServiceService interface{} + TestService struct{} +) func (t TestService) TestHandler(w http.ResponseWriter, _ *http.Request, _ map[string]string) { _, err := w.Write([]byte("hello from test service!")) @@ -99,14 +99,11 @@ func (suite *StartTestSuite) Test_Start_When_Extra_Service_Registered_Expect_Res require.NoError(t, err) // Register Test Service + ts := &TestService{} registerTestService, _ := mockTestServiceRegistry(mockTestServiceOptions{ - serviceObject: &TestService{}, - serviceHandler: func(_ context.Context, mux *runtime.ServeMux, server any) error { - t, ok := server.(*TestService) - if !ok { - return fmt.Errorf("Surprise! Not a TestService") - } - return mux.HandlePath(http.MethodGet, "/healthz", t.TestHandler) + serviceObject: ts, + serviceHandler: func(_ context.Context, mux *runtime.ServeMux) error { + return mux.HandlePath(http.MethodGet, "/healthz", ts.TestHandler) }, }) diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index a5c1f71571..6369dae241 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -5,8 +5,10 @@ import ( "embed" "fmt" "log/slog" + "net/http" "slices" + "connectrpc.com/connect" "github.com/opentdf/platform/sdk" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -47,23 +49,10 @@ type RegistrationParams struct { // ready to serve requests. This function should be called in the RegisterFunc function. RegisterReadinessCheck func(namespace string, check func(context.Context) error) error } -type HandlerServer func(ctx context.Context, mux *runtime.ServeMux, server any) error -type RegisterFunc func(RegistrationParams) (Impl any, HandlerServer HandlerServer) - -// Registration is a struct that holds the information needed to register a service -type Registration struct { - // Namespace is the namespace of the service. One or more gRPC services can be registered under - // the same namespace. - Namespace string - // ServiceDesc is the gRPC service descriptor. For non-gRPC services, this can be mocked out, - // but at minimum, the ServiceName field must be set - ServiceDesc *grpc.ServiceDesc - // RegisterFunc is the function that will be called to register the service - RegisterFunc RegisterFunc - - // DB is optional and used to register the service with a database - DB DBRegister -} +type ( + HandlerServer func(ctx context.Context, mux *runtime.ServeMux) error + RegisterFunc[S any] func(RegistrationParams) (Impl *S, HandlerServer HandlerServer) +) // DBRegister is a struct that holds the information needed to register a service with a database type DBRegister struct { @@ -75,21 +64,78 @@ type DBRegister struct { Migrations *embed.FS } +type IService interface { + IsDBRequired() bool + DBMigrations() *embed.FS + GetNamespace() string + GetServiceDesc() *grpc.ServiceDesc + Start(ctx context.Context, params RegistrationParams) error + IsStarted() bool + Shutdown() error + RegisterGRPCServer(server *grpc.Server) error + RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error +} + // Service is a struct that holds the registration information for a service as well as the state // of the service within the instance of the platform. -type Service struct { - Registration - impl any +type Service[S any] struct { + // Registration + impl *S handleFunc HandlerServer // Started is a flag that indicates whether the service has been started Started bool // Close is a function that can be called to close the service Close func() + // Service Options + ServiceOptions[S] +} + +type ServiceOptions[S any] struct { + // Namespace is the namespace of the service. One or more gRPC services can be registered under + // the same namespace. + Namespace string + // ServiceDesc is the gRPC service descriptor. For non-gRPC services, this can be mocked out, + // but at minimum, the ServiceName field must be set + ServiceDesc *grpc.ServiceDesc + // RegisterFunc is the function that will be called to register the service + RegisterFunc RegisterFunc[S] + httpHandlerFunc HandlerServer + // ConnectRPCServiceHandler is the function that will be called to register the service with the + ConnectRPCFunc func(S, ...connect.HandlerOption) (string, http.Handler) + // DB is optional and used to register the service with a database + DB DBRegister +} + +func (s Service[S]) GetNamespace() string { + return s.Namespace +} + +func (s Service[S]) GetServiceDesc() *grpc.ServiceDesc { + return s.ServiceDesc +} + +func (s Service[S]) IsStarted() bool { + return s.Started +} + +func (s Service[S]) Shutdown() error { + if s.Close != nil { + s.Close() + } + return nil +} + +func (s Service[S]) IsDBRequired() bool { + return s.DB.Required +} + +func (s Service[S]) DBMigrations() *embed.FS { + return s.DB.Migrations } // Start starts the service and performs necessary initialization steps. // It returns an error if the service is already started or if there is an issue running database migrations. -func (s *Service) Start(ctx context.Context, params RegistrationParams) error { +func (s *Service[S]) Start(ctx context.Context, params RegistrationParams) error { if s.Started { return fmt.Errorf("service already started") } @@ -113,7 +159,7 @@ func (s *Service) Start(ctx context.Context, params RegistrationParams) error { // RegisterGRPCServer registers the gRPC server with the service implementation. // It checks if the service implementation is registered and then registers the service with the server. // It returns an error if the service implementation is not registered. -func (s *Service) RegisterGRPCServer(server *grpc.Server) error { +func (s *Service[S]) RegisterGRPCServer(server *grpc.Server) error { if s.impl == nil { return fmt.Errorf("service did not register an implementation") } @@ -126,17 +172,17 @@ func (s *Service) RegisterGRPCServer(server *grpc.Server) error { // RegisterHTTPServer registers an HTTP server with the service. // It takes a context, a ServeMux, and an implementation function as parameters. // If the service did not register a handler, it returns an error. -func (s *Service) RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error { +func (s *Service[S]) RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error { if s.handleFunc == nil { return fmt.Errorf("service did not register a handler") } - return s.handleFunc(ctx, mux, s.impl) + return s.handleFunc(ctx, mux) } // namespace represents a namespace in the service registry. type Namespace struct { Mode string - Services []Service + Services []IService } // Registry represents a map of service namespaces. @@ -150,8 +196,8 @@ func NewServiceRegistry() Registry { // RegisterCoreService registers a core service with the given registration information. // It calls the RegisterService method of the Registry instance with the provided registration and service type "core". // Returns an error if the registration fails. -func (reg Registry) RegisterCoreService(r Registration) error { - return reg.RegisterService(r, "core") +func (reg Registry) RegisterCoreService(svc IService) error { + return reg.RegisterService(svc, "core") } // RegisterService registers a service in the service registry. @@ -160,27 +206,25 @@ func (reg Registry) RegisterCoreService(r Registration) error { // such as the namespace and service description. // The mode string specifies the mode in which the service should be registered. // It returns an error if the service is already registered in the specified namespace. -func (reg Registry) RegisterService(r Registration, mode string) error { +func (reg Registry) RegisterService(svc IService, mode string) error { // Can't directly modify structs within a map, so we need to copy the namespace - copyNamespace := reg[r.Namespace] + copyNamespace := reg[svc.GetNamespace()] copyNamespace.Mode = mode if copyNamespace.Services == nil { - copyNamespace.Services = make([]Service, 0) + copyNamespace.Services = make([]IService, 0) } - found := slices.ContainsFunc(reg[r.Namespace].Services, func(s Service) bool { - return s.ServiceDesc.ServiceName == r.ServiceDesc.ServiceName + found := slices.ContainsFunc(reg[svc.GetNamespace()].Services, func(s IService) bool { + return s.GetServiceDesc().ServiceName == svc.GetServiceDesc().ServiceName }) if found { - return fmt.Errorf("service already registered namespace:%s service:%s", r.Namespace, r.ServiceDesc.ServiceName) + return fmt.Errorf("service already registered namespace:%s service:%s", svc.GetNamespace(), svc.GetServiceDesc().ServiceName) } - slog.Info("registered service", slog.String("namespace", r.Namespace), slog.String("service", r.ServiceDesc.ServiceName)) - copyNamespace.Services = append(copyNamespace.Services, Service{ - Registration: r, - }) + slog.Info("registered service", slog.String("namespace", svc.GetNamespace()), slog.String("service", svc.GetServiceDesc().ServiceName)) + copyNamespace.Services = append(copyNamespace.Services, svc) - reg[r.Namespace] = copyNamespace + reg[svc.GetNamespace()] = copyNamespace return nil } @@ -191,9 +235,11 @@ func (reg Registry) RegisterService(r Registration, mode string) error { func (reg Registry) Shutdown() { for name, ns := range reg { for _, svc := range ns.Services { - if svc.Close != nil && svc.Started { - slog.Info("stopping service", slog.String("namespace", name), slog.String("service", svc.ServiceDesc.ServiceName)) - svc.Close() + if svc.IsStarted() { + slog.Info("stopping service", slog.String("namespace", name), slog.String("service", svc.GetServiceDesc().ServiceName)) + if err := svc.Shutdown(); err != nil { + slog.Error("error stopping service", slog.String("namespace", name), slog.String("service", svc.GetServiceDesc().ServiceName), slog.String("error", err.Error())) + } } } } diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 2bae2efe2f..c3d31aa836 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -21,16 +21,18 @@ type AttributesService struct { //nolint:revive // AttributesService is a valid logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &attributes.AttributesService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &AttributesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - if srv, ok := server.(attributes.AttributesServiceServer); ok { - return attributes.RegisterAttributesServiceHandlerServer(ctx, mux, srv) +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[AttributesService] { + return &serviceregistry.Service[AttributesService]{ + ServiceOptions: serviceregistry.ServiceOptions[AttributesService]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &attributes.AttributesService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*AttributesService, serviceregistry.HandlerServer) { + as := &AttributesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + return as, func(ctx context.Context, mux *runtime.ServeMux) error { + return attributes.RegisterAttributesServiceHandlerServer(ctx, mux, as) } - return fmt.Errorf("failed to assert server as attributes.AttributesServiceServer") - } + }, }, } } diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index c64bad3ff9..a310facc80 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -2,7 +2,6 @@ package kasregistry import ( "context" - "fmt" "log/slog" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -21,17 +20,18 @@ type KeyAccessServerRegistry struct { logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &kasr.KeyAccessServerRegistryService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &KeyAccessServerRegistry{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, s any) error { - srv, ok := s.(kasr.KeyAccessServerRegistryServiceServer) - if !ok { - return fmt.Errorf("argument is not of type kasr.KeyAccessServerRegistryServiceServer") +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[KeyAccessServerRegistry] { + return &serviceregistry.Service[KeyAccessServerRegistry]{ + ServiceOptions: serviceregistry.ServiceOptions[KeyAccessServerRegistry]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &kasr.KeyAccessServerRegistryService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*KeyAccessServerRegistry, serviceregistry.HandlerServer) { + ksr := &KeyAccessServerRegistry{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + return ksr, func(ctx context.Context, mux *runtime.ServeMux) error { + return kasr.RegisterKeyAccessServerRegistryServiceHandlerServer(ctx, mux, ksr) } - return kasr.RegisterKeyAccessServerRegistryServiceHandlerServer(ctx, mux, srv) - } + }, }, } } diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index 5598f5880c..f9ca32f53b 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -21,23 +21,23 @@ type NamespacesService struct { //nolint:revive // NamespacesService is a valid logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &namespaces.NamespaceService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - ns := &NamespacesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - - if err := srp.RegisterReadinessCheck("policy", ns.IsReady); err != nil { - srp.Logger.Error("failed to register policy readiness check", slog.String("error", err.Error())) - } - - return ns, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - nsServer, ok := server.(namespaces.NamespaceServiceServer) - if !ok { - return fmt.Errorf("failed to assert server as namespaces.NamespaceServiceServer") +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[NamespacesService] { + return &serviceregistry.Service[NamespacesService]{ + ServiceOptions: serviceregistry.ServiceOptions[NamespacesService]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &namespaces.NamespaceService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*NamespacesService, serviceregistry.HandlerServer) { + ns := &NamespacesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + + if err := srp.RegisterReadinessCheck("policy", ns.IsReady); err != nil { + srp.Logger.Error("failed to register policy readiness check", slog.String("error", err.Error())) } - return namespaces.RegisterNamespaceServiceHandlerServer(ctx, mux, nsServer) - } + + return ns, func(ctx context.Context, mux *runtime.ServeMux) error { + return namespaces.RegisterNamespaceServiceHandlerServer(ctx, mux, ns) + } + }, }, } } diff --git a/service/policy/policy.go b/service/policy/policy.go index 3096f31d20..69db81e86b 100644 --- a/service/policy/policy.go +++ b/service/policy/policy.go @@ -19,25 +19,21 @@ func init() { Migrations = &migrations.FS } -func NewRegistrations() []serviceregistry.Registration { - registrations := []serviceregistry.Registration{} +func NewRegistrations() []serviceregistry.IService { + registrations := []serviceregistry.IService{} namespace := "policy" dbRegister := serviceregistry.DBRegister{ Required: true, Migrations: Migrations, } - for _, r := range []serviceregistry.Registration{ - attributes.NewRegistration(), - namespaces.NewRegistration(), - resourcemapping.NewRegistration(), - subjectmapping.NewRegistration(), - kasregistry.NewRegistration(), - unsafe.NewRegistration(), - } { - r.Namespace = namespace - r.DB = dbRegister - registrations = append(registrations, r) - } + registrations = append(registrations, []serviceregistry.IService{ + attributes.NewRegistration(namespace, dbRegister), + namespaces.NewRegistration(namespace, dbRegister), + resourcemapping.NewRegistration(namespace, dbRegister), + subjectmapping.NewRegistration(namespace, dbRegister), + kasregistry.NewRegistration(namespace, dbRegister), + unsafe.NewRegistration(namespace, dbRegister), + }...) return registrations } diff --git a/service/policy/resourcemapping/resource_mapping.go b/service/policy/resourcemapping/resource_mapping.go index 58d4f273cc..54e732172e 100644 --- a/service/policy/resourcemapping/resource_mapping.go +++ b/service/policy/resourcemapping/resource_mapping.go @@ -2,7 +2,6 @@ package resourcemapping import ( "context" - "fmt" "log/slog" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -21,17 +20,18 @@ type ResourceMappingService struct { //nolint:revive // ResourceMappingService i logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &resourcemapping.ResourceMappingService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &ResourceMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, s any) error { - server, ok := s.(resourcemapping.ResourceMappingServiceServer) - if !ok { - return fmt.Errorf("failed to assert server as resourcemapping.ResourceMappingServiceServer") +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[ResourceMappingService] { + return &serviceregistry.Service[ResourceMappingService]{ + ServiceOptions: serviceregistry.ServiceOptions[ResourceMappingService]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &resourcemapping.ResourceMappingService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*ResourceMappingService, serviceregistry.HandlerServer) { + rm := &ResourceMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + return rm, func(ctx context.Context, mux *runtime.ServeMux) error { + return resourcemapping.RegisterResourceMappingServiceHandlerServer(ctx, mux, rm) } - return resourcemapping.RegisterResourceMappingServiceHandlerServer(ctx, mux, server) - } + }, }, } } diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index 3413ae4e4f..a44842a181 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -2,7 +2,6 @@ package subjectmapping import ( "context" - "fmt" "log/slog" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -21,17 +20,18 @@ type SubjectMappingService struct { //nolint:revive // SubjectMappingService is logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &sm.SubjectMappingService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &SubjectMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, s any) error { - server, ok := s.(sm.SubjectMappingServiceServer) - if !ok { - return fmt.Errorf("failed to assert server as sm.SubjectMappingServiceServer") +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[SubjectMappingService] { + return &serviceregistry.Service[SubjectMappingService]{ + ServiceOptions: serviceregistry.ServiceOptions[SubjectMappingService]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &sm.SubjectMappingService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*SubjectMappingService, serviceregistry.HandlerServer) { + smSvc := &SubjectMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + return smSvc, func(ctx context.Context, mux *runtime.ServeMux) error { + return sm.RegisterSubjectMappingServiceHandlerServer(ctx, mux, smSvc) } - return sm.RegisterSubjectMappingServiceHandlerServer(ctx, mux, server) - } + }, }, } } diff --git a/service/policy/unsafe/unsafe.go b/service/policy/unsafe/unsafe.go index bfade319f3..ed1f2700ec 100644 --- a/service/policy/unsafe/unsafe.go +++ b/service/policy/unsafe/unsafe.go @@ -2,7 +2,6 @@ package unsafe import ( "context" - "fmt" "log/slog" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -21,16 +20,18 @@ type UnsafeService struct { //nolint:revive // UnsafeService is a valid name for logger *logger.Logger } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - ServiceDesc: &unsafe.UnsafeService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &UnsafeService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - if srv, ok := server.(unsafe.UnsafeServiceServer); ok { - return unsafe.RegisterUnsafeServiceHandlerServer(ctx, mux, srv) +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[UnsafeService] { + return &serviceregistry.Service[UnsafeService]{ + ServiceOptions: serviceregistry.ServiceOptions[UnsafeService]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &unsafe.UnsafeService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*UnsafeService, serviceregistry.HandlerServer) { + unsafeSvc := &UnsafeService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} + return unsafeSvc, func(ctx context.Context, mux *runtime.ServeMux) error { + return unsafe.RegisterUnsafeServiceHandlerServer(ctx, mux, unsafeSvc) } - return fmt.Errorf("failed to assert server as unsafe.UnsafeServiceServer") - } + }, }, } } diff --git a/service/wellknownconfiguration/wellknown_configuration.go b/service/wellknownconfiguration/wellknown_configuration.go index dbfe045a10..bbfb34e3ad 100644 --- a/service/wellknownconfiguration/wellknown_configuration.go +++ b/service/wellknownconfiguration/wellknown_configuration.go @@ -35,17 +35,17 @@ func RegisterConfiguration(namespace string, config any) error { return nil } -func NewRegistration() serviceregistry.Registration { - return serviceregistry.Registration{ - Namespace: "wellknown", - ServiceDesc: &wellknown.WellKnownService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (any, serviceregistry.HandlerServer) { - return &WellKnownService{logger: srp.Logger}, func(ctx context.Context, mux *runtime.ServeMux, server any) error { - if srv, ok := server.(wellknown.WellKnownServiceServer); ok { - return wellknown.RegisterWellKnownServiceHandlerServer(ctx, mux, srv) +func NewRegistration() *serviceregistry.Service[WellKnownService] { + return &serviceregistry.Service[WellKnownService]{ + ServiceOptions: serviceregistry.ServiceOptions[WellKnownService]{ + Namespace: "wellknown", + ServiceDesc: &wellknown.WellKnownService_ServiceDesc, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (*WellKnownService, serviceregistry.HandlerServer) { + wk := &WellKnownService{logger: srp.Logger} + return wk, func(ctx context.Context, mux *runtime.ServeMux) error { + return wellknown.RegisterWellKnownServiceHandlerServer(ctx, mux, wk) } - return fmt.Errorf("failed to assert server as WellKnownServiceServer") - } + }, }, } } From 5886d1d7ee8d57d24c4ed3b1fff63a6ba5e89e5e Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 19:09:35 -0500 Subject: [PATCH 05/37] fix linter issues --- .../entityresolution/claims/claims_entity_resolution.go | 2 +- .../keycloak/keycloak_entity_resolution.go | 2 +- service/pkg/server/services.go | 2 +- service/pkg/serviceregistry/serviceregistry.go | 9 ++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/service/entityresolution/claims/claims_entity_resolution.go b/service/entityresolution/claims/claims_entity_resolution.go index 6fea8a8d6f..07ca34fd4a 100644 --- a/service/entityresolution/claims/claims_entity_resolution.go +++ b/service/entityresolution/claims/claims_entity_resolution.go @@ -26,7 +26,7 @@ func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) ( claimsSVC := ClaimsEntityResolutionService{logger: logger} return claimsSVC, func(ctx context.Context, mux *runtime.ServeMux) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, claimsSVC) //nolint:forcetypeassert // allow type assert, following other services + return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, claimsSVC) } } diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index 5c0617a214..16d3ba7e2b 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -61,7 +61,7 @@ func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Lo keycloakSVC := &KeycloakEntityResolutionService{idpConfig: inputIdpConfig, logger: logger} return keycloakSVC, func(ctx context.Context, mux *runtime.ServeMux) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, keycloakSVC) //nolint:forcetypeassert // allow type assert, following other services + return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, keycloakSVC) } } diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index a21e736174..14d4e8f602 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -174,7 +174,7 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS } // Register the service with the gRPC gateway - if err := svc.RegisterHTTPServer(ctx, otdf.Mux); err != nil { //nolint:staticcheck // This is deprecated for internal tracking + if err := svc.RegisterHTTPServer(ctx, otdf.Mux); err != nil { logger.Error("failed to register service to grpc gateway", slog.String("namespace", ns), slog.String("error", err.Error())) return err } diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index 6369dae241..2d9ca082ed 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -80,8 +80,7 @@ type IService interface { // of the service within the instance of the platform. type Service[S any] struct { // Registration - impl *S - handleFunc HandlerServer + impl *S // Started is a flag that indicates whether the service has been started Started bool // Close is a function that can be called to close the service @@ -150,7 +149,7 @@ func (s *Service[S]) Start(ctx context.Context, params RegistrationParams) error ) } - s.impl, s.handleFunc = s.RegisterFunc(params) + s.impl, s.httpHandlerFunc = s.RegisterFunc(params) s.Started = true return nil @@ -173,10 +172,10 @@ func (s *Service[S]) RegisterGRPCServer(server *grpc.Server) error { // It takes a context, a ServeMux, and an implementation function as parameters. // If the service did not register a handler, it returns an error. func (s *Service[S]) RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error { - if s.handleFunc == nil { + if s.httpHandlerFunc == nil { return fmt.Errorf("service did not register a handler") } - return s.handleFunc(ctx, mux) + return s.httpHandlerFunc(ctx, mux) } // namespace represents a namespace in the service registry. From 35553bc891d01621dab63554eb6af50fa5e399b2 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 19:14:32 -0500 Subject: [PATCH 06/37] untrack vscode folder --- .gitignore | 2 +- .vscode/launch.json | 28 ---------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.gitignore b/.gitignore index cda093a8a4..9ecf754dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,7 @@ __pycache__ # Userland files opentdf.yaml -.vscode/settings.json +.vscode/ .idea/ # Generated files diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 80071cc8a1..0000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - // Attach to Air for debugging - "version": "0.2.0", - "configurations": [ - { - "name": "Launch Package", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${fileDirname}", - "env": { - "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true", - "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE": "/var/run/docker.sock" - }, - "showLog": true, - "console": "integratedTerminal" - }, - { - "name": "Attach to Air", - "type": "go", - "debugAdapter": "dlv-dap", - "mode": "remote", - "request": "attach", - "host": "127.0.0.1", - "port": 12345 - } - ] -} \ No newline at end of file From 92a8bcf315303908a25d28afb3a472702d0b7951 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Mon, 4 Nov 2024 19:27:48 -0500 Subject: [PATCH 07/37] regen subjectmappings --- .../subject_mapping.connect.go | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go index 6cdbf3b7d7..ddce801411 100644 --- a/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go +++ b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go @@ -66,22 +66,26 @@ const ( // SubjectMappingServiceDeleteSubjectConditionSetProcedure is the fully-qualified name of the // SubjectMappingService's DeleteSubjectConditionSet RPC. SubjectMappingServiceDeleteSubjectConditionSetProcedure = "/policy.subjectmapping.SubjectMappingService/DeleteSubjectConditionSet" + // SubjectMappingServiceDeleteAllUnmappedSubjectConditionSetsProcedure is the fully-qualified name + // of the SubjectMappingService's DeleteAllUnmappedSubjectConditionSets RPC. + SubjectMappingServiceDeleteAllUnmappedSubjectConditionSetsProcedure = "/policy.subjectmapping.SubjectMappingService/DeleteAllUnmappedSubjectConditionSets" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - subjectMappingServiceServiceDescriptor = subjectmapping.File_policy_subjectmapping_subject_mapping_proto.Services().ByName("SubjectMappingService") - subjectMappingServiceMatchSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("MatchSubjectMappings") - subjectMappingServiceListSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectMappings") - subjectMappingServiceGetSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectMapping") - subjectMappingServiceCreateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectMapping") - subjectMappingServiceUpdateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectMapping") - subjectMappingServiceDeleteSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectMapping") - subjectMappingServiceListSubjectConditionSetsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectConditionSets") - subjectMappingServiceGetSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectConditionSet") - subjectMappingServiceCreateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectConditionSet") - subjectMappingServiceUpdateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectConditionSet") - subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectConditionSet") + subjectMappingServiceServiceDescriptor = subjectmapping.File_policy_subjectmapping_subject_mapping_proto.Services().ByName("SubjectMappingService") + subjectMappingServiceMatchSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("MatchSubjectMappings") + subjectMappingServiceListSubjectMappingsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectMappings") + subjectMappingServiceGetSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectMapping") + subjectMappingServiceCreateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectMapping") + subjectMappingServiceUpdateSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectMapping") + subjectMappingServiceDeleteSubjectMappingMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectMapping") + subjectMappingServiceListSubjectConditionSetsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("ListSubjectConditionSets") + subjectMappingServiceGetSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("GetSubjectConditionSet") + subjectMappingServiceCreateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("CreateSubjectConditionSet") + subjectMappingServiceUpdateSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("UpdateSubjectConditionSet") + subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteSubjectConditionSet") + subjectMappingServiceDeleteAllUnmappedSubjectConditionSetsMethodDescriptor = subjectMappingServiceServiceDescriptor.Methods().ByName("DeleteAllUnmappedSubjectConditionSets") ) // SubjectMappingServiceClient is a client for the policy.subjectmapping.SubjectMappingService @@ -99,6 +103,7 @@ type SubjectMappingServiceClient interface { CreateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) UpdateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) + DeleteAllUnmappedSubjectConditionSets(context.Context, *connect.Request[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse], error) } // NewSubjectMappingServiceClient constructs a client for the @@ -178,22 +183,29 @@ func NewSubjectMappingServiceClient(httpClient connect.HTTPClient, baseURL strin connect.WithSchema(subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor), connect.WithClientOptions(opts...), ), + deleteAllUnmappedSubjectConditionSets: connect.NewClient[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest, subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse]( + httpClient, + baseURL+SubjectMappingServiceDeleteAllUnmappedSubjectConditionSetsProcedure, + connect.WithSchema(subjectMappingServiceDeleteAllUnmappedSubjectConditionSetsMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // subjectMappingServiceClient implements SubjectMappingServiceClient. type subjectMappingServiceClient struct { - matchSubjectMappings *connect.Client[subjectmapping.MatchSubjectMappingsRequest, subjectmapping.MatchSubjectMappingsResponse] - listSubjectMappings *connect.Client[subjectmapping.ListSubjectMappingsRequest, subjectmapping.ListSubjectMappingsResponse] - getSubjectMapping *connect.Client[subjectmapping.GetSubjectMappingRequest, subjectmapping.GetSubjectMappingResponse] - createSubjectMapping *connect.Client[subjectmapping.CreateSubjectMappingRequest, subjectmapping.CreateSubjectMappingResponse] - updateSubjectMapping *connect.Client[subjectmapping.UpdateSubjectMappingRequest, subjectmapping.UpdateSubjectMappingResponse] - deleteSubjectMapping *connect.Client[subjectmapping.DeleteSubjectMappingRequest, subjectmapping.DeleteSubjectMappingResponse] - listSubjectConditionSets *connect.Client[subjectmapping.ListSubjectConditionSetsRequest, subjectmapping.ListSubjectConditionSetsResponse] - getSubjectConditionSet *connect.Client[subjectmapping.GetSubjectConditionSetRequest, subjectmapping.GetSubjectConditionSetResponse] - createSubjectConditionSet *connect.Client[subjectmapping.CreateSubjectConditionSetRequest, subjectmapping.CreateSubjectConditionSetResponse] - updateSubjectConditionSet *connect.Client[subjectmapping.UpdateSubjectConditionSetRequest, subjectmapping.UpdateSubjectConditionSetResponse] - deleteSubjectConditionSet *connect.Client[subjectmapping.DeleteSubjectConditionSetRequest, subjectmapping.DeleteSubjectConditionSetResponse] + matchSubjectMappings *connect.Client[subjectmapping.MatchSubjectMappingsRequest, subjectmapping.MatchSubjectMappingsResponse] + listSubjectMappings *connect.Client[subjectmapping.ListSubjectMappingsRequest, subjectmapping.ListSubjectMappingsResponse] + getSubjectMapping *connect.Client[subjectmapping.GetSubjectMappingRequest, subjectmapping.GetSubjectMappingResponse] + createSubjectMapping *connect.Client[subjectmapping.CreateSubjectMappingRequest, subjectmapping.CreateSubjectMappingResponse] + updateSubjectMapping *connect.Client[subjectmapping.UpdateSubjectMappingRequest, subjectmapping.UpdateSubjectMappingResponse] + deleteSubjectMapping *connect.Client[subjectmapping.DeleteSubjectMappingRequest, subjectmapping.DeleteSubjectMappingResponse] + listSubjectConditionSets *connect.Client[subjectmapping.ListSubjectConditionSetsRequest, subjectmapping.ListSubjectConditionSetsResponse] + getSubjectConditionSet *connect.Client[subjectmapping.GetSubjectConditionSetRequest, subjectmapping.GetSubjectConditionSetResponse] + createSubjectConditionSet *connect.Client[subjectmapping.CreateSubjectConditionSetRequest, subjectmapping.CreateSubjectConditionSetResponse] + updateSubjectConditionSet *connect.Client[subjectmapping.UpdateSubjectConditionSetRequest, subjectmapping.UpdateSubjectConditionSetResponse] + deleteSubjectConditionSet *connect.Client[subjectmapping.DeleteSubjectConditionSetRequest, subjectmapping.DeleteSubjectConditionSetResponse] + deleteAllUnmappedSubjectConditionSets *connect.Client[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest, subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse] } // MatchSubjectMappings calls policy.subjectmapping.SubjectMappingService.MatchSubjectMappings. @@ -255,6 +267,12 @@ func (c *subjectMappingServiceClient) DeleteSubjectConditionSet(ctx context.Cont return c.deleteSubjectConditionSet.CallUnary(ctx, req) } +// DeleteAllUnmappedSubjectConditionSets calls +// policy.subjectmapping.SubjectMappingService.DeleteAllUnmappedSubjectConditionSets. +func (c *subjectMappingServiceClient) DeleteAllUnmappedSubjectConditionSets(ctx context.Context, req *connect.Request[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse], error) { + return c.deleteAllUnmappedSubjectConditionSets.CallUnary(ctx, req) +} + // SubjectMappingServiceHandler is an implementation of the // policy.subjectmapping.SubjectMappingService service. type SubjectMappingServiceHandler interface { @@ -270,6 +288,7 @@ type SubjectMappingServiceHandler interface { CreateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.CreateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) UpdateSubjectConditionSet(context.Context, *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest]) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) + DeleteAllUnmappedSubjectConditionSets(context.Context, *connect.Request[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse], error) } // NewSubjectMappingServiceHandler builds an HTTP handler from the service implementation. It @@ -344,6 +363,12 @@ func NewSubjectMappingServiceHandler(svc SubjectMappingServiceHandler, opts ...c connect.WithSchema(subjectMappingServiceDeleteSubjectConditionSetMethodDescriptor), connect.WithHandlerOptions(opts...), ) + subjectMappingServiceDeleteAllUnmappedSubjectConditionSetsHandler := connect.NewUnaryHandler( + SubjectMappingServiceDeleteAllUnmappedSubjectConditionSetsProcedure, + svc.DeleteAllUnmappedSubjectConditionSets, + connect.WithSchema(subjectMappingServiceDeleteAllUnmappedSubjectConditionSetsMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/policy.subjectmapping.SubjectMappingService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case SubjectMappingServiceMatchSubjectMappingsProcedure: @@ -368,6 +393,8 @@ func NewSubjectMappingServiceHandler(svc SubjectMappingServiceHandler, opts ...c subjectMappingServiceUpdateSubjectConditionSetHandler.ServeHTTP(w, r) case SubjectMappingServiceDeleteSubjectConditionSetProcedure: subjectMappingServiceDeleteSubjectConditionSetHandler.ServeHTTP(w, r) + case SubjectMappingServiceDeleteAllUnmappedSubjectConditionSetsProcedure: + subjectMappingServiceDeleteAllUnmappedSubjectConditionSetsHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -420,3 +447,7 @@ func (UnimplementedSubjectMappingServiceHandler) UpdateSubjectConditionSet(conte func (UnimplementedSubjectMappingServiceHandler) DeleteSubjectConditionSet(context.Context, *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest]) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.DeleteSubjectConditionSet is not implemented")) } + +func (UnimplementedSubjectMappingServiceHandler) DeleteAllUnmappedSubjectConditionSets(context.Context, *connect.Request[subjectmapping.DeleteAllUnmappedSubjectConditionSetsRequest]) (*connect.Response[subjectmapping.DeleteAllUnmappedSubjectConditionSetsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("policy.subjectmapping.SubjectMappingService.DeleteAllUnmappedSubjectConditionSets is not implemented")) +} From 95f8da209686263fa68c6830c56de8c0939a04ca Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 11:08:59 -0500 Subject: [PATCH 08/37] show go.mod in protocol/go --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 8052f8372a..2800126d46 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ +protocol/go/go.mod linguist-generated=false protocol/go/** linguist-generated=true -sdkjava/src/main/java/** linguist-generated=true docs/grpc/** linguist-generated=true docs/openapi/** linguist-generated=true service/policy/db/*.sql.go linguist-generated=true From 320b4d2d0524f783dcb93cfb248989677fc790ee Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 11:11:46 -0500 Subject: [PATCH 09/37] try just go.mod --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 2800126d46..9d9a6e2aaa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -protocol/go/go.mod linguist-generated=false +go.mod linguist-generated=false protocol/go/** linguist-generated=true docs/grpc/** linguist-generated=true docs/openapi/** linguist-generated=true From d6998d87dd34e643ba786af191164b2ace2aec46 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 11:17:33 -0500 Subject: [PATCH 10/37] attribute changes --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 9d9a6e2aaa..66d85e6a27 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ go.mod linguist-generated=false -protocol/go/** linguist-generated=true +sdkjava/src/main/java/** linguist-generated=true docs/grpc/** linguist-generated=true docs/openapi/** linguist-generated=true service/policy/db/*.sql.go linguist-generated=true From 515bbb20cc3cb3ba4a143356a3a7260c6dce4151 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 11:24:37 -0500 Subject: [PATCH 11/37] remove javasdk from gitattributes --- .gitattributes | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 66d85e6a27..2669ff174a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,3 @@ -go.mod linguist-generated=false -sdkjava/src/main/java/** linguist-generated=true docs/grpc/** linguist-generated=true docs/openapi/** linguist-generated=true service/policy/db/*.sql.go linguist-generated=true From 9ee727f3c1e036943c1a32f02c314e4a6a65e625 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 13:19:27 -0500 Subject: [PATCH 12/37] update service go.mod --- service/go.mod | 1 + service/go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/service/go.mod b/service/go.mod index 51d945bcaf..3056b9d5f4 100644 --- a/service/go.mod +++ b/service/go.mod @@ -3,6 +3,7 @@ module github.com/opentdf/platform/service go 1.22 require ( + connectrpc.com/connect v1.17.0 github.com/Masterminds/squirrel v1.5.4 github.com/Nerzal/gocloak/v13 v13.9.0 github.com/bmatcuk/doublestar v1.3.4 diff --git a/service/go.sum b/service/go.sum index 98234e6005..e64f2e4af6 100644 --- a/service/go.sum +++ b/service/go.sum @@ -1,5 +1,7 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.1-20240508200655-46a4cf4ba109.1 h1:LEXWFH/xZ5oOWrC3oOtHbUyBdzRWMCPpAQmKC9v05mA= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.1-20240508200655-46a4cf4ba109.1/go.mod h1:XF+P8+RmfdufmIYpGUC+6bF7S+IlmHDEnCrO3OXaUAQ= +connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= +connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= From 683e2e490a73294657ae94bd5e0b404be1365bed Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 5 Nov 2024 14:37:31 -0500 Subject: [PATCH 13/37] feat: connectrpc realip interceptor --- service/internal/server/realip/realip.go | 62 +++++++++++++++++++ service/internal/server/realip/realip_test.go | 57 +++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 service/internal/server/realip/realip.go create mode 100644 service/internal/server/realip/realip_test.go diff --git a/service/internal/server/realip/realip.go b/service/internal/server/realip/realip.go new file mode 100644 index 0000000000..80bd680587 --- /dev/null +++ b/service/internal/server/realip/realip.go @@ -0,0 +1,62 @@ +package realip + +import ( + "context" + "net" + "net/http" + "net/netip" + "strings" + + "connectrpc.com/connect" +) + +const ( + XRealIP = "X-Real-IP" + XForwardedFor = "X-Forwarded-For" + TrueClientIP = "True-Client-Ip" +) + +type clientIP struct{} + +func ConnectRealIPUnaryInterceptor() connect.UnaryInterceptorFunc { + interceptor := func(next connect.UnaryFunc) connect.UnaryFunc { + return connect.UnaryFunc(func( + ctx context.Context, + req connect.AnyRequest, + ) (connect.AnyResponse, error) { + ip := getIP(ctx, req.Peer(), req.Header()) + + ctx = context.WithValue(ctx, clientIP{}, ip) + + return next(ctx, req) + }) + } + return connect.UnaryInterceptorFunc(interceptor) +} + +func getIP(_ context.Context, peer connect.Peer, headers http.Header) net.IP { + for _, header := range []string{XRealIP, XForwardedFor, TrueClientIP} { + if ip := headers.Get(header); ip != "" { + ips := strings.Split(ip, ",") + if ips[0] == "" || net.ParseIP(ips[0]) == nil { + continue + } + return net.ParseIP(ips[0]) + } + } + + ip, err := netip.ParseAddrPort(peer.Addr) + if err != nil { + return net.IP{} + } + + return net.IP(ip.Addr().AsSlice()) +} + +func FromContext(ctx context.Context) net.IP { + ip, ok := ctx.Value(clientIP{}).(net.IP) + if !ok { + return net.IP{} + } + return ip +} diff --git a/service/internal/server/realip/realip_test.go b/service/internal/server/realip/realip_test.go new file mode 100644 index 0000000000..c3162beba5 --- /dev/null +++ b/service/internal/server/realip/realip_test.go @@ -0,0 +1,57 @@ +package realip + +import ( + "context" + "net/http" + "testing" + + "connectrpc.com/connect" + "github.com/stretchr/testify/suite" +) + +type RealIPTestSuite struct { + suite.Suite +} + +func TestRealIPSuite(t *testing.T) { + suite.Run(t, new(RealIPTestSuite)) +} + +func (s *RealIPTestSuite) Test_getIP_from_x_real_ip_header() { + ip := "1.1.1.1" + peer := connect.Peer{} + + headers := http.Header{} + headers.Add(XRealIP, ip) + foundIP := getIP(context.Background(), peer, headers) + s.Equal(ip, foundIP.String()) +} + +func (s *RealIPTestSuite) Test_getIP_from_x_forwarded_for_header() { + ip := "1.1.1.1" + peer := connect.Peer{} + + headers := http.Header{} + headers.Add(XForwardedFor, ip) + foundIP := getIP(context.Background(), peer, headers) + s.Equal(ip, foundIP.String()) +} + +func (s *RealIPTestSuite) Test_getIP_from_true_client_ip_header() { + ip := "1.1.1.1" + peer := connect.Peer{} + + headers := http.Header{} + headers.Add(TrueClientIP, ip) + foundIP := getIP(context.Background(), peer, headers) + s.Equal(ip, foundIP.String()) +} + +func (s *RealIPTestSuite) Test_getIP_from_peer() { + ip := "1.1.1.1" + peer := connect.Peer{Addr: ip + ":1234"} + + headers := http.Header{} + foundIP := getIP(context.Background(), peer, headers) + s.Equal(ip, foundIP.String()) +} From cf78af96b80b3b98216d2c01f58dfbc13db24d48 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 12:21:51 -0500 Subject: [PATCH 14/37] start connectrpc implemenation --- service/internal/server/server.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/service/internal/server/server.go b/service/internal/server/server.go index f923730e76..693fbd40c5 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "connectrpc.com/connect" "github.com/bufbuild/protovalidate-go" "github.com/go-chi/cors" protovalidate_middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate" @@ -104,13 +105,21 @@ type CORSConfig struct { MaxAge int `mapstructure:"maxage" json:"maxage" default:"3600"` } +type ConnectRPC struct { + Mux *http.ServeMux + Interceptors []connect.HandlerOption + ServiceReflection []string +} + type OpenTDFServer struct { - AuthN *auth.Authentication - Mux *runtime.ServeMux - HTTPServer *http.Server - GRPCServer *grpc.Server - GRPCInProcess *inProcessServer - CryptoProvider security.CryptoProvider + AuthN *auth.Authentication + Mux *runtime.ServeMux + HTTPServer *http.Server + GRPCServer *grpc.Server + GRPCInProcess *inProcessServer + ConnectRPCInProcess *ConnectRPC + ConnectRPC *ConnectRPC + CryptoProvider security.CryptoProvider logger *logger.Logger } @@ -133,6 +142,11 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err var ( authN *auth.Authentication err error + // Two muxes are needed for the connect rpc server. One for the in process server and one for the http server. + connectRPCIPCMux = http.NewServeMux() + connectRPCMux = http.NewServeMux() + connectRPCIPCInterceptors []connect.HandlerOption + connectRPCInterceptors []connect.HandlerOption ) // Add authN interceptor From 4bda5980f00e761af497a1282e399719059db498 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 12:30:28 -0500 Subject: [PATCH 15/37] fix keycloak spelling in comment --- service/entityresolution/entityresolution.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/entityresolution/entityresolution.go b/service/entityresolution/entityresolution.go index 44537c8009..d66c2dc6b4 100644 --- a/service/entityresolution/entityresolution.go +++ b/service/entityresolution/entityresolution.go @@ -37,7 +37,7 @@ func NewRegistration() *serviceregistry.Service[EntityResolution] { return &EntityResolution{EntityResolutionServiceServer: claimsSVC}, claimsHandler } - // Default to keyclaok ERS + // Default to keycloak ERS kcSVC, kcHandler := keycloak.RegisterKeycloakERS(srp.Config, srp.Logger) return &EntityResolution{EntityResolutionServiceServer: kcSVC}, kcHandler }, From 7606479c7b212b2f1ca5b6b1c4dc3a11bb07b5dd Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 18:09:13 -0500 Subject: [PATCH 16/37] save changes --- go.work.sum | 1 + sdk/audit/context_keys.go | 4 + service/authorization/authorization.go | 86 ++-- service/authorization/authorization_test.go | 390 ++++++++++-------- .../claims/claims_entity_resolution.go | 19 +- service/entityresolution/entityresolution.go | 20 +- .../keycloak/keycloak_entity_resolution.go | 19 +- service/go.mod | 3 + service/go.sum | 6 + service/health/health.go | 49 ++- service/health/health_test.go | 33 +- service/internal/auth/authn.go | 95 +++-- service/internal/auth/authn_test.go | 71 ++-- service/internal/server/server.go | 248 +++++------ service/kas/access/publicKey.go | 121 +++++- service/kas/access/publicKey_test.go | 53 ++- service/kas/access/rewrap.go | 83 +++- service/kas/access/rewrap_test.go | 9 +- service/kas/kas.go | 22 +- .../logger/audit/contextServerInterceptor.go | 86 ++-- service/logger/audit/utils.go | 13 +- service/pkg/server/services.go | 20 +- service/pkg/server/services_test.go | 16 +- service/pkg/server/start.go | 2 +- service/pkg/server/start_test.go | 11 +- .../pkg/serviceregistry/serviceregistry.go | 39 +- service/policy/attributes/attributes.go | 273 +++++++----- .../kasregistry/key_access_server_registry.go | 125 +++--- service/policy/namespaces/namespaces.go | 88 ++-- .../resourcemapping/resource_mapping.go | 196 +++++---- .../policy/subjectmapping/subject_mapping.go | 137 +++--- service/policy/unsafe/unsafe.go | 92 ++--- .../wellknown_configuration.go | 27 +- 33 files changed, 1388 insertions(+), 1069 deletions(-) diff --git a/go.work.sum b/go.work.sum index b473435b06..3b76f7b56c 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,6 +1,7 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512 h1:SRsZGA7aFnCZETmov57jwPrWuTmaZK6+4R4v5FUe1/c= bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= +buf.build/gen/go/bufbuild/protovalidate-testing/protocolbuffers/go v1.31.0-20230824200732-8bc04916caea.1/go.mod h1:cJ4gQkiW4uPTUTI3+O2862OzMSTnzrFNwMauHLwPDPg= cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= diff --git a/sdk/audit/context_keys.go b/sdk/audit/context_keys.go index 86104c0e93..149b4f1d4c 100644 --- a/sdk/audit/context_keys.go +++ b/sdk/audit/context_keys.go @@ -17,3 +17,7 @@ const ( RequestIPHeaderKey RequestHeader = "x-forwarded-request-ip" ActorIDHeaderKey RequestHeader = "x-forwarded-actor-id" ) + +func (r RequestHeader) String() string { + return string(r) +} diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go index 8031fa7805..bc0872cb02 100644 --- a/service/authorization/authorization.go +++ b/service/authorization/authorization.go @@ -8,15 +8,16 @@ import ( "os" "strings" + "connectrpc.com/connect" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/creasty/defaults" "github.com/go-playground/validator/v10" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/mitchellh/mapstructure" "github.com/open-policy-agent/opa/rego" "github.com/opentdf/platform/protocol/go/authorization" + "github.com/opentdf/platform/protocol/go/authorization/authorizationconnect" "github.com/opentdf/platform/protocol/go/entityresolution" "github.com/opentdf/platform/protocol/go/policy" attr "github.com/opentdf/platform/protocol/go/policy/attributes" @@ -35,7 +36,6 @@ import ( const EntityIDPrefix string = "entity_idx_" type AuthorizationService struct { //nolint:revive // AuthorizationService is a valid name for this struct - authorization.UnimplementedAuthorizationServiceServer sdk *otdf.SDK config Config logger *logger.Logger @@ -54,12 +54,13 @@ type CustomRego struct { Query string `mapstructure:"query" json:"query" default:"data.opentdf.entitlements.attributes"` } -func NewRegistration() *serviceregistry.Service[AuthorizationService] { - return &serviceregistry.Service[AuthorizationService]{ - ServiceOptions: serviceregistry.ServiceOptions[AuthorizationService]{ - Namespace: "authorization", - ServiceDesc: &authorization.AuthorizationService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*AuthorizationService, serviceregistry.HandlerServer) { +func NewRegistration() *serviceregistry.Service[authorizationconnect.AuthorizationServiceHandler] { + return &serviceregistry.Service[authorizationconnect.AuthorizationServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[authorizationconnect.AuthorizationServiceHandler]{ + Namespace: "authorization", + ServiceDesc: &authorization.AuthorizationService_ServiceDesc, + ConnectRPCFunc: authorizationconnect.NewAuthorizationServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (authorizationconnect.AuthorizationServiceHandler, serviceregistry.HandlerServer) { var ( err error entitlementRego []byte @@ -134,9 +135,7 @@ func NewRegistration() *serviceregistry.Service[AuthorizationService] { as.config = *authZCfg - return as, func(ctx context.Context, mux *runtime.ServeMux) error { - return authorization.RegisterAuthorizationServiceHandlerServer(ctx, mux, as) - } + return as, nil }, }, } @@ -148,10 +147,10 @@ func (as AuthorizationService) IsReady(ctx context.Context) error { return nil } -func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *authorization.GetDecisionsByTokenRequest) (*authorization.GetDecisionsByTokenResponse, error) { +func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) { decisionsRequests := []*authorization.DecisionRequest{} // for each token decision request - for _, tdr := range req.GetDecisionRequests() { + for _, tdr := range req.Msg.GetDecisionRequests() { ecResp, err := as.sdk.EntityResoution.CreateEntityChainFromJwt(ctx, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: tdr.GetTokens()}) if err != nil { as.logger.Error("Error calling ERS to get entity chains from jwts") @@ -166,23 +165,29 @@ func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *au }) } - resp, err := as.GetDecisions(ctx, &authorization.GetDecisionsRequest{ - DecisionRequests: decisionsRequests, + resp, err := as.GetDecisions(ctx, &connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: decisionsRequests, + }, }) if err != nil { return nil, err } - return &authorization.GetDecisionsByTokenResponse{DecisionResponses: resp.GetDecisionResponses()}, err + return &connect.Response[authorization.GetDecisionsByTokenResponse]{ + Msg: &authorization.GetDecisionsByTokenResponse{ + DecisionResponses: resp.Msg.GetDecisionResponses(), + }, + }, err } -func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authorization.GetDecisionsRequest) (*authorization.GetDecisionsResponse, error) { +func (as *AuthorizationService) GetDecisions(ctx context.Context, req *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) { as.logger.DebugContext(ctx, "getting decisions") // Temporary canned echo response with permit decision for all requested decision/entity/ra combos rsp := &authorization.GetDecisionsResponse{ DecisionResponses: make([]*authorization.DecisionResponse, 0), } - for _, dr := range req.GetDecisionRequests() { + for _, dr := range req.Msg.GetDecisionRequests() { for _, ra := range dr.GetResourceAttributes() { as.logger.DebugContext(ctx, "getting resource attributes", slog.String("FQNs", strings.Join(ra.GetAttributeValueFqns(), ", "))) @@ -246,9 +251,11 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza // TODO: we should already have the subject mappings here and be able to just use OPA to trim down the known data attr values to the ones matched up with the entities // entities := ec.GetEntities() - req := authorization.GetEntitlementsRequest{ - Entities: entities, - Scope: &allPertinentFqnsRA, + req := connect.Request[authorization.GetEntitlementsRequest]{ + Msg: &authorization.GetEntitlementsRequest{ + Entities: entities, + Scope: &allPertinentFqnsRA, + }, } auditECEntitlements := make([]audit.EntityChainEntitlement, 0) @@ -271,7 +278,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza // TODO this might cause errors if multiple entities dont have ids // currently just adding each entity returned to same list - for idx, e := range ecEntitlements.GetEntitlements() { + for idx, e := range ecEntitlements.Msg.GetEntitlements() { entityID := e.GetEntityId() if entityID == "" { entityID = EntityIDPrefix + fmt.Sprint(idx) @@ -357,7 +364,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza } } } - return rsp, nil + return &connect.Response[authorization.GetDecisionsResponse]{Msg: rsp}, nil } // makeSubMapsByValLookup creates a lookup map of subject mappings by attribute value ID. @@ -438,7 +445,7 @@ func makeScopeMap(scope *authorization.ResourceAttribute) map[string]bool { return scopeMap } -func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *authorization.GetEntitlementsRequest) (*authorization.GetEntitlementsResponse, error) { +func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) { as.logger.DebugContext(ctx, "getting entitlements") attrsRes, err := as.sdk.Attributes.ListAttributes(ctx, &attr.ListAttributesRequest{}) if err != nil { @@ -451,7 +458,7 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *author return nil, status.Error(codes.Internal, "failed to list subject mappings") } // create a lookup map of attribute value FQNs (based on request scope) - scopeMap := makeScopeMap(req.GetScope()) + scopeMap := makeScopeMap(req.Msg.GetScope()) // create a lookup map of subject mappings by attribute value ID subMapsByVal := makeSubMapsByValLookup(subMapsRes.GetSubjectMappings()) // create a lookup map of attribute values by FQN (for rego query) @@ -462,18 +469,18 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *author subjectMappings := avf.GetFqnAttributeValues() as.logger.DebugContext(ctx, fmt.Sprintf("retrieved %d subject mappings", len(subjectMappings))) // TODO: this could probably be moved to proto validation https://github.com/opentdf/platform/issues/1057 - if req.Entities == nil { + if req.Msg.Entities == nil { as.logger.ErrorContext(ctx, "requires entities") return nil, status.Error(codes.InvalidArgument, "requires entities") } rsp := &authorization.GetEntitlementsResponse{ - Entitlements: make([]*authorization.EntityEntitlements, len(req.GetEntities())), + Entitlements: make([]*authorization.EntityEntitlements, len(req.Msg.GetEntities())), } // call ERS on all entities - ersResp, err := as.sdk.EntityResoution.ResolveEntities(ctx, &entityresolution.ResolveEntitiesRequest{Entities: req.GetEntities()}) + ersResp, err := as.sdk.EntityResoution.ResolveEntities(ctx, &entityresolution.ResolveEntitiesRequest{Entities: req.Msg.GetEntities()}) if err != nil { - as.logger.ErrorContext(ctx, "error calling ERS to resolve entities", "entities", req.GetEntities()) + as.logger.ErrorContext(ctx, "error calling ERS to resolve entities", "entities", req.Msg.GetEntities()) return nil, err } @@ -490,31 +497,34 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *author if err != nil { return nil, status.Error(codes.Internal, "failed to evaluate entitlements policy") } + + resp := &connect.Response[authorization.GetEntitlementsResponse]{Msg: rsp} + // If we get no results and no error then we assume that the entity is not entitled to anything if len(results) == 0 { as.logger.DebugContext(ctx, "no entitlement results") - return rsp, nil + return resp, nil } // I am not sure how we would end up with multiple results but lets return an empty entitlement set for now if len(results) > 1 { as.logger.WarnContext(ctx, "multiple entitlement results", slog.Any("results", results)) - return rsp, nil + return resp, nil } // If we get no expressions then we assume that the entity is not entitled to anything if len(results[0].Expressions) == 0 { as.logger.WarnContext(ctx, "no entitlement expressions", slog.Any("results", results)) - return rsp, nil + return resp, nil } resultsEntitlements, entitlementsMapOk := results[0].Expressions[0].Value.(map[string]interface{}) if !entitlementsMapOk { as.logger.ErrorContext(ctx, "entitlements is not a map[string]interface", slog.Any("value", resultsEntitlements)) - return rsp, nil + return resp, nil } as.logger.DebugContext(ctx, "rego results", slog.Any("results", results)) - for idx, entity := range req.GetEntities() { + for idx, entity := range req.Msg.GetEntities() { // Ensure the entity has an ID entityID := entity.GetId() if entityID == "" { @@ -524,7 +534,7 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *author entityEntitlements, valueListOk := resultsEntitlements[entityID].([]interface{}) if !valueListOk { as.logger.ErrorContext(ctx, "entitlements is not a map[string]interface", slog.Any("value", resultsEntitlements)) - return rsp, nil + return resp, nil } // map for attributes for optional comprehensive @@ -541,20 +551,20 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *author continue } // if comprehensive and a hierarchy attribute is entitled then add the lower entitlements - if req.GetWithComprehensiveHierarchy() { + if req.Msg.GetWithComprehensiveHierarchy() { entitlements = getComprehensiveHierarchy(attributesMap, avf, entitlement, as, entitlements) } // Add entitlement to entitlements array entitlements[valueIDX] = entitlement } // Update the entity with its entitlements - rsp.Entitlements[idx] = &authorization.EntityEntitlements{ + resp.Msg.Entitlements[idx] = &authorization.EntityEntitlements{ EntityId: entity.GetId(), AttributeValueFqns: entitlements, } } - return rsp, nil + return resp, nil } func retrieveAttributeDefinitions(ctx context.Context, ra *authorization.ResourceAttribute, sdk *otdf.SDK) (map[string]*attr.GetAttributeValuesByFqnsResponse_AttributeAndValue, error) { diff --git a/service/authorization/authorization_test.go b/service/authorization/authorization_test.go index 59940559fe..e64f849b78 100644 --- a/service/authorization/authorization_test.go +++ b/service/authorization/authorization_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + "connectrpc.com/connect" "github.com/open-policy-agent/opa/rego" "github.com/opentdf/platform/protocol/go/authorization" "github.com/opentdf/platform/protocol/go/entityresolution" @@ -63,6 +64,7 @@ func (*mySubjectMappingClient) ListSubjectMappings(_ context.Context, _ *sm.List func (*myERSClient) CreateEntityChainFromJwt(_ context.Context, _ *entityresolution.CreateEntityChainFromJwtRequest, _ ...grpc.CallOption) (*entityresolution.CreateEntityChainFromJwtResponse, error) { return &createEntityChainResp, nil } + func (*myERSClient) ResolveEntities(_ context.Context, _ *entityresolution.ResolveEntitiesRequest, _ ...grpc.CallOption) (*entityresolution.ResolveEntitiesResponse, error) { return &resolveEntitiesResp, nil } @@ -177,13 +179,14 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -200,27 +203,34 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) { require.NoError(t, err) // set the request - req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{ - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ + req := connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: []*authorization.DecisionRequest{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1}}, }, }, }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1}}, - }, }, - }} + } - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } resp, err := as.GetDecisions(ctxb, &req) @@ -228,42 +238,46 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) { assert.NotNil(t, resp) // one entitlement, one attribute value throughout - slog.Debug(resp.String()) - assert.Len(t, resp.GetDecisionResponses(), 1) - assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.GetDecisionResponses()[0].GetDecision()) + slog.Debug(resp.Msg.String()) + assert.Len(t, resp.Msg.GetDecisionResponses(), 1) + assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.Msg.GetDecisionResponses()[0].GetDecision()) // run again with two attribute values throughout // set the request - req = authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{ - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ + req = connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: []*authorization.DecisionRequest{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1}}, }, }, - }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1}}, - }, - }, - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1, mockFqn2}}, }, }, }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1, mockFqn2}}, - }, }, - }} + } attrDef.Values = append(attrDef.Values, &policy.Value{ Value: mockAttrValue2, }) @@ -288,9 +302,9 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) { resp, err = as.GetDecisions(ctxb, &req) require.NoError(t, err) - assert.Len(t, resp.GetDecisionResponses(), 2) - assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.GetDecisionResponses()[0].GetDecision()) - assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.GetDecisionResponses()[1].GetDecision()) + assert.Len(t, resp.Msg.GetDecisionResponses(), 2) + assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.Msg.GetDecisionResponses()[0].GetDecision()) + assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.Msg.GetDecisionResponses()[1].GetDecision()) } func Test_GetDecisions_AllOf_Fail(t *testing.T) { @@ -331,32 +345,37 @@ func Test_GetDecisions_AllOf_Fail(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } // set the request - req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{ - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ + req := connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: []*authorization.DecisionRequest{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1, mockFqn2}}, }, }, }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1, mockFqn2}}, - }, }, - }} + } ctxb := context.Background() @@ -371,10 +390,13 @@ func Test_GetDecisions_AllOf_Fail(t *testing.T) { prepared, err := testrego.PrepareForEval(ctxb) require.NoError(t, err) - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } resp, err := as.GetDecisions(ctxb, &req) @@ -384,9 +406,9 @@ func Test_GetDecisions_AllOf_Fail(t *testing.T) { // NOTE: there should be two decision responses, one for each data attribute value, but authorization service // only responds with one permit/deny at the moment // entitlements only contain the first FQN, so we have a deny decision - as.logger.Debug(resp.String()) - assert.Len(t, resp.GetDecisionResponses(), 1) - assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.GetDecisionResponses()[0].GetDecision()) + as.logger.Debug(resp.Msg.String()) + assert.Len(t, resp.Msg.GetDecisionResponses(), 1) + assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.Msg.GetDecisionResponses()[0].GetDecision()) } // Subject entitled and environment entity not entitled -- still pass @@ -421,13 +443,14 @@ func Test_GetDecisionsAllOfWithEnvironmental_Pass(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -444,28 +467,35 @@ func Test_GetDecisionsAllOfWithEnvironmental_Pass(t *testing.T) { require.NoError(t, err) // set the request - req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{ - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ + req := connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: []*authorization.DecisionRequest{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}, - {Id: "e2", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}, + {Id: "e2", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1}}, }, }, }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1}}, - }, }, - }} + } - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } resp, err := as.GetDecisions(ctxb, &req) @@ -473,9 +503,9 @@ func Test_GetDecisionsAllOfWithEnvironmental_Pass(t *testing.T) { assert.NotNil(t, resp) // one entitlement, one attribute value throughout - slog.Debug(resp.String()) - assert.Len(t, resp.GetDecisionResponses(), 1) - assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.GetDecisionResponses()[0].GetDecision()) + slog.Debug(resp.Msg.String()) + assert.Len(t, resp.Msg.GetDecisionResponses(), 1) + assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.Msg.GetDecisionResponses()[0].GetDecision()) } // Subject not entitled and environment entity entitled -- still fail @@ -510,13 +540,14 @@ func Test_GetDecisionsAllOfWithEnvironmental_Fail(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -533,28 +564,35 @@ func Test_GetDecisionsAllOfWithEnvironmental_Fail(t *testing.T) { require.NoError(t, err) // set the request - req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{ - { - Actions: []*policy.Action{}, - EntityChains: []*authorization.EntityChain{ + req := connect.Request[authorization.GetDecisionsRequest]{ + Msg: &authorization.GetDecisionsRequest{ + DecisionRequests: []*authorization.DecisionRequest{ { - Id: "ec1", - Entities: []*authorization.Entity{ - {Id: "e2", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}, - {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + Actions: []*policy.Action{}, + EntityChains: []*authorization.EntityChain{ + { + Id: "ec1", + Entities: []*authorization.Entity{ + {Id: "e2", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}, + {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT}, + }, + }, + }, + ResourceAttributes: []*authorization.ResourceAttribute{ + {AttributeValueFqns: []string{mockFqn1}}, }, }, }, - ResourceAttributes: []*authorization.ResourceAttribute{ - {AttributeValueFqns: []string{mockFqn1}}, - }, }, - }} + } - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } resp, err := as.GetDecisions(ctxb, &req) @@ -562,9 +600,9 @@ func Test_GetDecisionsAllOfWithEnvironmental_Fail(t *testing.T) { assert.NotNil(t, resp) // one entitlement, one attribute value throughout - slog.Debug(resp.String()) - assert.Len(t, resp.GetDecisionResponses(), 1) - assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.GetDecisionResponses()[0].GetDecision()) + slog.Debug(resp.Msg.String()) + assert.Len(t, resp.Msg.GetDecisionResponses(), 1) + assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.Msg.GetDecisionResponses()[0].GetDecision()) } func Test_GetEntitlementsSimple(t *testing.T) { @@ -600,13 +638,14 @@ func Test_GetEntitlementsSimple(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -622,23 +661,28 @@ func Test_GetEntitlementsSimple(t *testing.T) { prepared, err := rego.PrepareForEval(ctxb) require.NoError(t, err) - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } - req := authorization.GetEntitlementsRequest{ - Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, - Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}}, + req := connect.Request[authorization.GetEntitlementsRequest]{ + Msg: &authorization.GetEntitlementsRequest{ + Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, + Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}}, + }, } resp, err := as.GetEntitlements(ctxb, &req) require.NoError(t, err) assert.NotNil(t, resp) - assert.Len(t, resp.GetEntitlements(), 1) - assert.Equal(t, "e1", resp.GetEntitlements()[0].GetEntityId()) - assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1"}, resp.GetEntitlements()[0].GetAttributeValueFqns()) + assert.Len(t, resp.Msg.GetEntitlements(), 1) + assert.Equal(t, "e1", resp.Msg.GetEntitlements()[0].GetEntityId()) + assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1"}, resp.Msg.GetEntitlements()[0].GetAttributeValueFqns()) } func Test_GetEntitlementsFqnCasing(t *testing.T) { @@ -667,13 +711,14 @@ func Test_GetEntitlementsFqnCasing(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -689,18 +734,23 @@ func Test_GetEntitlementsFqnCasing(t *testing.T) { prepared, err := rego.PrepareForEval(ctxb) require.NoError(t, err) - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } - req := authorization.GetEntitlementsRequest{ - Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, - // Using mixed case here - Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/VaLuE1"}}, + req := connect.Request[authorization.GetEntitlementsRequest]{ + Msg: &authorization.GetEntitlementsRequest{ + Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, + // Using mixed case here + Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/VaLuE1"}}, + }, } - for fqn := range makeScopeMap(req.GetScope()) { + for fqn := range makeScopeMap(req.Msg.GetScope()) { assert.Equal(t, fqn, strings.ToLower(fqn)) } @@ -708,9 +758,9 @@ func Test_GetEntitlementsFqnCasing(t *testing.T) { require.NoError(t, err) assert.NotNil(t, resp) - assert.Len(t, resp.GetEntitlements(), 1) - assert.Equal(t, "e1", resp.GetEntitlements()[0].GetEntityId()) - assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1"}, resp.GetEntitlements()[0].GetAttributeValueFqns()) + assert.Len(t, resp.Msg.GetEntitlements(), 1) + assert.Equal(t, "e1", resp.Msg.GetEntitlements()[0].GetEntityId()) + assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1"}, resp.Msg.GetEntitlements()[0].GetAttributeValueFqns()) } func Test_GetEntitlementsWithComprehensiveHierarchy(t *testing.T) { @@ -747,13 +797,14 @@ func Test_GetEntitlementsWithComprehensiveHierarchy(t *testing.T) { } userStruct, _ := structpb.NewStruct(userRepresentation) resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{ - EntityRepresentations: []*entityresolution.EntityRepresentation{{ - OriginalId: "e1", - AdditionalProps: []*structpb.Struct{ - userStruct, + EntityRepresentations: []*entityresolution.EntityRepresentation{ + { + OriginalId: "e1", + AdditionalProps: []*structpb.Struct{ + userStruct, + }, }, }, - }, } ctxb := context.Background() @@ -768,25 +819,30 @@ func Test_GetEntitlementsWithComprehensiveHierarchy(t *testing.T) { // Run evaluation. prepared, err := rego.PrepareForEval(ctxb) require.NoError(t, err) - as := AuthorizationService{logger: logger, sdk: &otdf.SDK{ - SubjectMapping: &mySubjectMappingClient{}, - Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}}, - eval: prepared} + as := AuthorizationService{ + logger: logger, sdk: &otdf.SDK{ + SubjectMapping: &mySubjectMappingClient{}, + Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}, + }, + eval: prepared, + } withHierarchy := true - req := authorization.GetEntitlementsRequest{ - Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, - Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}}, - WithComprehensiveHierarchy: &withHierarchy, + req := connect.Request[authorization.GetEntitlementsRequest]{ + Msg: &authorization.GetEntitlementsRequest{ + Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}}, + Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}}, + WithComprehensiveHierarchy: &withHierarchy, + }, } resp, err := as.GetEntitlements(ctxb, &req) require.NoError(t, err) assert.NotNil(t, resp) - assert.Len(t, resp.GetEntitlements(), 1) - assert.Equal(t, "e1", resp.GetEntitlements()[0].GetEntityId()) - assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1", "https://www.example.org/attr/foo/value/value2"}, resp.GetEntitlements()[0].GetAttributeValueFqns()) + assert.Len(t, resp.Msg.GetEntitlements(), 1) + assert.Equal(t, "e1", resp.Msg.GetEntitlements()[0].GetEntityId()) + assert.Equal(t, []string{"https://www.example.org/attr/foo/value/value1", "https://www.example.org/attr/foo/value/value2"}, resp.Msg.GetEntitlements()[0].GetAttributeValueFqns()) } func TestFqnBuilder(t *testing.T) { diff --git a/service/entityresolution/claims/claims_entity_resolution.go b/service/entityresolution/claims/claims_entity_resolution.go index 07ca34fd4a..0a76864573 100644 --- a/service/entityresolution/claims/claims_entity_resolution.go +++ b/service/entityresolution/claims/claims_entity_resolution.go @@ -5,7 +5,7 @@ import ( "fmt" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/opentdf/platform/protocol/go/authorization" "github.com/opentdf/platform/protocol/go/entityresolution" @@ -24,20 +24,17 @@ type ClaimsEntityResolutionService struct { func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) (ClaimsEntityResolutionService, serviceregistry.HandlerServer) { claimsSVC := ClaimsEntityResolutionService{logger: logger} - return claimsSVC, - func(ctx context.Context, mux *runtime.ServeMux) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, claimsSVC) - } + return claimsSVC, nil } -func (s ClaimsEntityResolutionService) ResolveEntities(ctx context.Context, req *entityresolution.ResolveEntitiesRequest) (*entityresolution.ResolveEntitiesResponse, error) { - resp, err := EntityResolution(ctx, req, s.logger) - return &resp, err +func (s ClaimsEntityResolutionService) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { + resp, err := EntityResolution(ctx, req.Msg, s.logger) + return &connect.Response[entityresolution.ResolveEntitiesResponse]{Msg: &resp}, err } -func (s ClaimsEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *entityresolution.CreateEntityChainFromJwtRequest) (*entityresolution.CreateEntityChainFromJwtResponse, error) { - resp, err := CreateEntityChainFromJwt(ctx, req, s.logger) - return &resp, err +func (s ClaimsEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { + resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.logger) + return &connect.Response[entityresolution.CreateEntityChainFromJwtResponse]{Msg: &resp}, err } func CreateEntityChainFromJwt( diff --git a/service/entityresolution/entityresolution.go b/service/entityresolution/entityresolution.go index d66c2dc6b4..4150fe6d2e 100644 --- a/service/entityresolution/entityresolution.go +++ b/service/entityresolution/entityresolution.go @@ -3,6 +3,7 @@ package entityresolution import ( "github.com/mitchellh/mapstructure" "github.com/opentdf/platform/protocol/go/entityresolution" + "github.com/opentdf/platform/protocol/go/entityresolution/entityresolutionconnect" claims "github.com/opentdf/platform/service/entityresolution/claims" keycloak "github.com/opentdf/platform/service/entityresolution/keycloak" "github.com/opentdf/platform/service/pkg/serviceregistry" @@ -18,15 +19,16 @@ const ( ) type EntityResolution struct { - entityresolution.EntityResolutionServiceServer + entityresolutionconnect.EntityResolutionServiceHandler } -func NewRegistration() *serviceregistry.Service[EntityResolution] { - return &serviceregistry.Service[EntityResolution]{ - ServiceOptions: serviceregistry.ServiceOptions[EntityResolution]{ - Namespace: "entityresolution", - ServiceDesc: &entityresolution.EntityResolutionService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*EntityResolution, serviceregistry.HandlerServer) { +func NewRegistration() *serviceregistry.Service[entityresolutionconnect.EntityResolutionServiceHandler] { + return &serviceregistry.Service[entityresolutionconnect.EntityResolutionServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[entityresolutionconnect.EntityResolutionServiceHandler]{ + Namespace: "entityresolution", + ServiceDesc: &entityresolution.EntityResolutionService_ServiceDesc, + ConnectRPCFunc: entityresolutionconnect.NewEntityResolutionServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (entityresolutionconnect.EntityResolutionServiceHandler, serviceregistry.HandlerServer) { var inputConfig ERSConfig if err := mapstructure.Decode(srp.Config, &inputConfig); err != nil { @@ -34,12 +36,12 @@ func NewRegistration() *serviceregistry.Service[EntityResolution] { } if inputConfig.Mode == ClaimsMode { claimsSVC, claimsHandler := claims.RegisterClaimsERS(srp.Config, srp.Logger) - return &EntityResolution{EntityResolutionServiceServer: claimsSVC}, claimsHandler + return EntityResolution{EntityResolutionServiceHandler: claimsSVC}, claimsHandler } // Default to keycloak ERS kcSVC, kcHandler := keycloak.RegisterKeycloakERS(srp.Config, srp.Logger) - return &EntityResolution{EntityResolutionServiceServer: kcSVC}, kcHandler + return EntityResolution{EntityResolutionServiceHandler: kcSVC}, kcHandler }, }, } diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index 16d3ba7e2b..396ec46c34 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -8,8 +8,8 @@ import ( "log/slog" "strings" + "connectrpc.com/connect" "github.com/Nerzal/gocloak/v13" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/mitchellh/mapstructure" "github.com/opentdf/platform/protocol/go/authorization" @@ -59,20 +59,17 @@ func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Lo } logger.Debug("entity_resolution configuration", "config", inputIdpConfig) keycloakSVC := &KeycloakEntityResolutionService{idpConfig: inputIdpConfig, logger: logger} - return keycloakSVC, - func(ctx context.Context, mux *runtime.ServeMux) error { - return entityresolution.RegisterEntityResolutionServiceHandlerServer(ctx, mux, keycloakSVC) - } + return keycloakSVC, nil } -func (s KeycloakEntityResolutionService) ResolveEntities(ctx context.Context, req *entityresolution.ResolveEntitiesRequest) (*entityresolution.ResolveEntitiesResponse, error) { - resp, err := EntityResolution(ctx, req, s.idpConfig, s.logger) - return &resp, err +func (s KeycloakEntityResolutionService) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { + resp, err := EntityResolution(ctx, req.Msg, s.idpConfig, s.logger) + return &connect.Response[entityresolution.ResolveEntitiesResponse]{Msg: &resp}, err } -func (s KeycloakEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *entityresolution.CreateEntityChainFromJwtRequest) (*entityresolution.CreateEntityChainFromJwtResponse, error) { - resp, err := CreateEntityChainFromJwt(ctx, req, s.idpConfig, s.logger) - return &resp, err +func (s KeycloakEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { + resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.idpConfig, s.logger) + return &connect.Response[entityresolution.CreateEntityChainFromJwtResponse]{Msg: &resp}, err } func (c KeycloakConfig) LogValue() slog.Value { diff --git a/service/go.mod b/service/go.mod index 3056b9d5f4..997bbb88a7 100644 --- a/service/go.mod +++ b/service/go.mod @@ -4,6 +4,8 @@ go 1.22 require ( connectrpc.com/connect v1.17.0 + connectrpc.com/grpcreflect v1.2.0 + connectrpc.com/validate v0.1.0 github.com/Masterminds/squirrel v1.5.4 github.com/Nerzal/gocloak/v13 v13.9.0 github.com/bmatcuk/doublestar v1.3.4 @@ -147,6 +149,7 @@ require ( ) require ( + connectrpc.com/grpchealth v1.3.0 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect diff --git a/service/go.sum b/service/go.sum index e64f2e4af6..582e2af098 100644 --- a/service/go.sum +++ b/service/go.sum @@ -2,6 +2,12 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.1-2024050820065 buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.1-20240508200655-46a4cf4ba109.1/go.mod h1:XF+P8+RmfdufmIYpGUC+6bF7S+IlmHDEnCrO3OXaUAQ= connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= +connectrpc.com/grpchealth v1.3.0 h1:FA3OIwAvuMokQIXQrY5LbIy8IenftksTP/lG4PbYN+E= +connectrpc.com/grpchealth v1.3.0/go.mod h1:3vpqmX25/ir0gVgW6RdnCPPZRcR6HvqtXX5RNPmDXHM= +connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U= +connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY= +connectrpc.com/validate v0.1.0 h1:r55jirxMK7HO/xZwVHj3w2XkVFarsUM77ZDy367NtH4= +connectrpc.com/validate v0.1.0/go.mod h1:GU47c9/x/gd+u9wRSPkrQOP46gx2rMN+Wo37EHgI3Ow= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= diff --git a/service/health/health.go b/service/health/health.go index 053da5dffc..22c5273efa 100644 --- a/service/health/health.go +++ b/service/health/health.go @@ -4,7 +4,7 @@ import ( "context" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/grpchealth" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/serviceregistry" "google.golang.org/grpc/codes" @@ -19,60 +19,59 @@ type HealthService struct { //nolint:revive // HealthService is a valid name for logger *logger.Logger } -func NewRegistration() *serviceregistry.Service[HealthService] { - return &serviceregistry.Service[HealthService]{ - ServiceOptions: serviceregistry.ServiceOptions[HealthService]{ - Namespace: "health", - ServiceDesc: &healthpb.Health_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*HealthService, serviceregistry.HandlerServer) { +func NewRegistration() *serviceregistry.Service[grpchealth.Checker] { + return &serviceregistry.Service[grpchealth.Checker]{ + ServiceOptions: serviceregistry.ServiceOptions[grpchealth.Checker]{ + Namespace: "health", + ServiceDesc: &healthpb.Health_ServiceDesc, + ConnectRPCFunc: grpchealth.NewHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (grpchealth.Checker, serviceregistry.HandlerServer) { err := srp.WellKnownConfig("health", map[string]any{ "endpoint": "/healthz", }) if err != nil { srp.Logger.Error("failed to set well-known config", slog.String("error", err.Error())) } - return &HealthService{logger: srp.Logger}, func(_ context.Context, _ *runtime.ServeMux) error { - return nil - } + return HealthService{logger: srp.Logger}, nil }, }, } } -func (s HealthService) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { - if req.GetService() == "" { - return &healthpb.HealthCheckResponse{ - Status: healthpb.HealthCheckResponse_SERVING, +func (s HealthService) Check(ctx context.Context, req *grpchealth.CheckRequest) (*grpchealth.CheckResponse, error) { + if req.Service == "" { + return &grpchealth.CheckResponse{ + Status: grpchealth.StatusServing, }, nil } - switch req.GetService() { + switch req.Service { case "all": for service, check := range serviceHealthChecks { if err := check(ctx); err != nil { s.logger.ErrorContext(ctx, "service is not ready", slog.String("service", service), slog.String("error", err.Error())) - return &healthpb.HealthCheckResponse{ - Status: healthpb.HealthCheckResponse_NOT_SERVING, + return &grpchealth.CheckResponse{ + Status: grpchealth.StatusNotServing, }, nil } } default: - if check, ok := serviceHealthChecks[req.GetService()]; ok { + if check, ok := serviceHealthChecks[req.Service]; ok { if err := check(ctx); err != nil { - s.logger.ErrorContext(ctx, "service is not ready", slog.String("service", req.GetService()), slog.String("error", err.Error())) - return &healthpb.HealthCheckResponse{ - Status: healthpb.HealthCheckResponse_NOT_SERVING, + s.logger.ErrorContext(ctx, "service is not ready", slog.String("service", req.Service), slog.String("error", err.Error())) + return &grpchealth.CheckResponse{ + Status: grpchealth.StatusNotServing, }, nil } } else { - return &healthpb.HealthCheckResponse{ - Status: healthpb.HealthCheckResponse_SERVICE_UNKNOWN, + return &grpchealth.CheckResponse{ + Status: grpchealth.StatusUnknown, }, nil } } - return &healthpb.HealthCheckResponse{ - Status: healthpb.HealthCheckResponse_SERVING, + return &grpchealth.CheckResponse{ + Status: grpchealth.StatusServing, }, nil } diff --git a/service/health/health_test.go b/service/health/health_test.go index db39936c82..f7b45b8357 100644 --- a/service/health/health_test.go +++ b/service/health/health_test.go @@ -2,10 +2,12 @@ package health import ( "context" + "testing" + "connectrpc.com/grpchealth" + "github.com/opentdf/platform/service/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "google.golang.org/grpc/health/grpc_health_v1" ) type HealthCheckSuite struct { @@ -20,6 +22,10 @@ func (s *HealthCheckSuite) TearDownTest() { serviceHealthChecks = make(map[string]func(context.Context) error) } +func TestHealthCheckSuite(t *testing.T) { + suite.Run(t, new(HealthCheckSuite)) +} + func (s *HealthCheckSuite) TestRegisterReadinessCheck() { // TestRegisterReadinessCheck tests the registration of a health check. @@ -67,11 +73,11 @@ func (s *HealthCheckSuite) TestCheck() { s.Require().NoError(err) // Check the health check. - result, err := hs.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{ + result, err := hs.Check(context.Background(), &grpchealth.CheckRequest{ Service: "all", }) s.Require().NoError(err) - s.Equal("SERVING", result.GetStatus().String()) + s.Equal(grpchealth.StatusServing, result.Status) } func (s *HealthCheckSuite) TestCheckServiceUnknown() { @@ -79,28 +85,37 @@ func (s *HealthCheckSuite) TestCheckServiceUnknown() { hs := &HealthService{} // Check the health check. - result, err := hs.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{ + result, err := hs.Check(context.Background(), &grpchealth.CheckRequest{ Service: "unknown", }) s.Require().NoError(err) - s.Equal("SERVICE_UNKNOWN", result.GetStatus().String()) + s.Equal(grpchealth.StatusUnknown, result.Status) } func (s *HealthCheckSuite) TestCheckNotServing() { // TestCheckNotServing tests the health check when a service is not serving. - hs := &HealthService{} + lgr, err := logger.NewLogger(logger.Config{ + Output: "stdout", + Level: "info", + Type: "json", + }) + s.Require().NoError(err) + + hs := &HealthService{ + logger: lgr, + } // Register the health check. - err := RegisterReadinessCheck("failing", func(context.Context) error { + err = RegisterReadinessCheck("failing", func(context.Context) error { return assert.AnError }) s.Require().NoError(err) // Check the health check. - result, err := hs.Check(context.Background(), &grpc_health_v1.HealthCheckRequest{ + result, err := hs.Check(context.Background(), &grpchealth.CheckRequest{ Service: "failing", }) s.Require().NoError(err) - s.Equal("NOT_SERVING", result.GetStatus().String()) + s.Equal(grpchealth.StatusNotServing, result.Status) } diff --git a/service/internal/auth/authn.go b/service/internal/auth/authn.go index b2eb4cc769..556ecdaa85 100644 --- a/service/internal/auth/authn.go +++ b/service/internal/auth/authn.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "connectrpc.com/connect" "github.com/bmatcuk/doublestar" "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jwk" @@ -22,9 +23,7 @@ import ( sdkAudit "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/service/logger" - "google.golang.org/grpc" "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -266,57 +265,57 @@ func (a Authentication) MuxHandler(handler http.Handler) http.Handler { } // UnaryServerInterceptor is a grpc interceptor that verifies the token in the metadata -func (a Authentication) UnaryServerInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { - // Allow health checks and other public routes to pass through - if slices.ContainsFunc(a.publicRoutes, a.isPublicRoute(info.FullMethod)) { //nolint:contextcheck // There is no way to pass a context here - return handler(ctx, req) - } - - // Get the metadata from the context - // The keys within metadata.MD are normalized to lowercase. - // See: https://godoc.org/google.golang.org/grpc/metadata#New - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return nil, status.Error(codes.Unauthenticated, "missing metadata") - } +func (a Authentication) ConnectUnaryServerInterceptor() connect.UnaryInterceptorFunc { + interceptor := func(next connect.UnaryFunc) connect.UnaryFunc { + return connect.UnaryFunc(func( + ctx context.Context, + req connect.AnyRequest, + ) (connect.AnyResponse, error) { + // Interceptor Logic + // Allow health checks and other public routes to pass through + if slices.ContainsFunc(a.publicRoutes, a.isPublicRoute(req.Spec().Procedure)) { //nolint:contextcheck // There is no way to pass a context here + return next(ctx, req) + } - // Verify the token - header := md["authorization"] - if len(header) < 1 { - return nil, status.Error(codes.Unauthenticated, "missing authorization header") - } + header := req.Header()["Authorization"] + if len(header) < 1 { + return nil, status.Error(codes.Unauthenticated, "missing authorization header") + } - // parse the rpc method - p := strings.Split(info.FullMethod, "/") - resource := p[1] + "/" + p[2] - action := getAction(p[2]) + // parse the rpc method + p := strings.Split(req.Spec().Procedure, "/") + resource := p[1] + "/" + p[2] + action := getAction(p[2]) + + token, newCtx, err := a.checkToken( + ctx, + header, + receiverInfo{ + u: req.Spec().Procedure, + m: http.MethodPost, + }, + req.Header()["Dpop"], + ) + if err != nil { + return nil, status.Errorf(codes.Unauthenticated, "unauthenticated") + } - token, newCtx, err := a.checkToken( - ctx, - header, - receiverInfo{ - u: info.FullMethod, - m: http.MethodPost, - }, - md["dpop"], - ) - if err != nil { - return nil, status.Errorf(codes.Unauthenticated, "unauthenticated") - } + // Check if the token is allowed to access the resource + if allowed, err := a.enforcer.Enforce(token, resource, action); err != nil { + if err.Error() == "permission denied" { + a.logger.Warn("permission denied", slog.String("azp", token.Subject()), slog.String("error", err.Error())) + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + return nil, err + } else if !allowed { + a.logger.Warn("permission denied", slog.String("azp", token.Subject())) + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } - // Check if the token is allowed to access the resource - if allowed, err := a.enforcer.Enforce(token, resource, action); err != nil { - if err.Error() == "permission denied" { - a.logger.Warn("permission denied", slog.String("azp", token.Subject()), slog.String("error", err.Error())) - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - return nil, err - } else if !allowed { - a.logger.Warn("permission denied", slog.String("azp", token.Subject())) - return nil, status.Errorf(codes.PermissionDenied, "permission denied") + return next(newCtx, req) + }) } - - return handler(newCtx, req) + return connect.UnaryInterceptorFunc(interceptor) } // getAction returns the action based on the rpc name diff --git a/service/internal/auth/authn_test.go b/service/internal/auth/authn_test.go index 875c818a07..a7d5ed86ae 100644 --- a/service/internal/auth/authn_test.go +++ b/service/internal/auth/authn_test.go @@ -20,12 +20,15 @@ import ( "testing" "time" + "connectrpc.com/connect" "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/opentdf/platform/protocol/go/kas" + "github.com/opentdf/platform/protocol/go/kas/kasconnect" sdkauth "github.com/opentdf/platform/sdk/auth" + "github.com/opentdf/platform/service/internal/server/memhttp" "github.com/opentdf/platform/service/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -33,9 +36,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - "google.golang.org/grpc/test/bufconn" "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -57,24 +58,19 @@ type FakeAccessServiceServer struct { kas.UnimplementedAccessServiceServer } -func (f *FakeAccessServiceServer) Info(context.Context, *kas.InfoRequest) (*kas.InfoResponse, error) { - return &kas.InfoResponse{}, nil +func (f *FakeAccessServiceServer) PublicKey(_ context.Context, _ *connect.Request[kas.PublicKeyRequest]) (*connect.Response[kas.PublicKeyResponse], error) { + return &connect.Response[kas.PublicKeyResponse]{Msg: &kas.PublicKeyResponse{}}, status.Error(codes.Unauthenticated, "no public key for you") } -func (f *FakeAccessServiceServer) PublicKey(context.Context, *kas.PublicKeyRequest) (*kas.PublicKeyResponse, error) { - return &kas.PublicKeyResponse{}, status.Error(codes.Unauthenticated, "no public key for you") +func (f *FakeAccessServiceServer) LegacyPublicKey(_ context.Context, _ *connect.Request[kas.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) { + return &connect.Response[wrapperspb.StringValue]{Msg: &wrapperspb.StringValue{}}, nil } -func (f *FakeAccessServiceServer) LegacyPublicKey(context.Context, *kas.LegacyPublicKeyRequest) (*wrapperspb.StringValue, error) { - return &wrapperspb.StringValue{}, nil -} +func (f *FakeAccessServiceServer) Rewrap(ctx context.Context, req *connect.Request[kas.RewrapRequest]) (*connect.Response[kas.RewrapResponse], error) { + f.accessToken = req.Header()["Authorization"] + f.dpopKey = GetJWKFromContext(ctx, logger.CreateTestLogger()) -func (f *FakeAccessServiceServer) Rewrap(ctx context.Context, _ *kas.RewrapRequest) (*kas.RewrapResponse, error) { - if md, ok := metadata.FromIncomingContext(ctx); ok { - f.accessToken = md.Get("authorization") - f.dpopKey = GetJWKFromContext(ctx, logger.CreateTestLogger()) - } - return &kas.RewrapResponse{}, nil + return &connect.Response[kas.RewrapResponse]{Msg: &kas.RewrapResponse{}}, nil } type FakeTokenSource struct { @@ -230,11 +226,22 @@ func (s *AuthSuite) Test_MuxHandler_When_Authorization_Header_Missing_Expect_Err } func (s *AuthSuite) Test_UnaryServerInterceptor_When_Authorization_Header_Missing_Expect_Error() { - md := metadata.New(map[string]string{}) - ctx := metadata.NewIncomingContext(context.Background(), md) - _, err := s.auth.UnaryServerInterceptor(ctx, "test", &grpc.UnaryServerInfo{ - FullMethod: "/test", - }, nil) + // Create the interceptor + interceptor := s.auth.ConnectUnaryServerInterceptor() + + // Create a dummy next handler + next := func(_ context.Context, _ connect.AnyRequest) (connect.AnyResponse, error) { + // Return a dummy response + return connect.NewResponse[string](nil), nil + } + + // Create a request + req := connect.NewRequest[string](nil) + + _, err := interceptor(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { + return next(ctx, req) + })(context.Background(), req) + s.Require().Error(err) s.Require().ErrorIs(err, status.Error(codes.Unauthenticated, "missing authorization header")) } @@ -430,20 +437,16 @@ func (s *AuthSuite) TestDPoPEndToEnd_GRPC() { signedTok, err := jwt.Sign(tok, jwt.WithKey(jwa.RS256, s.key)) s.Require().NoError(err) - buffer := 1024 * 1024 - listener := bufconn.Listen(buffer) - - server := grpc.NewServer(grpc.UnaryInterceptor(s.auth.UnaryServerInterceptor)) - defer server.Stop() + interceptor := connect.WithInterceptors(s.auth.ConnectUnaryServerInterceptor()) fakeServer := &FakeAccessServiceServer{} - kas.RegisterAccessServiceServer(server, fakeServer) - go func() { - err := server.Serve(listener) - if err != nil { - panic(err) - } - }() + + mux := http.NewServeMux() + path, handler := kasconnect.NewAccessServiceHandler(fakeServer, interceptor) + mux.Handle(path, handler) + + server := memhttp.New(mux) + defer server.Close() addingInterceptor := sdkauth.NewTokenAddingInterceptor(&FakeTokenSource{ key: dpopKey, @@ -452,8 +455,8 @@ func (s *AuthSuite) TestDPoPEndToEnd_GRPC() { MinVersion: tls.VersionTLS12, }) - conn, _ := grpc.NewClient("passthrough://bufconn", grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { - return listener.Dial() + conn, _ := grpc.NewClient("passthrough://bufconn", grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) { + return server.Listener.DialContext(ctx, "tcp", "http://localhost:8080") }), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(addingInterceptor.AddCredentials)) client := kas.NewAccessServiceClient(conn) diff --git a/service/internal/server/server.go b/service/internal/server/server.go index 693fbd40c5..257f9fc4b4 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -9,16 +9,15 @@ import ( "net" "net/http" "net/http/pprof" - "net/netip" + "regexp" + "slices" "strings" "time" "connectrpc.com/connect" - "github.com/bufbuild/protovalidate-go" + "connectrpc.com/grpcreflect" + "connectrpc.com/validate" "github.com/go-chi/cors" - protovalidate_middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" sdkAudit "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/security" @@ -28,10 +27,7 @@ import ( "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "google.golang.org/grpc" - "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" - healthpb "google.golang.org/grpc/health/grpc_health_v1" - "google.golang.org/grpc/reflection" ) const ( @@ -113,11 +109,9 @@ type ConnectRPC struct { type OpenTDFServer struct { AuthN *auth.Authentication - Mux *runtime.ServeMux + ExtraHandlerMux *http.ServeMux HTTPServer *http.Server - GRPCServer *grpc.Server - GRPCInProcess *inProcessServer - ConnectRPCInProcess *ConnectRPC + ConnectRPCInProcess *inProcessServer ConnectRPC *ConnectRPC CryptoProvider security.CryptoProvider @@ -131,22 +125,16 @@ https://github.com/heroku/x/blob/master/grpc/grpcserver/inprocess.go https://github.com/valyala/fasthttp/blob/master/fasthttputil/inmemory_listener.go */ type inProcessServer struct { - ln *memhttp.Server - srv *grpc.Server - + srv *memhttp.Server maxCallRecvMsgSize int maxCallSendMsgSize int + *ConnectRPC } func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, error) { var ( authN *auth.Authentication err error - // Two muxes are needed for the connect rpc server. One for the in process server and one for the http server. - connectRPCIPCMux = http.NewServeMux() - connectRPCMux = http.NewServeMux() - connectRPCIPCInterceptors []connect.HandlerOption - connectRPCInterceptors []connect.HandlerOption ) // Add authN interceptor @@ -166,37 +154,37 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err logger.Warn("disabling authentication. this is deprecated and will be removed. if you are using an IdP without DPoP set `enforceDPoP = false`") } - // Create grpc server and in process grpc server - grpcServer, err := newGrpcServer(config, authN, logger) + connectRPCIpc, err := newConnectRPCIPC() if err != nil { - return nil, fmt.Errorf("failed to create grpc server: %w", err) + return nil, fmt.Errorf("failed to create connect rpc ipc server: %w", err) } - grpcInProcessServer := newGrpcInProcessServer() - - grpcIPCServer := &inProcessServer{ - ln: memhttp.New(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { grpcInProcessServer.ServeHTTP(w, r) })), - srv: grpcInProcessServer, - maxCallRecvMsgSize: config.GRPC.MaxCallRecvMsgSizeBytes, - maxCallSendMsgSize: config.GRPC.MaxCallSendMsgSizeBytes, + connectRPC, err := newConnectRPC(config, authN, logger) + if err != nil { + return nil, fmt.Errorf("failed to create connect rpc server: %w", err) } + // Mux for addtional http handlers + extraHandlerMux := http.NewServeMux() + // Create http server - mux := runtime.NewServeMux( - runtime.WithHealthzEndpoint(healthpb.NewHealthClient(grpcIPCServer.Conn())), - ) - httpServer, err := newHTTPServer(config, mux, authN, grpcServer, logger) + httpServer, err := newHTTPServer(config, connectRPC.Mux, extraHandlerMux, authN, logger) if err != nil { return nil, fmt.Errorf("failed to create http server: %w", err) } o := OpenTDFServer{ - AuthN: authN, - Mux: mux, - HTTPServer: httpServer, - GRPCServer: grpcServer, - GRPCInProcess: grpcIPCServer, - logger: logger, + AuthN: authN, + ExtraHandlerMux: extraHandlerMux, + HTTPServer: httpServer, + ConnectRPC: connectRPC, + ConnectRPCInProcess: &inProcessServer{ + srv: memhttp.New(connectRPCIpc.Mux), + maxCallRecvMsgSize: config.GRPC.MaxCallRecvMsgSizeBytes, + maxCallSendMsgSize: config.GRPC.MaxCallSendMsgSizeBytes, + ConnectRPC: connectRPCIpc, + }, + logger: logger, } // Create crypto provider @@ -210,24 +198,16 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err } // newHTTPServer creates a new http server with the given handler and grpc server -func newHTTPServer(c Config, h http.Handler, a *auth.Authentication, g *grpc.Server, l *logger.Logger) (*http.Server, error) { +func newHTTPServer(c Config, connectRPC http.Handler, extraHandlers http.Handler, a *auth.Authentication, l *logger.Logger) (*http.Server, error) { var ( err error tc *tls.Config writeTimeoutOverride = writeTimeout ) - // Add authN interceptor - // This is needed because we are leveraging RegisterXServiceHandlerServer instead of RegisterXServiceHandlerFromEndpoint - if c.Auth.Enabled { - h = a.MuxHandler(h) - } else { - l.Error("disabling authentication. this is deprecated and will be removed. if you are using an IdP without DPoP set `enforceDPoP = false`") - } - // CORS if c.CORS.Enabled { - h = cors.New(cors.Options{ + corsHandler := cors.New(cors.Options{ AllowOriginFunc: func(_ *http.Request, origin string) bool { for _, allowedOrigin := range c.CORS.AllowedOrigins { if allowedOrigin == "*" { @@ -244,37 +224,71 @@ func newHTTPServer(c Config, h http.Handler, a *auth.Authentication, g *grpc.Ser ExposedHeaders: c.CORS.ExposedHeaders, AllowCredentials: c.CORS.AllowCredentials, MaxAge: c.CORS.MaxAge, - }).Handler(h) + }) + + // Apply CORS to connectRPC and extra handlers + connectRPC = corsHandler.Handler(connectRPC) + extraHandlers = corsHandler.Handler(extraHandlers) + } + + // Add authN interceptor to extra handlers + if c.Auth.Enabled { + extraHandlers = a.MuxHandler(extraHandlers) + } else { + l.Error("disabling authentication. this is deprecated and will be removed. if you are using an IdP without DPoP set `enforceDPoP = false`") } // Enable pprof if c.EnablePprof { - h = pprofHandler(h) + extraHandlers = pprofHandler(extraHandlers) // Need to extend write timeout to collect pprof data. writeTimeoutOverride = 30 * time.Second //nolint:mnd // easier to read that we are overriding the default } - // Add grpc handler - h2 := httpGrpcHandlerFunc(h, g, l) - + var handler http.Handler if !c.TLS.Enabled { - h2 = h2c.NewHandler(h2, &http2.Server{}) + handler = h2c.NewHandler(routeConnectRPCRequests(connectRPC, extraHandlers), &http2.Server{}) } else { tc, err = loadTLSConfig(c.TLS) if err != nil { return nil, fmt.Errorf("failed to load tls config: %w", err) } + handler = routeConnectRPCRequests(connectRPC, extraHandlers) } return &http.Server{ Addr: fmt.Sprintf("%s:%d", c.Host, c.Port), WriteTimeout: writeTimeoutOverride, ReadTimeout: readTimeout, - Handler: h2, + Handler: handler, TLSConfig: tc, }, nil } +var rpcPathRegex = regexp.MustCompile(`^/[\w\.]+\.[\w\.]+/[\w]+$`) + +func routeConnectRPCRequests(connectRPC http.Handler, httpHandler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + contentType := r.Header.Get("Content-Type") + if slices.Contains([]string{ + "application/grpc", + "application/grpc+proto", + "application/grpc+json", + "application/grpc-web", + "application/grpc-web+proto", + "application/grpc-web+json", + "application/proto", + "application/json", + "application/connect+proto", + "application/connect+json", + }, contentType) && r.Method == http.MethodPost && rpcPathRegex.MatchString(r.URL.Path) { + connectRPC.ServeHTTP(w, r) + } else { + httpHandler.ServeHTTP(w, r) + } + }) +} + // ppprof handler func pprofHandler(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -297,91 +311,58 @@ func pprofHandler(h http.Handler) http.Handler { }) } -// httpGrpcHandlerFunc returns a http.Handler that delegates to the grpc server if the request is a grpc request -func httpGrpcHandlerFunc(h http.Handler, g *grpc.Server, l *logger.Logger) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - l.TraceContext(r.Context(), "grpc handler func", slog.Int("proto_major", r.ProtoMajor), slog.String("content_type", r.Header.Get("Content-Type"))) - if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") { - g.ServeHTTP(w, r) - } else { - h.ServeHTTP(w, r) - } - }) -} +func newConnectRPCIPC() (*ConnectRPC, error) { + interceptors := make([]connect.HandlerOption, 0) -func newGrpcInProcessServer() *grpc.Server { - var interceptors []grpc.UnaryServerInterceptor - var serverOptions []grpc.ServerOption - - // Add audit to in process server - interceptors = append(interceptors, audit.ContextServerInterceptor) + // Add protovalidate interceptor + vaidationInterceptor, err := validate.NewInterceptor() + if err != nil { + return nil, fmt.Errorf("failed to create validation interceptor: %w", err) + } - // FIXME: this should probably use existing IP address instead of local? - // Add RealIP interceptor to in process server - // trustedPeers := []netip.Prefix{} // TODO: add this as a config option? - // headers := []string{realip.XForwardedFor, realip.XRealIp} - // interceptors = append(interceptors, realip.UnaryServerInterceptor(trustedPeers, headers)) + interceptors = append(interceptors, connect.WithInterceptors(vaidationInterceptor, audit.ContextServerInterceptor())) - // Add interceptors to server options - serverOptions = append(serverOptions, grpc.ChainUnaryInterceptor(interceptors...)) - return grpc.NewServer(serverOptions...) + return &ConnectRPC{ + Interceptors: interceptors, + Mux: http.NewServeMux(), + }, nil } -// newGrpcServer creates a new grpc server with the given config and authN interceptor -func newGrpcServer(c Config, a *auth.Authentication, logger *logger.Logger) (*grpc.Server, error) { - var i []grpc.UnaryServerInterceptor - var o []grpc.ServerOption +func newConnectRPC(c Config, a *auth.Authentication, logger *logger.Logger) (*ConnectRPC, error) { + interceptors := make([]connect.HandlerOption, 0) - // Enable proto validation - validator, err := protovalidate.New() + // Add protovalidate interceptor + vaidationInterceptor, err := validate.NewInterceptor() if err != nil { - logger.Warn("failed to create proto validator", slog.String("error", err.Error())) + return nil, fmt.Errorf("failed to create validation interceptor: %w", err) } - // Add Audit Unary Server Interceptor - i = append(i, audit.ContextServerInterceptor) + interceptors = append(interceptors, connect.WithInterceptors(vaidationInterceptor, audit.ContextServerInterceptor())) if c.Auth.Enabled { - i = append(i, a.UnaryServerInterceptor) + interceptors = append(interceptors, connect.WithInterceptors(a.ConnectUnaryServerInterceptor())) } else { logger.Error("disabling authentication. this is deprecated and will be removed. if you are using an IdP without DPoP you can set `enforceDpop = false`") } - // Add tls creds if tls is not nil - if c.TLS.Enabled { - c, err := loadTLSConfig(c.TLS) - if err != nil { - return nil, fmt.Errorf("failed to load tls config: %w", err) - } - o = append(o, grpc.Creds(credentials.NewTLS(c))) - } - - // Add proto validation interceptor - i = append(i, protovalidate_middleware.UnaryServerInterceptor(validator)) - - o = append(o, grpc.ChainUnaryInterceptor( - i..., - )) - - // Chain relaip interceptor - trustedPeers := []netip.Prefix{} // TODO: add this as a config option? - headers := []string{realip.XForwardedFor, realip.XRealIp} - - o = append(o, grpc.ChainUnaryInterceptor( - realip.UnaryServerInterceptor(trustedPeers, headers), - )) + return &ConnectRPC{ + Interceptors: interceptors, + Mux: http.NewServeMux(), + }, nil +} - s := grpc.NewServer(o...) +func (s OpenTDFServer) Start() error { + // Add reflection api to connect-rpc + reflector := grpcreflect.NewStaticReflector( + s.ConnectRPC.ServiceReflection..., + ) - // Enable grpc reflection - if c.GRPC.ReflectionEnabled { - reflection.Register(s) - } + s.ConnectRPC.Mux.Handle(grpcreflect.NewHandlerV1(reflector)) + s.ConnectRPC.Mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) - return s, nil -} + s.ConnectRPCInProcess.Mux.Handle(grpcreflect.NewHandlerV1(reflector)) + s.ConnectRPCInProcess.Mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) -func (s OpenTDFServer) Start() error { // Start Http Server ln, err := s.openHTTPServerPort() if err != nil { @@ -389,8 +370,6 @@ func (s OpenTDFServer) Start() error { } go s.startHTTPServer(ln) - // Start In Process Grpc Server - go s.startInProcessGrpcServer() return nil } @@ -404,15 +383,14 @@ func (s OpenTDFServer) Stop() { } s.logger.Info("shutting down in process grpc server") - s.GRPCInProcess.srv.GracefulStop() + if err := s.ConnectRPCInProcess.srv.Shutdown(ctx); err != nil { + s.logger.Error("failed to shutdown in process connect-rpc server", slog.String("error", err.Error())) + return + } s.logger.Info("shutdown complete") } -func (s inProcessServer) GetGrpcServer() *grpc.Server { - return s.srv -} - func (s inProcessServer) Conn() *grpc.ClientConn { var clientInterceptors []grpc.UnaryClientInterceptor @@ -425,7 +403,7 @@ func (s inProcessServer) Conn() *grpc.ClientConn { grpc.MaxCallSendMsgSize(s.maxCallSendMsgSize), ), grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) { - conn, err := s.ln.Listener.DialContext(ctx, "inprocess", "") + conn, err := s.srv.Listener.DialContext(ctx, "tcp", "http://localhost:8080") if err != nil { return nil, fmt.Errorf("failed to dial in process grpc server: %w", err) } @@ -439,14 +417,6 @@ func (s inProcessServer) Conn() *grpc.ClientConn { return conn } -func (s OpenTDFServer) startInProcessGrpcServer() { - s.logger.Info("starting in process grpc server") - if err := s.GRPCInProcess.srv.Serve(s.GRPCInProcess.ln.Listener); err != nil { - s.logger.Error("failed to serve in process grpc", slog.String("error", err.Error())) - panic(err) - } -} - func (s OpenTDFServer) openHTTPServerPort() (net.Listener, error) { addr := s.HTTPServer.Addr if addr == "" { diff --git a/service/kas/access/publicKey.go b/service/kas/access/publicKey.go index 19dde9b9dc..28fbbcc252 100644 --- a/service/kas/access/publicKey.go +++ b/service/kas/access/publicKey.go @@ -7,11 +7,15 @@ import ( "crypto/x509" "encoding/pem" "errors" + "fmt" + "net/http" + "connectrpc.com/connect" kaspb "github.com/opentdf/platform/protocol/go/kas" "github.com/opentdf/platform/service/internal/security" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/encoding/protojson" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -35,19 +39,41 @@ func (p Provider) lookupKid(ctx context.Context, algorithm string) (string, erro return "", errors.Join(ErrConfig, status.Error(codes.NotFound, "no default key for algorithm")) } -func (p Provider) LegacyPublicKey(ctx context.Context, in *kaspb.LegacyPublicKeyRequest) (*wrapperspb.StringValue, error) { - algorithm := in.GetAlgorithm() +func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kaspb.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) { + algorithm := req.Msg.GetAlgorithm() if algorithm == "" { algorithm = security.AlgorithmRSA2048 } + pem, err := legacyPublicKey(ctx, p, algorithm) + if err != nil { + return nil, err + } + rsp := &wrapperspb.StringValue{Value: pem} + return &connect.Response[wrapperspb.StringValue]{Msg: rsp}, nil +} + +func (p Provider) LegacyPublicKeyHandler(w http.ResponseWriter, r *http.Request) { + algorithm := r.URL.Query().Get("algorithm") + if algorithm == "" { + algorithm = security.AlgorithmRSA2048 + } + pem, err := legacyPublicKey(r.Context(), p, algorithm) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Write([]byte(pem)) //nolint:errcheck // ignore error +} + +func legacyPublicKey(ctx context.Context, p Provider, algorithm string) (string, error) { var pem string var err error if p.CryptoProvider == nil { - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } kid, err := p.lookupKid(ctx, algorithm) if err != nil { - return nil, err + return "", err } switch algorithm { @@ -55,7 +81,7 @@ func (p Provider) LegacyPublicKey(ctx context.Context, in *kaspb.LegacyPublicKey pem, err = p.CryptoProvider.ECCertificate(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.ECPublicKey failed", "err", err) - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } case security.AlgorithmRSA2048: fallthrough @@ -63,26 +89,26 @@ func (p Provider) LegacyPublicKey(ctx context.Context, in *kaspb.LegacyPublicKey pem, err = p.CryptoProvider.RSAPublicKey(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.RSAPublicKey failed", "err", err) - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } default: - return nil, errors.Join(ErrConfig, status.Error(codes.NotFound, "invalid algorithm")) + return "", errors.Join(ErrConfig, status.Error(codes.NotFound, "invalid algorithm")) } - return &wrapperspb.StringValue{Value: pem}, nil + return pem, nil } -func (p Provider) PublicKey(ctx context.Context, in *kaspb.PublicKeyRequest) (*kaspb.PublicKeyResponse, error) { - algorithm := in.GetAlgorithm() +func (p Provider) PublicKey(ctx context.Context, req *connect.Request[kaspb.PublicKeyRequest]) (*connect.Response[kaspb.PublicKeyResponse], error) { + algorithm := req.Msg.GetAlgorithm() if algorithm == "" { algorithm = security.AlgorithmRSA2048 } - fmt := in.GetFmt() + fmt := req.Msg.GetFmt() kid, err := p.lookupKid(ctx, algorithm) if err != nil { return nil, err } - r := func(value, kid string, err error) (*kaspb.PublicKeyResponse, error) { + r := func(value, kid string, err error) (*connect.Response[kaspb.PublicKeyResponse], error) { if errors.Is(err, security.ErrCertNotFound) { p.Logger.ErrorContext(ctx, "no key found for", "err", err, "kid", kid, "algorithm", algorithm, "fmt", fmt) return nil, errors.Join(err, status.Error(codes.NotFound, "no such key")) @@ -90,32 +116,87 @@ func (p Provider) PublicKey(ctx context.Context, in *kaspb.PublicKeyRequest) (*k p.Logger.ErrorContext(ctx, "configuration error for key lookup", "err", err, "kid", kid, "algorithm", algorithm, "fmt", fmt) return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } - if in.GetV() == "1" { - p.Logger.WarnContext(ctx, "hiding kid in public key response for legacy client", "kid", kid, "v", in.GetV()) - return &kaspb.PublicKeyResponse{PublicKey: value}, nil + + rsp := &connect.Response[kaspb.PublicKeyResponse]{Msg: &kaspb.PublicKeyResponse{PublicKey: value}} + + if req.Msg.GetV() == "1" { + p.Logger.WarnContext(ctx, "hiding kid in public key response for legacy client", "kid", kid, "v", req.Msg.GetV()) + return rsp, nil } - return &kaspb.PublicKeyResponse{PublicKey: value, Kid: kid}, nil + rsp.Msg.Kid = kid + return rsp, nil + } + + pem, err := publicKey(ctx, p, algorithm, fmt) + return r(pem, kid, err) +} + +func (p Provider) PublicKeyHandler(w http.ResponseWriter, r *http.Request) { + algorithm := r.URL.Query().Get("algorithm") + if algorithm == "" { + algorithm = security.AlgorithmRSA2048 + } + keyFormat := r.URL.Query().Get("fmt") + + kid, err := p.lookupKid(r.Context(), algorithm) + if err != nil { + http.Error(w, fmt.Sprintf("key not found with algorithm: %s", algorithm), http.StatusNotFound) + return + } + + pem, err := publicKey(r.Context(), p, algorithm, keyFormat) + if err != nil { + if errors.Is(err, security.ErrCertNotFound) { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + pubkey := &kaspb.PublicKeyResponse{PublicKey: pem, Kid: kid} + pubkeyByte, err := protojson.Marshal(pubkey) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Write(pubkeyByte) //nolint:errcheck // ignore error +} + +func publicKey(ctx context.Context, p Provider, algorithm, fmt string) (string, error) { + kid, err := p.lookupKid(ctx, algorithm) + if err != nil { + return "", err } switch algorithm { case security.AlgorithmECP256R1: ecPublicKeyPem, err := p.CryptoProvider.ECPublicKey(kid) - return r(ecPublicKeyPem, kid, err) + if err != nil { + return "", err + } + return ecPublicKeyPem, nil case security.AlgorithmRSA2048: fallthrough case "": switch fmt { case "jwk": rsaPublicKeyPem, err := p.CryptoProvider.RSAPublicKeyAsJSON(kid) - return r(rsaPublicKeyPem, kid, err) + if err != nil { + return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + } + return rsaPublicKeyPem, nil case "pkcs8": fallthrough case "": rsaPublicKeyPem, err := p.CryptoProvider.RSAPublicKey(kid) - return r(rsaPublicKeyPem, kid, err) + if err != nil { + return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + } + return rsaPublicKeyPem, nil } } - return nil, status.Error(codes.NotFound, "invalid algorithm or format") + return "", status.Error(codes.NotFound, "invalid algorithm or format") } func exportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) { diff --git a/service/kas/access/publicKey_test.go b/service/kas/access/publicKey_test.go index e469ddd5e7..b0585bafb0 100644 --- a/service/kas/access/publicKey_test.go +++ b/service/kas/access/publicKey_test.go @@ -13,6 +13,7 @@ import ( "os" "testing" + "connectrpc.com/connect" kaspb "github.com/opentdf/platform/protocol/go/kas" "github.com/opentdf/platform/service/internal/security" "github.com/opentdf/platform/service/logger" @@ -101,7 +102,7 @@ func TestStandardCertificateHandlerEmpty(t *testing.T) { Logger: logger.CreateTestLogger(), } - result, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{Fmt: "pkcs8"}) + result, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{Msg: &kaspb.PublicKeyRequest{Fmt: "pkcs8"}}) require.Error(t, err, "not found") assert.Nil(t, result) } @@ -147,10 +148,10 @@ func TestStandardPublicKeyHandlerV2(t *testing.T) { }, } - result, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{}) + result, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{Msg: &kaspb.PublicKeyRequest{}}) require.NoError(t, err) require.NotNil(t, result) - assert.Contains(t, result.GetPublicKey(), "BEGIN PUBLIC KEY") + assert.Contains(t, result.Msg.GetPublicKey(), "BEGIN PUBLIC KEY") } func TestStandardPublicKeyHandlerV2Failure(t *testing.T) { @@ -166,7 +167,7 @@ func TestStandardPublicKeyHandlerV2Failure(t *testing.T) { Logger: logger.CreateTestLogger(), } - k, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{}) + k, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{Msg: &kaspb.PublicKeyRequest{}}) assert.Nil(t, k) require.Error(t, err) } @@ -192,8 +193,10 @@ func TestStandardPublicKeyHandlerV2NotFound(t *testing.T) { Logger: logger.CreateTestLogger(), } - k, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{ - Algorithm: "algorithm:unknown", + k, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{ + Msg: &kaspb.PublicKeyRequest{ + Algorithm: "algorithm:unknown", + }, }) assert.Nil(t, k) require.Error(t, err) @@ -230,14 +233,16 @@ func TestStandardPublicKeyHandlerV2WithJwk(t *testing.T) { }, } - result, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{ - Algorithm: "rsa:2048", - V: "2", - Fmt: "jwk", + result, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{ + Msg: &kaspb.PublicKeyRequest{ + Algorithm: "rsa:2048", + V: "2", + Fmt: "jwk", + }, }) require.NoError(t, err) require.NotNil(t, result) - assert.Contains(t, result.GetPublicKey(), "\"kty\"") + assert.Contains(t, result.Msg.GetPublicKey(), "\"kty\"") } func TestStandardCertificateHandlerWithEc256(t *testing.T) { @@ -261,10 +266,14 @@ func TestStandardCertificateHandlerWithEc256(t *testing.T) { CryptoProvider: c, } - result, err := kas.LegacyPublicKey(context.Background(), &kaspb.LegacyPublicKeyRequest{Algorithm: "ec:secp256r1"}) + result, err := kas.LegacyPublicKey(context.Background(), &connect.Request[kaspb.LegacyPublicKeyRequest]{ + Msg: &kaspb.LegacyPublicKeyRequest{ + Algorithm: "ec:secp256r1", + }, + }) require.NoError(t, err) require.NotNil(t, result) - assert.Contains(t, result.GetValue(), "BEGIN PUBLIC KEY") + assert.Contains(t, result.Msg.GetValue(), "BEGIN PUBLIC KEY") } func TestStandardPublicKeyHandlerWithEc256(t *testing.T) { @@ -288,10 +297,14 @@ func TestStandardPublicKeyHandlerWithEc256(t *testing.T) { CryptoProvider: c, } - result, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{Algorithm: "ec:secp256r1"}) + result, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{ + Msg: &kaspb.PublicKeyRequest{ + Algorithm: "ec:secp256r1", + }, + }) require.NoError(t, err) require.NotNil(t, result) - assert.Contains(t, result.GetPublicKey(), "BEGIN PUBLIC KEY") + assert.Contains(t, result.Msg.GetPublicKey(), "BEGIN PUBLIC KEY") } func TestStandardPublicKeyHandlerV2WithEc256(t *testing.T) { @@ -315,9 +328,13 @@ func TestStandardPublicKeyHandlerV2WithEc256(t *testing.T) { CryptoProvider: c, } - result, err := kas.PublicKey(context.Background(), &kaspb.PublicKeyRequest{Algorithm: "ec:secp256r1", - V: "2"}) + result, err := kas.PublicKey(context.Background(), &connect.Request[kaspb.PublicKeyRequest]{ + Msg: &kaspb.PublicKeyRequest{ + Algorithm: "ec:secp256r1", + V: "2", + }, + }) require.NoError(t, err) require.NotNil(t, result) - assert.Contains(t, result.GetPublicKey(), "BEGIN PUBLIC KEY") + assert.Contains(t, result.Msg.GetPublicKey(), "BEGIN PUBLIC KEY") } diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index bec70fb6ca..08ac1073c4 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -15,10 +15,13 @@ import ( "encoding/pem" "errors" "fmt" + "io" "log/slog" + "net/http" "strings" "time" + "connectrpc.com/connect" "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" @@ -32,8 +35,8 @@ import ( "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/encoding/protojson" ) type SignedRequestBody struct { @@ -119,14 +122,9 @@ func justRequestBody(ctx context.Context, token jwt.Token, logger logger.Logger) return rbString, nil } -func extractSRTBody(ctx context.Context, in *kaspb.RewrapRequest, logger logger.Logger) (*RequestBody, error) { +func extractSRTBody(ctx context.Context, headers http.Header, in *kaspb.RewrapRequest, logger logger.Logger) (*RequestBody, error) { // First load legacy method for verifying SRT - md, exists := metadata.FromIncomingContext(ctx) - if !exists { - logger.WarnContext(ctx, "missing metadata for srt validation") - return nil, errors.New("missing metadata") - } - if vpk, ok := md["X-Virtrupubkey"]; ok && len(vpk) == 1 { + if vpk, ok := headers["X-Virtrupubkey"]; ok && len(vpk) == 1 { logger.InfoContext(ctx, "Legacy Client: Processing X-Virtrupubkey") } @@ -190,6 +188,7 @@ func extractSRTBody(ctx context.Context, in *kaspb.RewrapRequest, logger logger. return nil, err400("clientPublicKey unsupported type") } } + func extractPolicyBinding(policyBinding interface{}) (string, error) { switch v := policyBinding.(type) { case string: @@ -203,6 +202,7 @@ func extractPolicyBinding(policyBinding interface{}) (string, error) { return "", fmt.Errorf("unsupported policy binding type") } } + func verifyAndParsePolicy(ctx context.Context, requestBody *RequestBody, k []byte, logger logger.Logger) (*Policy, error) { actualHMAC, err := generateHMACDigest(ctx, []byte(requestBody.Policy), k, logger) if err != nil { @@ -246,7 +246,7 @@ func verifyAndParsePolicy(ctx context.Context, requestBody *RequestBody, k []byt } func getEntityInfo(ctx context.Context, logger *logger.Logger) (*entityInfo, error) { - var info = new(entityInfo) + info := new(entityInfo) token := auth.GetAccessTokenFromContext(ctx, logger) if token == nil { @@ -269,10 +269,11 @@ func getEntityInfo(ctx context.Context, logger *logger.Logger) (*entityInfo, err return info, nil } -func (p *Provider) Rewrap(ctx context.Context, in *kaspb.RewrapRequest) (*kaspb.RewrapResponse, error) { +func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.RewrapRequest]) (*connect.Response[kaspb.RewrapResponse], error) { + in := req.Msg p.Logger.DebugContext(ctx, "REWRAP") - body, err := extractSRTBody(ctx, in, *p.Logger) + body, err := extractSRTBody(ctx, req.Header(), in, *p.Logger) if err != nil { p.Logger.DebugContext(ctx, "unverifiable srt", "err", err) return nil, err @@ -295,13 +296,69 @@ func (p *Provider) Rewrap(ctx context.Context, in *kaspb.RewrapRequest) (*kaspb. p.Logger.ErrorContext(ctx, "rewrap nano", "err", err) } p.Logger.DebugContext(ctx, "rewrap nano", "rsp", rsp) - return rsp, err + return &connect.Response[kaspb.RewrapResponse]{Msg: rsp}, err } rsp, err := p.tdf3Rewrap(ctx, body, entityInfo) if err != nil { p.Logger.ErrorContext(ctx, "rewrap tdf3", "err", err) } - return rsp, err + return &connect.Response[kaspb.RewrapResponse]{Msg: rsp}, err +} + +func (p *Provider) RewrapHandler(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + req := &kaspb.RewrapRequest{} + bodyBytes, err := io.ReadAll(r.Body) + if err != nil { + p.Logger.WarnContext(ctx, "read request body", "err", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + err = protojson.Unmarshal(bodyBytes, req) + if err != nil { + p.Logger.WarnContext(ctx, "decode request", "err", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + p.Logger.DebugContext(ctx, "REWRAP HANDLER") + body, err := extractSRTBody(ctx, r.Header, req, *p.Logger) + if err != nil { + p.Logger.DebugContext(ctx, "unverifiable srt", "err", err) + http.Error(w, err.Error(), http.StatusBadRequest) + } + + entityInfo, err := getEntityInfo(ctx, p.Logger) + if err != nil { + p.Logger.DebugContext(ctx, "no entity info", "err", err) + http.Error(w, err.Error(), http.StatusBadRequest) + } + + if body.Algorithm == "" { + p.Logger.DebugContext(ctx, "default rewrap algorithm") + body.Algorithm = "rsa:2048" + } + rewrapFunc := p.tdf3Rewrap + logType := "tdf3" + isNano := body.Algorithm == "ec:secp256r1" + if isNano { + rewrapFunc = p.nanoTDFRewrap + logType = "nano" + } + rsp, err := rewrapFunc(ctx, body, entityInfo) + if err != nil { + p.Logger.ErrorContext(ctx, "rewrap "+logType, "err", err) + } + if isNano { + p.Logger.DebugContext(ctx, "rewrap nano", "rsp", rsp) + } + rspBytes, err := protojson.Marshal(rsp) + if err != nil { + p.Logger.WarnContext(ctx, "marshal response", "err", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(rspBytes) //nolint:errcheck // ignore error } func (p *Provider) tdf3Rewrap(ctx context.Context, body *RequestBody, entity *entityInfo) (*kaspb.RewrapResponse, error) { diff --git a/service/kas/access/rewrap_test.go b/service/kas/access/rewrap_test.go index 74ad90290d..f75348a09d 100644 --- a/service/kas/access/rewrap_test.go +++ b/service/kas/access/rewrap_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "encoding/pem" "log/slog" + "net/http" "testing" "github.com/lestrrat-go/jwx/v2/jwa" @@ -154,7 +155,7 @@ func privateKey(t *testing.T) *rsa.PrivateKey { return k } -func publicKey(t *testing.T) *rsa.PublicKey { +func publicKeyTest(t *testing.T) *rsa.PublicKey { b, rest := pem.Decode([]byte(rsaPublic)) require.NotNil(t, b) assert.Empty(t, rest) @@ -298,7 +299,7 @@ func TestParseAndVerifyRequest(t *testing.T) { srt2 := makeRewrapBody(t, fauxPolicyBytes(t), true) badPolicySrt := makeRewrapBody(t, emptyPolicyBytes(), true) - var tests = []struct { + tests := []struct { name string body []byte goodDPoP bool @@ -322,7 +323,7 @@ func TestParseAndVerifyRequest(t *testing.T) { if tt.goodDPoP { key, err = jwk.FromRaw(entityPublicKey(t)) } else { - key, err = jwk.FromRaw(publicKey(t)) + key, err = jwk.FromRaw(publicKeyTest(t)) } require.NoError(t, err, "couldn't get JWK from key") err = key.Set(jwk.AlgorithmKey, jwa.RS256) // Check the error return value @@ -337,6 +338,7 @@ func TestParseAndVerifyRequest(t *testing.T) { verified, err := extractSRTBody( ctx, + http.Header{}, &kaspb.RewrapRequest{ SignedRequestToken: string(tt.body), }, @@ -375,6 +377,7 @@ func Test_SignedRequestBody_When_Bad_Signature_Expect_Failure(t *testing.T) { verified, err := extractSRTBody( ctx, + http.Header{}, &kaspb.RewrapRequest{ SignedRequestToken: string(makeRewrapBody(t, fauxPolicyBytes(t), false)), }, diff --git a/service/kas/kas.go b/service/kas/kas.go index 280a068ec1..386507e8f5 100644 --- a/service/kas/kas.go +++ b/service/kas/kas.go @@ -4,23 +4,25 @@ import ( "context" "fmt" "log/slog" + "net/http" "net/url" "strings" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/mitchellh/mapstructure" kaspb "github.com/opentdf/platform/protocol/go/kas" + "github.com/opentdf/platform/protocol/go/kas/kasconnect" "github.com/opentdf/platform/service/internal/security" "github.com/opentdf/platform/service/kas/access" "github.com/opentdf/platform/service/pkg/serviceregistry" ) -func NewRegistration() *serviceregistry.Service[access.Provider] { - return &serviceregistry.Service[access.Provider]{ - ServiceOptions: serviceregistry.ServiceOptions[access.Provider]{ - Namespace: "kas", - ServiceDesc: &kaspb.AccessService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*access.Provider, serviceregistry.HandlerServer) { +func NewRegistration() *serviceregistry.Service[kasconnect.AccessServiceHandler] { + return &serviceregistry.Service[kasconnect.AccessServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[kasconnect.AccessServiceHandler]{ + Namespace: "kas", + ServiceDesc: &kaspb.AccessService_ServiceDesc, + ConnectRPCFunc: kasconnect.NewAccessServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (kasconnect.AccessServiceHandler, serviceregistry.HandlerServer) { // FIXME msg="mismatched key access url" keyAccessURL=http://localhost:9000 kasURL=https://:9000 hostWithPort := srp.OTDF.HTTPServer.Addr if strings.HasPrefix(hostWithPort, ":") { @@ -65,7 +67,7 @@ func NewRegistration() *serviceregistry.Service[access.Provider] { kasCfg.Keyring = append(kasCfg.Keyring, inferLegacyKeys(kasCfg.Keyring)...) } - p := access.Provider{ + p := &access.Provider{ URI: *kasURI, AttributeSvc: nil, CryptoProvider: srp.OTDF.CryptoProvider, @@ -80,8 +82,8 @@ func NewRegistration() *serviceregistry.Service[access.Provider] { srp.Logger.Error("failed to register kas readiness check", slog.String("error", err.Error())) } - return &p, func(ctx context.Context, mux *runtime.ServeMux) error { - return kaspb.RegisterAccessServiceHandlerServer(ctx, mux, &p) + return p, func(_ context.Context, _ *http.ServeMux) error { + return nil } }, }, diff --git a/service/logger/audit/contextServerInterceptor.go b/service/logger/audit/contextServerInterceptor.go index 5c3e61a595..94984f8838 100644 --- a/service/logger/audit/contextServerInterceptor.go +++ b/service/logger/audit/contextServerInterceptor.go @@ -2,56 +2,58 @@ package audit import ( "context" + "net/http" + "connectrpc.com/connect" "github.com/google/uuid" sdkAudit "github.com/opentdf/platform/sdk/audit" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" ) // The audit unary server interceptor is a gRPC interceptor that adds metadata // to the context of incoming requests. This metadata is used to log audit // audit events. -func ContextServerInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { - // Get metadata from the context - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - return nil, status.Error(codes.InvalidArgument, "missing metadata") +func ContextServerInterceptor() connect.UnaryInterceptorFunc { + interceptor := func(next connect.UnaryFunc) connect.UnaryFunc { + return connect.UnaryFunc(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { + // Get metadata from the context + headers := req.Header() + + // Add request ID from existing header or create a new one + var requestID uuid.UUID + var err error + + requestIDFromMetadata := headers[http.CanonicalHeaderKey(sdkAudit.RequestIDHeaderKey.String())] + if len(requestIDFromMetadata) > 0 { + requestID, err = uuid.Parse(requestIDFromMetadata[0]) + if err != nil { + requestID = uuid.New() + } + } else { + requestID = uuid.New() + } + ctx = context.WithValue(ctx, sdkAudit.RequestIDContextKey, requestID) + + // Get the request IP from the metadata header + requestIPFromMetadata := headers[http.CanonicalHeaderKey(sdkAudit.RequestIPHeaderKey.String())] + if len(requestIPFromMetadata) > 0 { + ctx = context.WithValue(ctx, sdkAudit.RequestIPContextKey, requestIPFromMetadata[0]) + } + + // Get the actor ID from the metadata header + actorIDFromMetadata := headers[http.CanonicalHeaderKey(sdkAudit.ActorIDHeaderKey.String())] + if len(actorIDFromMetadata) > 0 { + ctx = context.WithValue(ctx, sdkAudit.ActorIDContextKey, actorIDFromMetadata[0]) + } + + // Sets the user agent header on the context if it is present in the metadata + userAgent := headers[http.CanonicalHeaderKey(sdkAudit.UserAgentHeaderKey.String())] + if len(userAgent) > 0 { + ctx = context.WithValue(ctx, sdkAudit.UserAgentContextKey, userAgent[0]) + } + + return next(ctx, req) + }) } - // Add request ID from existing header or create a new one - var requestID uuid.UUID - var err error - requestIDFromMetadata := md[string(sdkAudit.RequestIDHeaderKey)] - if len(requestIDFromMetadata) > 0 { - requestID, err = uuid.Parse(requestIDFromMetadata[0]) - if err != nil { - requestID = uuid.New() - } - } else { - requestID = uuid.New() - } - ctx = context.WithValue(ctx, sdkAudit.RequestIDContextKey, requestID) - - // Get the request IP from the metadata header - requestIPFromMetadata := md[string(sdkAudit.RequestIPHeaderKey)] - if len(requestIPFromMetadata) > 0 { - ctx = context.WithValue(ctx, sdkAudit.RequestIPContextKey, requestIPFromMetadata[0]) - } - - // Get the actor ID from the metadata header - actorIDFromMetadata := md[string(sdkAudit.ActorIDHeaderKey)] - if len(actorIDFromMetadata) > 0 { - ctx = context.WithValue(ctx, sdkAudit.ActorIDContextKey, actorIDFromMetadata[0]) - } - - // Sets the user agent header on the context if it is present in the metadata - userAgent := md[string(sdkAudit.UserAgentHeaderKey)] - if len(userAgent) > 0 { - ctx = context.WithValue(ctx, sdkAudit.UserAgentContextKey, userAgent[0]) - } - - return handler(ctx, req) + return connect.UnaryInterceptorFunc(interceptor) } diff --git a/service/logger/audit/utils.go b/service/logger/audit/utils.go index 6929eac998..be81c4591f 100644 --- a/service/logger/audit/utils.go +++ b/service/logger/audit/utils.go @@ -5,8 +5,8 @@ import ( "log/slog" "github.com/google/uuid" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip" sdkAudit "github.com/opentdf/platform/sdk/audit" + "github.com/opentdf/platform/service/internal/server/realip" ) // Common Strings @@ -155,14 +155,9 @@ func getContextValue(ctx context.Context, key sdkAudit.ContextKey) string { // can pass the custom X-Forwarded-Request-IP header for internal requests. If // that is not present, it falls back to the realip package. func getRequestIPFromContext(ctx context.Context) string { - requestIPFromContextKey, isOK := ctx.Value(sdkAudit.RequestIPContextKey).(string) - if isOK { - return requestIPFromContextKey - } - - requestIPFromRealip, ipOK := realip.FromContext(ctx) - if ipOK { - return requestIPFromRealip.String() + ip := realip.FromContext(ctx) + if ip.String() != "" { + return ip.String() } return defaultNone diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index 14d4e8f602..c1644e8388 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -163,20 +163,20 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS if err != nil { return err } - // Register the service with the gRPC server - if err := svc.RegisterGRPCServer(otdf.GRPCServer); err != nil { - return err + + // Register the service with the gRPC gateway + if err := svc.RegisterExtraHandlers(ctx, otdf.ExtraHandlerMux); err != nil { + logger.Error("service did not register extra http handlers", slog.String("namespace", ns)) } - // Register the service with in process gRPC server - if err := svc.RegisterGRPCServer(otdf.GRPCInProcess.GetGrpcServer()); err != nil { - return err + // Register Connect RPC Services + if err := svc.RegisterConnectRPCServiceHandler(ctx, otdf.ConnectRPC); err != nil { + logger.Info("service did not register a connect-rpc handler", slog.String("namespace", ns)) } - // Register the service with the gRPC gateway - if err := svc.RegisterHTTPServer(ctx, otdf.Mux); err != nil { - logger.Error("failed to register service to grpc gateway", slog.String("namespace", ns), slog.String("error", err.Error())) - return err + // Register In Process Connect RPC Services + if err := svc.RegisterConnectRPCServiceHandler(ctx, otdf.ConnectRPCInProcess.ConnectRPC); err != nil { + logger.Info("service did not register a connect-rpc handler", slog.String("namespace", ns)) } logger.Info( diff --git a/service/pkg/server/services_test.go b/service/pkg/server/services_test.go index 1f9037f400..5d4e163c9e 100644 --- a/service/pkg/server/services_test.go +++ b/service/pkg/server/services_test.go @@ -2,9 +2,9 @@ package server import ( "context" + "net/http" "testing" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/config" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/serviceregistry" @@ -22,7 +22,7 @@ type mockTestServiceOptions struct { serviceName string serviceHandlerType any serviceObject any - serviceHandler func(ctx context.Context, mux *runtime.ServeMux) error + serviceHandler func(ctx context.Context, mux *http.ServeMux) error dbRegister serviceregistry.DBRegister } @@ -32,7 +32,7 @@ func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.IServ namespace: "test", serviceName: "TestService", serviceHandlerType: (*interface{})(nil), - serviceHandler: func(_ context.Context, _ *runtime.ServeMux) error { + serviceHandler: func(_ context.Context, _ *http.ServeMux) error { return nil }, } @@ -59,13 +59,13 @@ func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.IServ ServiceName: serviceName, HandlerType: serviceHandlerType, }, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*TestService, serviceregistry.HandlerServer) { - var ts *TestService + RegisterFunc: func(srp serviceregistry.RegistrationParams) (TestService, serviceregistry.HandlerServer) { + var ts TestService var ok bool - if ts, ok = opts.serviceObject.(*TestService); !ok { + if ts, ok = opts.serviceObject.(TestService); !ok { panic("serviceObject is not a TestService") } - return ts, func(ctx context.Context, mux *runtime.ServeMux) error { + return ts, func(ctx context.Context, mux *http.ServeMux) error { spy.wasCalled = true spy.callParams = append(spy.callParams, srp, ctx, mux, ts) return serviceHandler(ctx, mux) @@ -196,7 +196,7 @@ func (suite *ServiceTestSuite) TestStartServicesWithVariousCases() { // Test service which will be enabled registerTest, testSpy := mockTestServiceRegistry(mockTestServiceOptions{ - serviceObject: &TestService{}, + serviceObject: TestService{}, }) err := registry.RegisterService(registerTest, "test") suite.Require().NoError(err) diff --git a/service/pkg/server/start.go b/service/pkg/server/start.go index 8a82dec64e..dbbdf190b9 100644 --- a/service/pkg/server/start.go +++ b/service/pkg/server/start.go @@ -156,7 +156,7 @@ func Start(f ...StartOptions) error { if slices.Contains(cfg.Mode, "all") || slices.Contains(cfg.Mode, "core") { // Use IPC for the SDK client sdkOptions = append(sdkOptions, sdk.WithIPC()) - sdkOptions = append(sdkOptions, sdk.WithCustomCoreConnection(otdf.GRPCInProcess.Conn())) + sdkOptions = append(sdkOptions, sdk.WithCustomCoreConnection(otdf.ConnectRPCInProcess.Conn())) client, err = sdk.New("", sdkOptions...) if err != nil { diff --git a/service/pkg/server/start_test.go b/service/pkg/server/start_test.go index 5ab8ed3144..15a31d38fa 100644 --- a/service/pkg/server/start_test.go +++ b/service/pkg/server/start_test.go @@ -2,6 +2,7 @@ package server import ( "context" + "fmt" "io" "log/slog" "net/http" @@ -9,7 +10,6 @@ import ( "testing" "time" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/config" "github.com/opentdf/platform/service/internal/server" @@ -25,7 +25,7 @@ type ( TestService struct{} ) -func (t TestService) TestHandler(w http.ResponseWriter, _ *http.Request, _ map[string]string) { +func (t TestService) TestHandler(w http.ResponseWriter, _ *http.Request) { _, err := w.Write([]byte("hello from test service!")) if err != nil { panic(err) @@ -99,11 +99,12 @@ func (suite *StartTestSuite) Test_Start_When_Extra_Service_Registered_Expect_Res require.NoError(t, err) // Register Test Service - ts := &TestService{} + ts := TestService{} registerTestService, _ := mockTestServiceRegistry(mockTestServiceOptions{ serviceObject: ts, - serviceHandler: func(_ context.Context, mux *runtime.ServeMux) error { - return mux.HandlePath(http.MethodGet, "/healthz", ts.TestHandler) + serviceHandler: func(_ context.Context, mux *http.ServeMux) error { + mux.HandleFunc(fmt.Sprintf("%s /healthz", http.MethodGet), ts.TestHandler) + return nil }, }) diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index 2d9ca082ed..26526efdf2 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -11,7 +11,6 @@ import ( "connectrpc.com/connect" "github.com/opentdf/platform/sdk" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/server" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/db" @@ -50,8 +49,8 @@ type RegistrationParams struct { RegisterReadinessCheck func(namespace string, check func(context.Context) error) error } type ( - HandlerServer func(ctx context.Context, mux *runtime.ServeMux) error - RegisterFunc[S any] func(RegistrationParams) (Impl *S, HandlerServer HandlerServer) + HandlerServer func(ctx context.Context, mux *http.ServeMux) error + RegisterFunc[S any] func(RegistrationParams) (impl S, HandlerServer HandlerServer) ) // DBRegister is a struct that holds the information needed to register a service with a database @@ -72,15 +71,15 @@ type IService interface { Start(ctx context.Context, params RegistrationParams) error IsStarted() bool Shutdown() error - RegisterGRPCServer(server *grpc.Server) error - RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error + RegisterExtraHandlers(context.Context, *http.ServeMux) error + RegisterConnectRPCServiceHandler(context.Context, *server.ConnectRPC) error } // Service is a struct that holds the registration information for a service as well as the state // of the service within the instance of the platform. type Service[S any] struct { // Registration - impl *S + impl S // Started is a flag that indicates whether the service has been started Started bool // Close is a function that can be called to close the service @@ -155,29 +154,29 @@ func (s *Service[S]) Start(ctx context.Context, params RegistrationParams) error return nil } -// RegisterGRPCServer registers the gRPC server with the service implementation. -// It checks if the service implementation is registered and then registers the service with the server. -// It returns an error if the service implementation is not registered. -func (s *Service[S]) RegisterGRPCServer(server *grpc.Server) error { - if s.impl == nil { - return fmt.Errorf("service did not register an implementation") - } - server.RegisterService(s.ServiceDesc, s.impl) - return nil -} - -// Deprecated: RegisterHTTPServer is deprecated and should not be used going forward. +// Deprecated: RegisterExtraHandlers is deprecated and should not be used going forward. // We will be looking onto other alternatives like bufconnect to replace this. -// RegisterHTTPServer registers an HTTP server with the service. +// RegisterExtraHandlers registers an HTTP server with the service. // It takes a context, a ServeMux, and an implementation function as parameters. // If the service did not register a handler, it returns an error. -func (s *Service[S]) RegisterHTTPServer(ctx context.Context, mux *runtime.ServeMux) error { +func (s *Service[S]) RegisterExtraHandlers(ctx context.Context, mux *http.ServeMux) error { if s.httpHandlerFunc == nil { return fmt.Errorf("service did not register a handler") } return s.httpHandlerFunc(ctx, mux) } +// RegisterConnectRPCServiceHandler registers a ConnectRPC service handler with the service. +func (s Service[S]) RegisterConnectRPCServiceHandler(_ context.Context, connectRPC *server.ConnectRPC) error { + if s.ConnectRPCFunc == nil { + return fmt.Errorf("service did not register a handler") + } + connectRPC.ServiceReflection = append(connectRPC.ServiceReflection, s.GetServiceDesc().ServiceName) + path, handler := s.ConnectRPCFunc(s.impl, connectRPC.Interceptors...) + connectRPC.Mux.Handle(path, handler) + return nil +} + // namespace represents a namespace in the service registry. type Namespace struct { Mode string diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index c3d31aa836..0686c2d231 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -4,43 +4,45 @@ import ( "context" "fmt" "log/slog" + "net/http" + "strconv" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" "github.com/opentdf/platform/protocol/go/policy/attributes" + "github.com/opentdf/platform/protocol/go/policy/attributes/attributesconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" "github.com/opentdf/platform/service/pkg/serviceregistry" policydb "github.com/opentdf/platform/service/policy/db" + "google.golang.org/protobuf/encoding/protojson" ) type AttributesService struct { //nolint:revive // AttributesService is a valid name for this struct - attributes.UnimplementedAttributesServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[AttributesService] { - return &serviceregistry.Service[AttributesService]{ - ServiceOptions: serviceregistry.ServiceOptions[AttributesService]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &attributes.AttributesService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*AttributesService, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[attributesconnect.AttributesServiceHandler] { + return &serviceregistry.Service[attributesconnect.AttributesServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[attributesconnect.AttributesServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &attributes.AttributesService_ServiceDesc, + ConnectRPCFunc: attributesconnect.NewAttributesServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (attributesconnect.AttributesServiceHandler, serviceregistry.HandlerServer) { as := &AttributesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return as, func(ctx context.Context, mux *runtime.ServeMux) error { - return attributes.RegisterAttributesServiceHandlerServer(ctx, mux, as) - } + return as, nil }, }, } } func (s AttributesService) CreateAttribute(ctx context.Context, - req *attributes.CreateAttributeRequest, -) (*attributes.CreateAttributeResponse, error) { - s.logger.Debug("creating new attribute definition", slog.String("name", req.GetName())) + req *connect.Request[attributes.CreateAttributeRequest], +) (*connect.Response[attributes.CreateAttributeResponse], error) { + s.logger.Debug("creating new attribute definition", slog.String("name", req.Msg.GetName())) rsp := &attributes.CreateAttributeResponse{} auditParams := audit.PolicyEventParams{ @@ -48,27 +50,27 @@ func (s AttributesService) CreateAttribute(ctx context.Context, ActionType: audit.ActionTypeCreate, } - item, err := s.dbClient.CreateAttribute(ctx, req) + item, err := s.dbClient.CreateAttribute(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attribute", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attribute", req.Msg.String())) } - s.logger.Debug("created new attribute definition", slog.String("name", req.GetName())) + s.logger.Debug("created new attribute definition", slog.String("name", req.Msg.GetName())) auditParams.ObjectID = item.GetId() auditParams.Original = item s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.Attribute = item - return rsp, nil + return &connect.Response[attributes.CreateAttributeResponse]{Msg: rsp}, nil } func (s *AttributesService) ListAttributes(ctx context.Context, - req *attributes.ListAttributesRequest, -) (*attributes.ListAttributesResponse, error) { - state := policydb.GetDBStateTypeTransformedEnum(req.GetState()) - namespace := req.GetNamespace() + req *connect.Request[attributes.ListAttributesRequest], +) (*connect.Response[attributes.ListAttributesResponse], error) { + state := policydb.GetDBStateTypeTransformedEnum(req.Msg.GetState()) + namespace := req.Msg.GetNamespace() s.logger.Debug("listing attribute definitions", slog.String("state", state)) rsp := &attributes.ListAttributesResponse{} @@ -78,43 +80,85 @@ func (s *AttributesService) ListAttributes(ctx context.Context, } rsp.Attributes = list - return rsp, nil + return &connect.Response[attributes.ListAttributesResponse]{Msg: rsp}, nil } func (s *AttributesService) GetAttribute(ctx context.Context, - req *attributes.GetAttributeRequest, -) (*attributes.GetAttributeResponse, error) { + req *connect.Request[attributes.GetAttributeRequest], +) (*connect.Response[attributes.GetAttributeResponse], error) { rsp := &attributes.GetAttributeResponse{} - item, err := s.dbClient.GetAttribute(ctx, req.GetId()) + item, err := s.dbClient.GetAttribute(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } rsp.Attribute = item - return rsp, err + return &connect.Response[attributes.GetAttributeResponse]{Msg: rsp}, err } func (s *AttributesService) GetAttributeValuesByFqns(ctx context.Context, - req *attributes.GetAttributeValuesByFqnsRequest, -) (*attributes.GetAttributeValuesByFqnsResponse, error) { + req *connect.Request[attributes.GetAttributeValuesByFqnsRequest], +) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) { rsp := &attributes.GetAttributeValuesByFqnsResponse{} - fqnsToAttributes, err := s.dbClient.GetAttributesByValueFqns(ctx, req) + fqnsToAttributes, err := s.dbClient.GetAttributesByValueFqns(ctx, req.Msg) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("fqns", fmt.Sprintf("%v", req.GetFqns()))) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("fqns", fmt.Sprintf("%v", req.Msg.GetFqns()))) } rsp.FqnAttributeValues = fqnsToAttributes - return rsp, nil + return &connect.Response[attributes.GetAttributeValuesByFqnsResponse]{Msg: rsp}, nil +} + +func (s *AttributesService) GetAttributeValuesByFqnsHandler(w http.ResponseWriter, r *http.Request) { + q := r.URL.Query() + + fqns := q["fqns"] + withAttrGrants, err := strconv.ParseBool(q.Get("withValue.withAttribute.withKeyAccessGrants")) + if err != nil { + s.logger.Error("failed to parse withValue.withAttribute.withKeyAccessGrants", slog.String("error", err.Error())) + withAttrGrants = false + } + + withGrants, err := strconv.ParseBool(q.Get("withValue.withKeyAccessGrants")) + if err != nil { + s.logger.Error("failed to parse withValue.withKeyAccessGrants", slog.String("error", err.Error())) + withGrants = false + } + + fqnsToAttributes, err := s.dbClient.GetAttributesByValueFqns(r.Context(), &attributes.GetAttributeValuesByFqnsRequest{ + Fqns: fqns, + WithValue: &policy.AttributeValueSelector{ + WithKeyAccessGrants: withGrants, + WithAttribute: &policy.AttributeValueSelector_AttributeSelector{ + WithKeyAccessGrants: withAttrGrants, + }, + }, + }) + if err != nil { + s.logger.Error("failed to get attribute values by fqns", slog.String("error", err.Error())) + http.Error(w, "failed to get attribute values by fqns", http.StatusInternalServerError) + return + } + fqnsToAttributesBytes, err := protojson.Marshal(&attributes.GetAttributeValuesByFqnsResponse{FqnAttributeValues: fqnsToAttributes}) + if err != nil { + s.logger.Error("failed to marshal attribute values by fqns", slog.String("error", err.Error())) + http.Error(w, "failed to marshal attribute values by fqns", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + if _, err = w.Write(fqnsToAttributesBytes); err != nil { + s.logger.Error("failed to write attribute values by fqns", slog.String("error", err.Error())) + } } func (s *AttributesService) UpdateAttribute(ctx context.Context, - req *attributes.UpdateAttributeRequest, -) (*attributes.UpdateAttributeResponse, error) { + req *connect.Request[attributes.UpdateAttributeRequest], +) (*connect.Response[attributes.UpdateAttributeResponse], error) { rsp := &attributes.UpdateAttributeResponse{} - attributeID := req.GetId() + attributeID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, ObjectType: audit.ObjectTypeAttributeDefinition, @@ -127,10 +171,10 @@ func (s *AttributesService) UpdateAttribute(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", attributeID)) } - updated, err := s.dbClient.UpdateAttribute(ctx, attributeID, req) + updated, err := s.dbClient.UpdateAttribute(ctx, attributeID, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.GetId()), slog.String("attribute", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.Msg.GetId()), slog.String("attribute", req.Msg.String())) } auditParams.Original = original @@ -141,15 +185,15 @@ func (s *AttributesService) UpdateAttribute(ctx context.Context, Id: attributeID, } - return rsp, nil + return &connect.Response[attributes.UpdateAttributeResponse]{Msg: rsp}, nil } func (s *AttributesService) DeactivateAttribute(ctx context.Context, - req *attributes.DeactivateAttributeRequest, -) (*attributes.DeactivateAttributeResponse, error) { + req *connect.Request[attributes.DeactivateAttributeRequest], +) (*connect.Response[attributes.DeactivateAttributeResponse], error) { rsp := &attributes.DeactivateAttributeResponse{} - attributeID := req.GetId() + attributeID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ObjectType: audit.ObjectTypeAttributeDefinition, ActionType: audit.ActionTypeUpdate, @@ -175,60 +219,67 @@ func (s *AttributesService) DeactivateAttribute(ctx context.Context, rsp.Attribute = &policy.Attribute{ Id: attributeID, } - return rsp, nil + return &connect.Response[attributes.DeactivateAttributeResponse]{Msg: rsp}, nil } /// /// Attribute Values /// -func (s *AttributesService) CreateAttributeValue(ctx context.Context, req *attributes.CreateAttributeValueRequest) (*attributes.CreateAttributeValueResponse, error) { +func (s *AttributesService) CreateAttributeValue(ctx context.Context, req *connect.Request[attributes.CreateAttributeValueRequest]) (*connect.Response[attributes.CreateAttributeValueResponse], error) { + rsp := &attributes.CreateAttributeValueResponse{} + auditParams := audit.PolicyEventParams{ ObjectType: audit.ObjectTypeAttributeValue, ActionType: audit.ActionTypeCreate, } - item, err := s.dbClient.CreateAttributeValue(ctx, req.GetAttributeId(), req) + item, err := s.dbClient.CreateAttributeValue(ctx, req.Msg.GetAttributeId(), req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeId", req.GetAttributeId()), slog.String("value", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeId", req.Msg.GetAttributeId()), slog.String("value", req.Msg.String())) } auditParams.ObjectID = item.GetId() auditParams.Original = item s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.CreateAttributeValueResponse{ - Value: item, - }, nil + rsp.Value = item + return &connect.Response[attributes.CreateAttributeValueResponse]{Msg: rsp}, nil } -func (s *AttributesService) ListAttributeValues(ctx context.Context, req *attributes.ListAttributeValuesRequest) (*attributes.ListAttributeValuesResponse, error) { - state := policydb.GetDBStateTypeTransformedEnum(req.GetState()) - s.logger.Debug("listing attribute values", slog.String("attributeId", req.GetAttributeId()), slog.String("state", state)) - list, err := s.dbClient.ListAttributeValues(ctx, req.GetAttributeId(), state) +func (s *AttributesService) ListAttributeValues(ctx context.Context, req *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) { + rsp := &attributes.ListAttributeValuesResponse{} + + state := policydb.GetDBStateTypeTransformedEnum(req.Msg.GetState()) + s.logger.Debug("listing attribute values", slog.String("attributeId", req.Msg.GetAttributeId()), slog.String("state", state)) + list, err := s.dbClient.ListAttributeValues(ctx, req.Msg.GetAttributeId(), state) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed, slog.String("attributeId", req.GetAttributeId())) + return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed, slog.String("attributeId", req.Msg.GetAttributeId())) } - return &attributes.ListAttributeValuesResponse{ - Values: list, - }, nil + rsp.Values = list + + return &connect.Response[attributes.ListAttributeValuesResponse]{Msg: rsp}, nil } -func (s *AttributesService) GetAttributeValue(ctx context.Context, req *attributes.GetAttributeValueRequest) (*attributes.GetAttributeValueResponse, error) { - item, err := s.dbClient.GetAttributeValue(ctx, req.GetId()) +func (s *AttributesService) GetAttributeValue(ctx context.Context, req *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { + rsp := &attributes.GetAttributeValueResponse{} + + item, err := s.dbClient.GetAttributeValue(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } - return &attributes.GetAttributeValueResponse{ - Value: item, - }, nil + rsp.Value = item + + return &connect.Response[attributes.GetAttributeValueResponse]{Msg: rsp}, nil } -func (s *AttributesService) UpdateAttributeValue(ctx context.Context, req *attributes.UpdateAttributeValueRequest) (*attributes.UpdateAttributeValueResponse, error) { - attributeID := req.GetId() +func (s *AttributesService) UpdateAttributeValue(ctx context.Context, req *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) { + rsp := &attributes.UpdateAttributeValueResponse{} + + attributeID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, ObjectType: audit.ObjectTypeAttributeValue, @@ -241,25 +292,27 @@ func (s *AttributesService) UpdateAttributeValue(ctx context.Context, req *attri return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", attributeID)) } - updated, err := s.dbClient.UpdateAttributeValue(ctx, req) + updated, err := s.dbClient.UpdateAttributeValue(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.GetId()), slog.String("value", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.Msg.GetId()), slog.String("value", req.Msg.String())) } auditParams.Original = original auditParams.Updated = updated s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.UpdateAttributeValueResponse{ - Value: &policy.Value{ - Id: attributeID, - }, - }, nil + rsp.Value = &policy.Value{ + Id: attributeID, + } + + return &connect.Response[attributes.UpdateAttributeValueResponse]{Msg: rsp}, nil } -func (s *AttributesService) DeactivateAttributeValue(ctx context.Context, req *attributes.DeactivateAttributeValueRequest) (*attributes.DeactivateAttributeValueResponse, error) { - attributeID := req.GetId() +func (s *AttributesService) DeactivateAttributeValue(ctx context.Context, req *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) { + rsp := &attributes.DeactivateAttributeValueResponse{} + + attributeID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ObjectType: audit.ObjectTypeAttributeValue, ActionType: audit.ActionTypeDelete, @@ -282,83 +335,91 @@ func (s *AttributesService) DeactivateAttributeValue(ctx context.Context, req *a auditParams.Updated = updated s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.DeactivateAttributeValueResponse{ - Value: updated, - }, nil + rsp.Value = updated + + return &connect.Response[attributes.DeactivateAttributeValueResponse]{Msg: rsp}, nil } -func (s *AttributesService) AssignKeyAccessServerToAttribute(ctx context.Context, req *attributes.AssignKeyAccessServerToAttributeRequest) (*attributes.AssignKeyAccessServerToAttributeResponse, error) { +func (s *AttributesService) AssignKeyAccessServerToAttribute(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) { + rsp := &attributes.AssignKeyAccessServerToAttributeResponse{} + auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, ObjectType: audit.ObjectTypeKasAttributeDefinitionAssignment, - ObjectID: fmt.Sprintf("%s-%s", req.GetAttributeKeyAccessServer().GetAttributeId(), req.GetAttributeKeyAccessServer().GetKeyAccessServerId()), + ObjectID: fmt.Sprintf("%s-%s", req.Msg.GetAttributeKeyAccessServer().GetAttributeId(), req.Msg.GetAttributeKeyAccessServer().GetKeyAccessServerId()), } - attributeKas, err := s.dbClient.AssignKeyAccessServerToAttribute(ctx, req.GetAttributeKeyAccessServer()) + attributeKas, err := s.dbClient.AssignKeyAccessServerToAttribute(ctx, req.Msg.GetAttributeKeyAccessServer()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeKas", req.GetAttributeKeyAccessServer().String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeKas", req.Msg.GetAttributeKeyAccessServer().String())) } s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.AssignKeyAccessServerToAttributeResponse{ - AttributeKeyAccessServer: attributeKas, - }, nil + rsp.AttributeKeyAccessServer = attributeKas + + return &connect.Response[attributes.AssignKeyAccessServerToAttributeResponse]{Msg: rsp}, nil } -func (s *AttributesService) RemoveKeyAccessServerFromAttribute(ctx context.Context, req *attributes.RemoveKeyAccessServerFromAttributeRequest) (*attributes.RemoveKeyAccessServerFromAttributeResponse, error) { +func (s *AttributesService) RemoveKeyAccessServerFromAttribute(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) { + rsp := &attributes.RemoveKeyAccessServerFromAttributeResponse{} + auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeKasAttributeDefinitionAssignment, - ObjectID: fmt.Sprintf("%s-%s", req.GetAttributeKeyAccessServer().GetAttributeId(), req.GetAttributeKeyAccessServer().GetKeyAccessServerId()), + ObjectID: fmt.Sprintf("%s-%s", req.Msg.GetAttributeKeyAccessServer().GetAttributeId(), req.Msg.GetAttributeKeyAccessServer().GetKeyAccessServerId()), } - attributeKas, err := s.dbClient.RemoveKeyAccessServerFromAttribute(ctx, req.GetAttributeKeyAccessServer()) + attributeKas, err := s.dbClient.RemoveKeyAccessServerFromAttribute(ctx, req.Msg.GetAttributeKeyAccessServer()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("attributeKas", req.GetAttributeKeyAccessServer().String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("attributeKas", req.Msg.GetAttributeKeyAccessServer().String())) } s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.RemoveKeyAccessServerFromAttributeResponse{ - AttributeKeyAccessServer: attributeKas, - }, nil + rsp.AttributeKeyAccessServer = attributeKas + + return &connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse]{Msg: rsp}, nil } -func (s *AttributesService) AssignKeyAccessServerToValue(ctx context.Context, req *attributes.AssignKeyAccessServerToValueRequest) (*attributes.AssignKeyAccessServerToValueResponse, error) { +func (s *AttributesService) AssignKeyAccessServerToValue(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) { + rsp := &attributes.AssignKeyAccessServerToValueResponse{} + auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, ObjectType: audit.ObjectTypeKasAttributeValueAssignment, - ObjectID: fmt.Sprintf("%s-%s", req.GetValueKeyAccessServer().GetValueId(), req.GetValueKeyAccessServer().GetKeyAccessServerId()), + ObjectID: fmt.Sprintf("%s-%s", req.Msg.GetValueKeyAccessServer().GetValueId(), req.Msg.GetValueKeyAccessServer().GetKeyAccessServerId()), } - valueKas, err := s.dbClient.AssignKeyAccessServerToValue(ctx, req.GetValueKeyAccessServer()) + valueKas, err := s.dbClient.AssignKeyAccessServerToValue(ctx, req.Msg.GetValueKeyAccessServer()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeValueKas", req.GetValueKeyAccessServer().String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("attributeValueKas", req.Msg.GetValueKeyAccessServer().String())) } s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.AssignKeyAccessServerToValueResponse{ - ValueKeyAccessServer: valueKas, - }, nil + rsp.ValueKeyAccessServer = valueKas + + return &connect.Response[attributes.AssignKeyAccessServerToValueResponse]{Msg: rsp}, nil } -func (s *AttributesService) RemoveKeyAccessServerFromValue(ctx context.Context, req *attributes.RemoveKeyAccessServerFromValueRequest) (*attributes.RemoveKeyAccessServerFromValueResponse, error) { +func (s *AttributesService) RemoveKeyAccessServerFromValue(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) { + rsp := &attributes.RemoveKeyAccessServerFromValueResponse{} + auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeKasAttributeValueAssignment, - ObjectID: fmt.Sprintf("%s-%s", req.GetValueKeyAccessServer().GetValueId(), req.GetValueKeyAccessServer().GetKeyAccessServerId()), + ObjectID: fmt.Sprintf("%s-%s", req.Msg.GetValueKeyAccessServer().GetValueId(), req.Msg.GetValueKeyAccessServer().GetKeyAccessServerId()), } - valueKas, err := s.dbClient.RemoveKeyAccessServerFromValue(ctx, req.GetValueKeyAccessServer()) + valueKas, err := s.dbClient.RemoveKeyAccessServerFromValue(ctx, req.Msg.GetValueKeyAccessServer()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("attributeValueKas", req.GetValueKeyAccessServer().String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("attributeValueKas", req.Msg.GetValueKeyAccessServer().String())) } s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &attributes.RemoveKeyAccessServerFromValueResponse{ - ValueKeyAccessServer: valueKas, - }, nil + rsp.ValueKeyAccessServer = valueKas + + return &connect.Response[attributes.RemoveKeyAccessServerFromValueResponse]{Msg: rsp}, nil } diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index db821d1ac7..14d7581d41 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -4,9 +4,10 @@ import ( "context" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" kasr "github.com/opentdf/platform/protocol/go/policy/kasregistry" + "github.com/opentdf/platform/protocol/go/policy/kasregistry/kasregistryconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" @@ -15,30 +16,30 @@ import ( ) type KeyAccessServerRegistry struct { - kasr.UnimplementedKeyAccessServerRegistryServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[KeyAccessServerRegistry] { - return &serviceregistry.Service[KeyAccessServerRegistry]{ - ServiceOptions: serviceregistry.ServiceOptions[KeyAccessServerRegistry]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &kasr.KeyAccessServerRegistryService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*KeyAccessServerRegistry, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[kasregistryconnect.KeyAccessServerRegistryServiceHandler] { + return &serviceregistry.Service[kasregistryconnect.KeyAccessServerRegistryServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[kasregistryconnect.KeyAccessServerRegistryServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &kasr.KeyAccessServerRegistryService_ServiceDesc, + ConnectRPCFunc: kasregistryconnect.NewKeyAccessServerRegistryServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (kasregistryconnect.KeyAccessServerRegistryServiceHandler, serviceregistry.HandlerServer) { ksr := &KeyAccessServerRegistry{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return ksr, func(ctx context.Context, mux *runtime.ServeMux) error { - return kasr.RegisterKeyAccessServerRegistryServiceHandlerServer(ctx, mux, ksr) - } + return ksr, nil }, }, } } func (s KeyAccessServerRegistry) CreateKeyAccessServer(ctx context.Context, - req *kasr.CreateKeyAccessServerRequest, -) (*kasr.CreateKeyAccessServerResponse, error) { + req *connect.Request[kasr.CreateKeyAccessServerRequest], +) (*connect.Response[kasr.CreateKeyAccessServerResponse], error) { + rsp := &kasr.CreateKeyAccessServerResponse{} + s.logger.Debug("creating key access server") auditParams := audit.PolicyEventParams{ @@ -46,51 +47,57 @@ func (s KeyAccessServerRegistry) CreateKeyAccessServer(ctx context.Context, ObjectType: audit.ObjectTypeKasRegistry, } - ks, err := s.dbClient.CreateKeyAccessServer(ctx, req) + ks, err := s.dbClient.CreateKeyAccessServer(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("keyAccessServer", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("keyAccessServer", req.Msg.String())) } auditParams.ObjectID = ks.GetId() auditParams.Original = ks s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &kasr.CreateKeyAccessServerResponse{ - KeyAccessServer: ks, - }, nil + rsp.KeyAccessServer = ks + + return &connect.Response[kasr.CreateKeyAccessServerResponse]{Msg: rsp}, nil } func (s KeyAccessServerRegistry) ListKeyAccessServers(ctx context.Context, - _ *kasr.ListKeyAccessServersRequest, -) (*kasr.ListKeyAccessServersResponse, error) { + _ *connect.Request[kasr.ListKeyAccessServersRequest], +) (*connect.Response[kasr.ListKeyAccessServersResponse], error) { + rsp := &kasr.ListKeyAccessServersResponse{} + keyAccessServers, err := s.dbClient.ListKeyAccessServers(ctx) if err != nil { return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed) } - return &kasr.ListKeyAccessServersResponse{ - KeyAccessServers: keyAccessServers, - }, nil + rsp.KeyAccessServers = keyAccessServers + + return &connect.Response[kasr.ListKeyAccessServersResponse]{Msg: rsp}, nil } func (s KeyAccessServerRegistry) GetKeyAccessServer(ctx context.Context, - req *kasr.GetKeyAccessServerRequest, -) (*kasr.GetKeyAccessServerResponse, error) { - keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, req.GetId()) + req *connect.Request[kasr.GetKeyAccessServerRequest], +) (*connect.Response[kasr.GetKeyAccessServerResponse], error) { + rsp := &kasr.GetKeyAccessServerResponse{} + + keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } - return &kasr.GetKeyAccessServerResponse{ - KeyAccessServer: keyAccessServer, - }, nil + rsp.KeyAccessServer = keyAccessServer + + return &connect.Response[kasr.GetKeyAccessServerResponse]{Msg: rsp}, nil } func (s KeyAccessServerRegistry) UpdateKeyAccessServer(ctx context.Context, - req *kasr.UpdateKeyAccessServerRequest, -) (*kasr.UpdateKeyAccessServerResponse, error) { - kasID := req.GetId() + req *connect.Request[kasr.UpdateKeyAccessServerRequest], +) (*connect.Response[kasr.UpdateKeyAccessServerResponse], error) { + rsp := &kasr.UpdateKeyAccessServerResponse{} + + kasID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, @@ -104,56 +111,60 @@ func (s KeyAccessServerRegistry) UpdateKeyAccessServer(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", kasID)) } - updated, err := s.dbClient.UpdateKeyAccessServer(ctx, kasID, req) + updated, err := s.dbClient.UpdateKeyAccessServer(ctx, kasID, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", kasID), slog.String("keyAccessServer", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", kasID), slog.String("keyAccessServer", req.Msg.String())) } auditParams.Original = original auditParams.Updated = updated s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &kasr.UpdateKeyAccessServerResponse{ - KeyAccessServer: &policy.KeyAccessServer{ - Id: kasID, - }, - }, nil + rsp.KeyAccessServer = &policy.KeyAccessServer{ + Id: kasID, + } + + return &connect.Response[kasr.UpdateKeyAccessServerResponse]{Msg: rsp}, nil } func (s KeyAccessServerRegistry) DeleteKeyAccessServer(ctx context.Context, - req *kasr.DeleteKeyAccessServerRequest, -) (*kasr.DeleteKeyAccessServerResponse, error) { - kasID := req.GetId() + req *connect.Request[kasr.DeleteKeyAccessServerRequest], +) (*connect.Response[kasr.DeleteKeyAccessServerResponse], error) { + rsp := &kasr.DeleteKeyAccessServerResponse{} + + kasID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeKasRegistry, ObjectID: kasID, } - _, err := s.dbClient.DeleteKeyAccessServer(ctx, req.GetId()) + _, err := s.dbClient.DeleteKeyAccessServer(ctx, req.Msg.GetId()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextDeletionFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextDeletionFailed, slog.String("id", req.Msg.GetId())) } s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &kasr.DeleteKeyAccessServerResponse{ - KeyAccessServer: &policy.KeyAccessServer{ - Id: kasID, - }, - }, nil + rsp.KeyAccessServer = &policy.KeyAccessServer{ + Id: kasID, + } + + return &connect.Response[kasr.DeleteKeyAccessServerResponse]{Msg: rsp}, nil } func (s KeyAccessServerRegistry) ListKeyAccessServerGrants(ctx context.Context, - req *kasr.ListKeyAccessServerGrantsRequest, -) (*kasr.ListKeyAccessServerGrantsResponse, error) { - keyAccessServerGrants, err := s.dbClient.ListKeyAccessServerGrants(ctx, req.GetKasId(), req.GetKasUri(), req.GetKasName()) + req *connect.Request[kasr.ListKeyAccessServerGrantsRequest], +) (*connect.Response[kasr.ListKeyAccessServerGrantsResponse], error) { + rsp := &kasr.ListKeyAccessServerGrantsResponse{} + + keyAccessServerGrants, err := s.dbClient.ListKeyAccessServerGrants(ctx, req.Msg.GetKasId(), req.Msg.GetKasUri(), req.Msg.GetKasName()) if err != nil { return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed) } - return &kasr.ListKeyAccessServerGrantsResponse{ - Grants: keyAccessServerGrants, - }, nil + rsp.Grants = keyAccessServerGrants + + return &connect.Response[kasr.ListKeyAccessServerGrantsResponse]{Msg: rsp}, nil } diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index f9ca32f53b..73666d89b7 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -5,9 +5,10 @@ import ( "fmt" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" "github.com/opentdf/platform/protocol/go/policy/namespaces" + "github.com/opentdf/platform/protocol/go/policy/namespaces/namespacesconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" @@ -21,22 +22,21 @@ type NamespacesService struct { //nolint:revive // NamespacesService is a valid logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[NamespacesService] { - return &serviceregistry.Service[NamespacesService]{ - ServiceOptions: serviceregistry.ServiceOptions[NamespacesService]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &namespaces.NamespaceService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*NamespacesService, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[namespacesconnect.NamespaceServiceHandler] { + return &serviceregistry.Service[namespacesconnect.NamespaceServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[namespacesconnect.NamespaceServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &namespaces.NamespaceService_ServiceDesc, + ConnectRPCFunc: namespacesconnect.NewNamespaceServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (namespacesconnect.NamespaceServiceHandler, serviceregistry.HandlerServer) { ns := &NamespacesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} if err := srp.RegisterReadinessCheck("policy", ns.IsReady); err != nil { srp.Logger.Error("failed to register policy readiness check", slog.String("error", err.Error())) } - return ns, func(ctx context.Context, mux *runtime.ServeMux) error { - return namespaces.RegisterNamespaceServiceHandlerServer(ctx, mux, ns) - } + return ns, nil }, }, } @@ -53,8 +53,8 @@ func (ns NamespacesService) IsReady(ctx context.Context) error { return nil } -func (ns NamespacesService) ListNamespaces(ctx context.Context, req *namespaces.ListNamespacesRequest) (*namespaces.ListNamespacesResponse, error) { - state := policydb.GetDBStateTypeTransformedEnum(req.GetState()) +func (ns NamespacesService) ListNamespaces(ctx context.Context, req *connect.Request[namespaces.ListNamespacesRequest]) (*connect.Response[namespaces.ListNamespacesResponse], error) { + state := policydb.GetDBStateTypeTransformedEnum(req.Msg.GetState()) ns.logger.Debug("listing namespaces", slog.String("state", state)) rsp := &namespaces.ListNamespacesResponse{} @@ -66,26 +66,26 @@ func (ns NamespacesService) ListNamespaces(ctx context.Context, req *namespaces. ns.logger.Debug("listed namespaces") rsp.Namespaces = list - return rsp, nil + return &connect.Response[namespaces.ListNamespacesResponse]{Msg: rsp}, nil } -func (ns NamespacesService) GetNamespace(ctx context.Context, req *namespaces.GetNamespaceRequest) (*namespaces.GetNamespaceResponse, error) { - ns.logger.Debug("getting namespace", slog.String("id", req.GetId())) +func (ns NamespacesService) GetNamespace(ctx context.Context, req *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { + ns.logger.Debug("getting namespace", slog.String("id", req.Msg.GetId())) rsp := &namespaces.GetNamespaceResponse{} - namespace, err := ns.dbClient.GetNamespace(ctx, req.GetId()) + namespace, err := ns.dbClient.GetNamespace(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, "id", req.GetId()) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, "id", req.Msg.GetId()) } rsp.Namespace = namespace - return rsp, nil + return &connect.Response[namespaces.GetNamespaceResponse]{Msg: rsp}, nil } -func (ns NamespacesService) CreateNamespace(ctx context.Context, req *namespaces.CreateNamespaceRequest) (*namespaces.CreateNamespaceResponse, error) { - ns.logger.Debug("creating new namespace", slog.String("name", req.GetName())) +func (ns NamespacesService) CreateNamespace(ctx context.Context, req *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) { + ns.logger.Debug("creating new namespace", slog.String("name", req.Msg.GetName())) auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, @@ -93,24 +93,24 @@ func (ns NamespacesService) CreateNamespace(ctx context.Context, req *namespaces } rsp := &namespaces.CreateNamespaceResponse{} - n, err := ns.dbClient.CreateNamespace(ctx, req) + n, err := ns.dbClient.CreateNamespace(ctx, req.Msg) if err != nil { ns.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("name", req.GetName())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("name", req.Msg.GetName())) } auditParams.ObjectID = n.GetId() auditParams.Original = n ns.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - ns.logger.Debug("created new namespace", slog.String("name", req.GetName())) + ns.logger.Debug("created new namespace", slog.String("name", req.Msg.GetName())) rsp.Namespace = n - return rsp, nil + return &connect.Response[namespaces.CreateNamespaceResponse]{Msg: rsp}, nil } -func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *namespaces.UpdateNamespaceRequest) (*namespaces.UpdateNamespaceResponse, error) { - namespaceID := req.GetId() +func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) { + namespaceID := req.Msg.GetId() ns.logger.Debug("updating namespace", slog.String("name", namespaceID)) rsp := &namespaces.UpdateNamespaceResponse{} @@ -126,7 +126,7 @@ func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *namespaces return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", namespaceID)) } - updated, err := ns.dbClient.UpdateNamespace(ctx, namespaceID, req) + updated, err := ns.dbClient.UpdateNamespace(ctx, namespaceID, req.Msg) if err != nil { ns.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", namespaceID)) @@ -141,11 +141,11 @@ func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *namespaces rsp.Namespace = &policy.Namespace{ Id: namespaceID, } - return rsp, nil + return &connect.Response[namespaces.UpdateNamespaceResponse]{Msg: rsp}, nil } -func (ns NamespacesService) DeactivateNamespace(ctx context.Context, req *namespaces.DeactivateNamespaceRequest) (*namespaces.DeactivateNamespaceResponse, error) { - namespaceID := req.GetId() +func (ns NamespacesService) DeactivateNamespace(ctx context.Context, req *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) { + namespaceID := req.Msg.GetId() ns.logger.Debug("deactivating namespace", slog.String("id", namespaceID)) rsp := &namespaces.DeactivateNamespaceResponse{} @@ -173,11 +173,13 @@ func (ns NamespacesService) DeactivateNamespace(ctx context.Context, req *namesp ns.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) ns.logger.Debug("soft-deleted namespace", slog.String("id", namespaceID)) - return rsp, nil + return &connect.Response[namespaces.DeactivateNamespaceResponse]{Msg: rsp}, nil } -func (ns NamespacesService) AssignKeyAccessServerToNamespace(ctx context.Context, req *namespaces.AssignKeyAccessServerToNamespaceRequest) (*namespaces.AssignKeyAccessServerToNamespaceResponse, error) { - grant := req.GetNamespaceKeyAccessServer() +func (ns NamespacesService) AssignKeyAccessServerToNamespace(ctx context.Context, req *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) { + rsp := &namespaces.AssignKeyAccessServerToNamespaceResponse{} + + grant := req.Msg.GetNamespaceKeyAccessServer() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, ObjectType: audit.ObjectTypeKasAttributeNamespaceAssignment, @@ -191,13 +193,15 @@ func (ns NamespacesService) AssignKeyAccessServerToNamespace(ctx context.Context } ns.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &namespaces.AssignKeyAccessServerToNamespaceResponse{ - NamespaceKeyAccessServer: namespaceKas, - }, nil + rsp.NamespaceKeyAccessServer = namespaceKas + + return &connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse]{Msg: rsp}, nil } -func (ns NamespacesService) RemoveKeyAccessServerFromNamespace(ctx context.Context, req *namespaces.RemoveKeyAccessServerFromNamespaceRequest) (*namespaces.RemoveKeyAccessServerFromNamespaceResponse, error) { - grant := req.GetNamespaceKeyAccessServer() +func (ns NamespacesService) RemoveKeyAccessServerFromNamespace(ctx context.Context, req *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) { + rsp := &namespaces.RemoveKeyAccessServerFromNamespaceResponse{} + + grant := req.Msg.GetNamespaceKeyAccessServer() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeKasAttributeNamespaceAssignment, @@ -211,7 +215,7 @@ func (ns NamespacesService) RemoveKeyAccessServerFromNamespace(ctx context.Conte } ns.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &namespaces.RemoveKeyAccessServerFromNamespaceResponse{ - NamespaceKeyAccessServer: namespaceKas, - }, nil + rsp.NamespaceKeyAccessServer = namespaceKas + + return &connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse]{Msg: rsp}, nil } diff --git a/service/policy/resourcemapping/resource_mapping.go b/service/policy/resourcemapping/resource_mapping.go index 54e732172e..a75cd41ff9 100644 --- a/service/policy/resourcemapping/resource_mapping.go +++ b/service/policy/resourcemapping/resource_mapping.go @@ -4,9 +4,10 @@ import ( "context" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" "github.com/opentdf/platform/protocol/go/policy/resourcemapping" + "github.com/opentdf/platform/protocol/go/policy/resourcemapping/resourcemappingconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" @@ -20,17 +21,16 @@ type ResourceMappingService struct { //nolint:revive // ResourceMappingService i logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[ResourceMappingService] { - return &serviceregistry.Service[ResourceMappingService]{ - ServiceOptions: serviceregistry.ServiceOptions[ResourceMappingService]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &resourcemapping.ResourceMappingService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*ResourceMappingService, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[resourcemappingconnect.ResourceMappingServiceHandler] { + return &serviceregistry.Service[resourcemappingconnect.ResourceMappingServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[resourcemappingconnect.ResourceMappingServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &resourcemapping.ResourceMappingService_ServiceDesc, + ConnectRPCFunc: resourcemappingconnect.NewResourceMappingServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (resourcemappingconnect.ResourceMappingServiceHandler, serviceregistry.HandlerServer) { rm := &ResourceMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return rm, func(ctx context.Context, mux *runtime.ServeMux) error { - return resourcemapping.RegisterResourceMappingServiceHandlerServer(ctx, mux, rm) - } + return rm, nil }, }, } @@ -40,51 +40,59 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer Resource Mapping Groups */ -func (s ResourceMappingService) ListResourceMappingGroups(ctx context.Context, req *resourcemapping.ListResourceMappingGroupsRequest) (*resourcemapping.ListResourceMappingGroupsResponse, error) { - rmGroups, err := s.dbClient.ListResourceMappingGroups(ctx, req) +func (s ResourceMappingService) ListResourceMappingGroups(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingGroupsRequest]) (*connect.Response[resourcemapping.ListResourceMappingGroupsResponse], error) { + rsp := &resourcemapping.ListResourceMappingGroupsResponse{} + + rmGroups, err := s.dbClient.ListResourceMappingGroups(ctx, req.Msg) if err != nil { return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed) } - return &resourcemapping.ListResourceMappingGroupsResponse{ - ResourceMappingGroups: rmGroups, - }, nil + rsp.ResourceMappingGroups = rmGroups + + return &connect.Response[resourcemapping.ListResourceMappingGroupsResponse]{Msg: rsp}, nil } -func (s ResourceMappingService) GetResourceMappingGroup(ctx context.Context, req *resourcemapping.GetResourceMappingGroupRequest) (*resourcemapping.GetResourceMappingGroupResponse, error) { - rmGroup, err := s.dbClient.GetResourceMappingGroup(ctx, req.GetId()) +func (s ResourceMappingService) GetResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) { + rsp := &resourcemapping.GetResourceMappingGroupResponse{} + + rmGroup, err := s.dbClient.GetResourceMappingGroup(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } - return &resourcemapping.GetResourceMappingGroupResponse{ - ResourceMappingGroup: rmGroup, - }, nil + rsp.ResourceMappingGroup = rmGroup + + return &connect.Response[resourcemapping.GetResourceMappingGroupResponse]{Msg: rsp}, nil } -func (s ResourceMappingService) CreateResourceMappingGroup(ctx context.Context, req *resourcemapping.CreateResourceMappingGroupRequest) (*resourcemapping.CreateResourceMappingGroupResponse, error) { +func (s ResourceMappingService) CreateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) { + rsp := &resourcemapping.CreateResourceMappingGroupResponse{} + auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, ObjectType: audit.ObjectTypeResourceMappingGroup, } - rmGroup, err := s.dbClient.CreateResourceMappingGroup(ctx, req) + rmGroup, err := s.dbClient.CreateResourceMappingGroup(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("resourceMappingGroup", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("resourceMappingGroup", req.Msg.String())) } auditParams.ObjectID = rmGroup.GetId() auditParams.Original = rmGroup s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.CreateResourceMappingGroupResponse{ - ResourceMappingGroup: rmGroup, - }, nil + rsp.ResourceMappingGroup = rmGroup + + return &connect.Response[resourcemapping.CreateResourceMappingGroupResponse]{Msg: rsp}, nil } -func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, req *resourcemapping.UpdateResourceMappingGroupRequest) (*resourcemapping.UpdateResourceMappingGroupResponse, error) { - id := req.GetId() +func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) { + rsp := &resourcemapping.UpdateResourceMappingGroupResponse{} + + id := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, @@ -98,7 +106,7 @@ func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - updatedRmGroup, err := s.dbClient.UpdateResourceMappingGroup(ctx, id, req) + updatedRmGroup, err := s.dbClient.UpdateResourceMappingGroup(ctx, id, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", id)) @@ -109,15 +117,17 @@ func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.UpdateResourceMappingGroupResponse{ - ResourceMappingGroup: &policy.ResourceMappingGroup{ - Id: id, - }, - }, nil + rsp.ResourceMappingGroup = &policy.ResourceMappingGroup{ + Id: id, + } + + return &connect.Response[resourcemapping.UpdateResourceMappingGroupResponse]{Msg: rsp}, nil } -func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, req *resourcemapping.DeleteResourceMappingGroupRequest) (*resourcemapping.DeleteResourceMappingGroupResponse, error) { - id := req.GetId() +func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) { + rsp := &resourcemapping.DeleteResourceMappingGroupResponse{} + + id := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, @@ -133,11 +143,11 @@ func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.DeleteResourceMappingGroupResponse{ - ResourceMappingGroup: &policy.ResourceMappingGroup{ - Id: id, - }, - }, nil + rsp.ResourceMappingGroup = &policy.ResourceMappingGroup{ + Id: id, + } + + return &connect.Response[resourcemapping.DeleteResourceMappingGroupResponse]{Msg: rsp}, nil } /* @@ -145,47 +155,55 @@ func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, */ func (s ResourceMappingService) ListResourceMappings(ctx context.Context, - req *resourcemapping.ListResourceMappingsRequest, -) (*resourcemapping.ListResourceMappingsResponse, error) { - resourceMappings, err := s.dbClient.ListResourceMappings(ctx, req) + req *connect.Request[resourcemapping.ListResourceMappingsRequest], +) (*connect.Response[resourcemapping.ListResourceMappingsResponse], error) { + rsp := &resourcemapping.ListResourceMappingsResponse{} + + resourceMappings, err := s.dbClient.ListResourceMappings(ctx, req.Msg) if err != nil { return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed) } - return &resourcemapping.ListResourceMappingsResponse{ - ResourceMappings: resourceMappings, - }, nil + rsp.ResourceMappings = resourceMappings + + return &connect.Response[resourcemapping.ListResourceMappingsResponse]{Msg: rsp}, nil } -func (s ResourceMappingService) ListResourceMappingsByGroupFqns(ctx context.Context, req *resourcemapping.ListResourceMappingsByGroupFqnsRequest) (*resourcemapping.ListResourceMappingsByGroupFqnsResponse, error) { - fqns := req.GetFqns() +func (s ResourceMappingService) ListResourceMappingsByGroupFqns(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) { + rsp := &resourcemapping.ListResourceMappingsByGroupFqnsResponse{} + + fqns := req.Msg.GetFqns() fqnRmGroupMap, err := s.dbClient.ListResourceMappingsByGroupFqns(ctx, fqns) if err != nil { return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed, slog.Any("fqns", fqns)) } - return &resourcemapping.ListResourceMappingsByGroupFqnsResponse{ - FqnResourceMappingGroups: fqnRmGroupMap, - }, nil + rsp.FqnResourceMappingGroups = fqnRmGroupMap + + return &connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse]{Msg: rsp}, nil } func (s ResourceMappingService) GetResourceMapping(ctx context.Context, - req *resourcemapping.GetResourceMappingRequest, -) (*resourcemapping.GetResourceMappingResponse, error) { - rm, err := s.dbClient.GetResourceMapping(ctx, req.GetId()) + req *connect.Request[resourcemapping.GetResourceMappingRequest], +) (*connect.Response[resourcemapping.GetResourceMappingResponse], error) { + rsp := &resourcemapping.GetResourceMappingResponse{} + + rm, err := s.dbClient.GetResourceMapping(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } - return &resourcemapping.GetResourceMappingResponse{ - ResourceMapping: rm, - }, nil + rsp.ResourceMapping = rm + + return &connect.Response[resourcemapping.GetResourceMappingResponse]{Msg: rsp}, nil } func (s ResourceMappingService) CreateResourceMapping(ctx context.Context, - req *resourcemapping.CreateResourceMappingRequest, -) (*resourcemapping.CreateResourceMappingResponse, error) { + req *connect.Request[resourcemapping.CreateResourceMappingRequest], +) (*connect.Response[resourcemapping.CreateResourceMappingResponse], error) { + rsp := &resourcemapping.CreateResourceMappingResponse{} + s.logger.Debug("creating resource mapping") auditParams := audit.PolicyEventParams{ @@ -193,25 +211,27 @@ func (s ResourceMappingService) CreateResourceMapping(ctx context.Context, ObjectType: audit.ObjectTypeResourceMapping, } - rm, err := s.dbClient.CreateResourceMapping(ctx, req) + rm, err := s.dbClient.CreateResourceMapping(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("resourceMapping", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("resourceMapping", req.Msg.String())) } auditParams.ObjectID = rm.GetId() auditParams.Original = rm s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.CreateResourceMappingResponse{ - ResourceMapping: rm, - }, nil + rsp.ResourceMapping = rm + + return &connect.Response[resourcemapping.CreateResourceMappingResponse]{Msg: rsp}, nil } func (s ResourceMappingService) UpdateResourceMapping(ctx context.Context, - req *resourcemapping.UpdateResourceMappingRequest, -) (*resourcemapping.UpdateResourceMappingResponse, error) { - resourceMappingID := req.GetId() + req *connect.Request[resourcemapping.UpdateResourceMappingRequest], +) (*connect.Response[resourcemapping.UpdateResourceMappingResponse], error) { + rsp := &resourcemapping.UpdateResourceMappingResponse{} + + resourceMappingID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, @@ -225,12 +245,12 @@ func (s ResourceMappingService) UpdateResourceMapping(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextListRetrievalFailed) } - updatedRM, err := s.dbClient.UpdateResourceMapping(ctx, resourceMappingID, req) + updatedRM, err := s.dbClient.UpdateResourceMapping(ctx, resourceMappingID, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, - slog.String("id", req.GetId()), - slog.String("resourceMapping", req.String()), + slog.String("id", req.Msg.GetId()), + slog.String("resourceMapping", req.Msg.String()), ) } @@ -238,17 +258,19 @@ func (s ResourceMappingService) UpdateResourceMapping(ctx context.Context, auditParams.Updated = updatedRM s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.UpdateResourceMappingResponse{ - ResourceMapping: &policy.ResourceMapping{ - Id: resourceMappingID, - }, - }, nil + rsp.ResourceMapping = &policy.ResourceMapping{ + Id: resourceMappingID, + } + + return &connect.Response[resourcemapping.UpdateResourceMappingResponse]{Msg: rsp}, nil } func (s ResourceMappingService) DeleteResourceMapping(ctx context.Context, - req *resourcemapping.DeleteResourceMappingRequest, -) (*resourcemapping.DeleteResourceMappingResponse, error) { - resourceMappingID := req.GetId() + req *connect.Request[resourcemapping.DeleteResourceMappingRequest], +) (*connect.Response[resourcemapping.DeleteResourceMappingResponse], error) { + rsp := &resourcemapping.DeleteResourceMappingResponse{} + + resourceMappingID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, @@ -264,9 +286,9 @@ func (s ResourceMappingService) DeleteResourceMapping(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - return &resourcemapping.DeleteResourceMappingResponse{ - ResourceMapping: &policy.ResourceMapping{ - Id: resourceMappingID, - }, - }, nil + rsp.ResourceMapping = &policy.ResourceMapping{ + Id: resourceMappingID, + } + + return &connect.Response[resourcemapping.DeleteResourceMappingResponse]{Msg: rsp}, nil } diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index a44842a181..0b7b335abf 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -4,9 +4,11 @@ import ( "context" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" + "github.com/opentdf/platform/protocol/go/policy/subjectmapping" sm "github.com/opentdf/platform/protocol/go/policy/subjectmapping" + "github.com/opentdf/platform/protocol/go/policy/subjectmapping/subjectmappingconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" @@ -20,17 +22,16 @@ type SubjectMappingService struct { //nolint:revive // SubjectMappingService is logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[SubjectMappingService] { - return &serviceregistry.Service[SubjectMappingService]{ - ServiceOptions: serviceregistry.ServiceOptions[SubjectMappingService]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &sm.SubjectMappingService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*SubjectMappingService, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[subjectmappingconnect.SubjectMappingServiceHandler] { + return &serviceregistry.Service[subjectmappingconnect.SubjectMappingServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[subjectmappingconnect.SubjectMappingServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &sm.SubjectMappingService_ServiceDesc, + ConnectRPCFunc: subjectmappingconnect.NewSubjectMappingServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (subjectmappingconnect.SubjectMappingServiceHandler, serviceregistry.HandlerServer) { smSvc := &SubjectMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return smSvc, func(ctx context.Context, mux *runtime.ServeMux) error { - return sm.RegisterSubjectMappingServiceHandlerServer(ctx, mux, smSvc) - } + return smSvc, nil }, }, } @@ -41,8 +42,8 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer * --------------------------------------------------*/ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, - req *sm.CreateSubjectMappingRequest, -) (*sm.CreateSubjectMappingResponse, error) { + req *connect.Request[subjectmapping.CreateSubjectMappingRequest], +) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) { rsp := &sm.CreateSubjectMappingResponse{} s.logger.Debug("creating subject mapping") @@ -54,7 +55,7 @@ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, sm, err := s.dbClient.CreateSubjectMapping(ctx, req) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectMapping", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectMapping", req.Msg.String())) } auditParams.ObjectID = sm.GetId() @@ -62,12 +63,12 @@ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.SubjectMapping = sm - return rsp, nil + return &connect.Response[subjectmapping.CreateSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, - _ *sm.ListSubjectMappingsRequest, -) (*sm.ListSubjectMappingsResponse, error) { + _ *connect.Request[subjectmapping.ListSubjectMappingsRequest], +) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) { rsp := &sm.ListSubjectMappingsResponse{} s.logger.Debug("listing subject mappings") @@ -77,31 +78,31 @@ func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, } rsp.SubjectMappings = mappings - return rsp, nil + return &connect.Response[subjectmapping.ListSubjectMappingsResponse]{Msg: rsp}, nil } func (s SubjectMappingService) GetSubjectMapping(ctx context.Context, - req *sm.GetSubjectMappingRequest, -) (*sm.GetSubjectMappingResponse, error) { + req *connect.Request[subjectmapping.GetSubjectMappingRequest], +) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) { rsp := &sm.GetSubjectMappingResponse{} - s.logger.Debug("getting subject mapping", slog.String("id", req.GetId())) + s.logger.Debug("getting subject mapping", slog.String("id", req.Msg.GetId())) - mapping, err := s.dbClient.GetSubjectMapping(ctx, req.GetId()) + mapping, err := s.dbClient.GetSubjectMapping(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } rsp.SubjectMapping = mapping - return rsp, nil + return &connect.Response[subjectmapping.GetSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, - req *sm.UpdateSubjectMappingRequest, -) (*sm.UpdateSubjectMappingResponse, error) { + req *connect.Request[subjectmapping.UpdateSubjectMappingRequest], +) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) { rsp := &sm.UpdateSubjectMappingResponse{} - subjectMappingID := req.GetId() + subjectMappingID := req.Msg.GetId() - s.logger.Debug("updating subject mapping", slog.String("subjectMapping", req.String())) + s.logger.Debug("updating subject mapping", slog.String("subjectMapping", req.Msg.String())) auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, @@ -115,10 +116,10 @@ func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", subjectMappingID)) } - updated, err := s.dbClient.UpdateSubjectMapping(ctx, req) + updated, err := s.dbClient.UpdateSubjectMapping(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.GetId()), slog.String("subjectMapping fields", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.Msg.GetId()), slog.String("subjectMapping fields", req.Msg.String())) } auditParams.Original = original @@ -128,16 +129,16 @@ func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return rsp, nil + return &connect.Response[subjectmapping.UpdateSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, - req *sm.DeleteSubjectMappingRequest, -) (*sm.DeleteSubjectMappingResponse, error) { + req *connect.Request[subjectmapping.DeleteSubjectMappingRequest], +) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) { rsp := &sm.DeleteSubjectMappingResponse{} - s.logger.Debug("deleting subject mapping", slog.String("id", req.GetId())) + s.logger.Debug("deleting subject mapping", slog.String("id", req.Msg.GetId())) - subjectMappingID := req.GetId() + subjectMappingID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeSubjectMapping, @@ -155,22 +156,22 @@ func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return rsp, nil + return &connect.Response[subjectmapping.DeleteSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, - req *sm.MatchSubjectMappingsRequest, -) (*sm.MatchSubjectMappingsResponse, error) { + req *connect.Request[subjectmapping.MatchSubjectMappingsRequest], +) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) { rsp := &sm.MatchSubjectMappingsResponse{} - s.logger.Debug("matching subject mappings", slog.Any("subjectProperties", req.GetSubjectProperties())) + s.logger.Debug("matching subject mappings", slog.Any("subjectProperties", req.Msg.GetSubjectProperties())) - smList, err := s.dbClient.GetMatchedSubjectMappings(ctx, req.GetSubjectProperties()) + smList, err := s.dbClient.GetMatchedSubjectMappings(ctx, req.Msg.GetSubjectProperties()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("subjectProperties", req.GetSubjectProperties())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("subjectProperties", req.Msg.GetSubjectProperties())) } rsp.SubjectMappings = smList - return rsp, nil + return &connect.Response[subjectmapping.MatchSubjectMappingsResponse]{Msg: rsp}, nil } /* -------------------------------------------------------- @@ -178,23 +179,23 @@ func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, * -------------------------------------------------------*/ func (s SubjectMappingService) GetSubjectConditionSet(ctx context.Context, - req *sm.GetSubjectConditionSetRequest, -) (*sm.GetSubjectConditionSetResponse, error) { + req *connect.Request[subjectmapping.GetSubjectConditionSetRequest], +) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) { rsp := &sm.GetSubjectConditionSetResponse{} - s.logger.Debug("getting subject condition set", slog.String("id", req.GetId())) + s.logger.Debug("getting subject condition set", slog.String("id", req.Msg.GetId())) - conditionSet, err := s.dbClient.GetSubjectConditionSet(ctx, req.GetId()) + conditionSet, err := s.dbClient.GetSubjectConditionSet(ctx, req.Msg.GetId()) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) } rsp.SubjectConditionSet = conditionSet - return rsp, nil + return &connect.Response[subjectmapping.GetSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, - _ *sm.ListSubjectConditionSetsRequest, -) (*sm.ListSubjectConditionSetsResponse, error) { + _ *connect.Request[subjectmapping.ListSubjectConditionSetsRequest], +) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) { rsp := &sm.ListSubjectConditionSetsResponse{} s.logger.Debug("listing subject condition sets") @@ -204,24 +205,24 @@ func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, } rsp.SubjectConditionSets = conditionSets - return rsp, nil + return &connect.Response[subjectmapping.ListSubjectConditionSetsResponse]{Msg: rsp}, nil } func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, - req *sm.CreateSubjectConditionSetRequest, -) (*sm.CreateSubjectConditionSetResponse, error) { + req *connect.Request[subjectmapping.CreateSubjectConditionSetRequest], +) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) { rsp := &sm.CreateSubjectConditionSetResponse{} - s.logger.Debug("creating subject condition set", slog.String("subjectConditionSet", req.String())) + s.logger.Debug("creating subject condition set", slog.String("subjectConditionSet", req.Msg.String())) auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeCreate, ObjectType: audit.ObjectTypeConditionSet, } - conditionSet, err := s.dbClient.CreateSubjectConditionSet(ctx, req.GetSubjectConditionSet()) + conditionSet, err := s.dbClient.CreateSubjectConditionSet(ctx, req.Msg.GetSubjectConditionSet()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectConditionSet", req.String())) + return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectConditionSet", req.Msg.String())) } auditParams.ObjectID = conditionSet.GetId() @@ -229,16 +230,16 @@ func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.SubjectConditionSet = conditionSet - return rsp, nil + return &connect.Response[subjectmapping.CreateSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, - req *sm.UpdateSubjectConditionSetRequest, -) (*sm.UpdateSubjectConditionSetResponse, error) { + req *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest], +) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) { rsp := &sm.UpdateSubjectConditionSetResponse{} - s.logger.Debug("updating subject condition set", slog.String("subjectConditionSet", req.String())) + s.logger.Debug("updating subject condition set", slog.String("subjectConditionSet", req.Msg.String())) - subjectConditionSetID := req.GetId() + subjectConditionSetID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeUpdate, ObjectType: audit.ObjectTypeConditionSet, @@ -251,10 +252,10 @@ func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", subjectConditionSetID)) } - updated, err := s.dbClient.UpdateSubjectConditionSet(ctx, req) + updated, err := s.dbClient.UpdateSubjectConditionSet(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.GetId()), slog.String("subjectConditionSet fields", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", req.Msg.GetId()), slog.String("subjectConditionSet fields", req.Msg.String())) } auditParams.Original = original @@ -264,16 +265,16 @@ func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: subjectConditionSetID, } - return rsp, nil + return &connect.Response[subjectmapping.UpdateSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, - req *sm.DeleteSubjectConditionSetRequest, -) (*sm.DeleteSubjectConditionSetResponse, error) { + req *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest], +) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { rsp := &sm.DeleteSubjectConditionSetResponse{} s.logger.Debug("deleting subject condition set", slog.String("id", req.GetId())) - conditionSetID := req.GetId() + conditionSetID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ ActionType: audit.ActionTypeDelete, ObjectType: audit.ObjectTypeConditionSet, @@ -291,5 +292,5 @@ func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: conditionSetID, } - return rsp, nil + return &connect.Response[subjectmapping.DeleteSubjectConditionSetResponse]{Msg: rsp}, nil } diff --git a/service/policy/unsafe/unsafe.go b/service/policy/unsafe/unsafe.go index ed1f2700ec..531ed668f0 100644 --- a/service/policy/unsafe/unsafe.go +++ b/service/policy/unsafe/unsafe.go @@ -4,9 +4,10 @@ import ( "context" "log/slog" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" "github.com/opentdf/platform/protocol/go/policy/unsafe" + "github.com/opentdf/platform/protocol/go/policy/unsafe/unsafeconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/logger/audit" "github.com/opentdf/platform/service/pkg/db" @@ -20,17 +21,16 @@ type UnsafeService struct { //nolint:revive // UnsafeService is a valid name for logger *logger.Logger } -func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[UnsafeService] { - return &serviceregistry.Service[UnsafeService]{ - ServiceOptions: serviceregistry.ServiceOptions[UnsafeService]{ - Namespace: ns, - DB: dbRegister, - ServiceDesc: &unsafe.UnsafeService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*UnsafeService, serviceregistry.HandlerServer) { +func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[unsafeconnect.UnsafeServiceHandler] { + return &serviceregistry.Service[unsafeconnect.UnsafeServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[unsafeconnect.UnsafeServiceHandler]{ + Namespace: ns, + DB: dbRegister, + ServiceDesc: &unsafe.UnsafeService_ServiceDesc, + ConnectRPCFunc: unsafeconnect.NewUnsafeServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (unsafeconnect.UnsafeServiceHandler, serviceregistry.HandlerServer) { unsafeSvc := &UnsafeService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return unsafeSvc, func(ctx context.Context, mux *runtime.ServeMux) error { - return unsafe.RegisterUnsafeServiceHandlerServer(ctx, mux, unsafeSvc) - } + return unsafeSvc, nil }, }, } @@ -40,9 +40,9 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer // Unsafe Namespace RPCs // -func (s *UnsafeService) UnsafeUpdateNamespace(ctx context.Context, req *unsafe.UnsafeUpdateNamespaceRequest) (*unsafe.UnsafeUpdateNamespaceResponse, error) { - id := req.GetId() - name := req.GetName() +func (s *UnsafeService) UnsafeUpdateNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateNamespaceRequest]) (*connect.Response[unsafe.UnsafeUpdateNamespaceResponse], error) { + id := req.Msg.GetId() + name := req.Msg.GetName() rsp := &unsafe.UnsafeUpdateNamespaceResponse{} @@ -73,11 +73,11 @@ func (s *UnsafeService) UnsafeUpdateNamespace(ctx context.Context, req *unsafe.U Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeUpdateNamespaceResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeReactivateNamespace(ctx context.Context, req *unsafe.UnsafeReactivateNamespaceRequest) (*unsafe.UnsafeReactivateNamespaceResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeReactivateNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeReactivateNamespaceResponse{} @@ -108,11 +108,11 @@ func (s *UnsafeService) UnsafeReactivateNamespace(ctx context.Context, req *unsa Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeReactivateNamespaceResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *unsafe.UnsafeDeleteNamespaceRequest) (*unsafe.UnsafeDeleteNamespaceResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeDeleteNamespaceResponse{} @@ -128,7 +128,7 @@ func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *unsafe.U return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - _, err = s.dbClient.UnsafeDeleteNamespace(ctx, existing, req.GetFqn()) + _, err = s.dbClient.UnsafeDeleteNamespace(ctx, existing, req.Msg.GetFqn()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextDeletionFailed, slog.String("id", id)) @@ -140,15 +140,15 @@ func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *unsafe.U Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeDeleteNamespaceResponse]{Msg: rsp}, nil } // // Unsafe Attribute Definition RPCs // -func (s *UnsafeService) UnsafeUpdateAttribute(ctx context.Context, req *unsafe.UnsafeUpdateAttributeRequest) (*unsafe.UnsafeUpdateAttributeResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeUpdateAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateAttributeRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeUpdateAttributeResponse{} @@ -164,10 +164,10 @@ func (s *UnsafeService) UnsafeUpdateAttribute(ctx context.Context, req *unsafe.U return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - updated, err := s.dbClient.UnsafeUpdateAttribute(ctx, req) + updated, err := s.dbClient.UnsafeUpdateAttribute(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", id), slog.String("attribute", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", id), slog.String("attribute", req.Msg.String())) } auditParams.Original = original @@ -179,11 +179,11 @@ func (s *UnsafeService) UnsafeUpdateAttribute(ctx context.Context, req *unsafe.U Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeUpdateAttributeResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeReactivateAttribute(ctx context.Context, req *unsafe.UnsafeReactivateAttributeRequest) (*unsafe.UnsafeReactivateAttributeResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeReactivateAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeReactivateAttributeResponse{} @@ -214,11 +214,11 @@ func (s *UnsafeService) UnsafeReactivateAttribute(ctx context.Context, req *unsa Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeReactivateAttributeResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *unsafe.UnsafeDeleteAttributeRequest) (*unsafe.UnsafeDeleteAttributeResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeDeleteAttributeResponse{} @@ -234,7 +234,7 @@ func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *unsafe.U return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - _, err = s.dbClient.UnsafeDeleteAttribute(ctx, existing, req.GetFqn()) + _, err = s.dbClient.UnsafeDeleteAttribute(ctx, existing, req.Msg.GetFqn()) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextDeletionFailed, slog.String("id", id)) @@ -246,15 +246,15 @@ func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *unsafe.U Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeDeleteAttributeResponse]{Msg: rsp}, nil } // // Unsafe Attribute Value RPCs // -func (s *UnsafeService) UnsafeUpdateAttributeValue(ctx context.Context, req *unsafe.UnsafeUpdateAttributeValueRequest) (*unsafe.UnsafeUpdateAttributeValueResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeUpdateAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeUpdateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeUpdateAttributeValueResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeUpdateAttributeValueResponse{} @@ -270,10 +270,10 @@ func (s *UnsafeService) UnsafeUpdateAttributeValue(ctx context.Context, req *uns return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - updated, err := s.dbClient.UnsafeUpdateAttributeValue(ctx, req) + updated, err := s.dbClient.UnsafeUpdateAttributeValue(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) - return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", id), slog.String("attribute_value", req.String())) + return nil, db.StatusifyError(err, db.ErrTextUpdateFailed, slog.String("id", id), slog.String("attribute_value", req.Msg.String())) } auditParams.Original = original @@ -284,11 +284,11 @@ func (s *UnsafeService) UnsafeUpdateAttributeValue(ctx context.Context, req *uns rsp.Value = &policy.Value{ Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeUpdateAttributeValueResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeReactivateAttributeValue(ctx context.Context, req *unsafe.UnsafeReactivateAttributeValueRequest) (*unsafe.UnsafeReactivateAttributeValueResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeReactivateAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeReactivateAttributeValueResponse{} @@ -318,11 +318,11 @@ func (s *UnsafeService) UnsafeReactivateAttributeValue(ctx context.Context, req rsp.Value = &policy.Value{ Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeReactivateAttributeValueResponse]{Msg: rsp}, nil } -func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *unsafe.UnsafeDeleteAttributeValueRequest) (*unsafe.UnsafeDeleteAttributeValueResponse, error) { - id := req.GetId() +func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) { + id := req.Msg.GetId() rsp := &unsafe.UnsafeDeleteAttributeValueResponse{} @@ -338,7 +338,7 @@ func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *uns return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", id)) } - _, err = s.dbClient.UnsafeDeleteAttributeValue(ctx, existing, req) + _, err = s.dbClient.UnsafeDeleteAttributeValue(ctx, existing, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextDeletionFailed, slog.String("id", id)) @@ -349,5 +349,5 @@ func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *uns rsp.Value = &policy.Value{ Id: id, } - return rsp, nil + return &connect.Response[unsafe.UnsafeDeleteAttributeValueResponse]{Msg: rsp}, nil } diff --git a/service/wellknownconfiguration/wellknown_configuration.go b/service/wellknownconfiguration/wellknown_configuration.go index bbfb34e3ad..1377e19d5e 100644 --- a/service/wellknownconfiguration/wellknown_configuration.go +++ b/service/wellknownconfiguration/wellknown_configuration.go @@ -6,8 +6,9 @@ import ( "log/slog" "sync" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "connectrpc.com/connect" wellknown "github.com/opentdf/platform/protocol/go/wellknownconfiguration" + "github.com/opentdf/platform/protocol/go/wellknownconfiguration/wellknownconfigurationconnect" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/serviceregistry" "google.golang.org/grpc/codes" @@ -35,22 +36,21 @@ func RegisterConfiguration(namespace string, config any) error { return nil } -func NewRegistration() *serviceregistry.Service[WellKnownService] { - return &serviceregistry.Service[WellKnownService]{ - ServiceOptions: serviceregistry.ServiceOptions[WellKnownService]{ - Namespace: "wellknown", - ServiceDesc: &wellknown.WellKnownService_ServiceDesc, - RegisterFunc: func(srp serviceregistry.RegistrationParams) (*WellKnownService, serviceregistry.HandlerServer) { +func NewRegistration() *serviceregistry.Service[wellknownconfigurationconnect.WellKnownServiceHandler] { + return &serviceregistry.Service[wellknownconfigurationconnect.WellKnownServiceHandler]{ + ServiceOptions: serviceregistry.ServiceOptions[wellknownconfigurationconnect.WellKnownServiceHandler]{ + Namespace: "wellknown", + ServiceDesc: &wellknown.WellKnownService_ServiceDesc, + ConnectRPCFunc: wellknownconfigurationconnect.NewWellKnownServiceHandler, + RegisterFunc: func(srp serviceregistry.RegistrationParams) (wellknownconfigurationconnect.WellKnownServiceHandler, serviceregistry.HandlerServer) { wk := &WellKnownService{logger: srp.Logger} - return wk, func(ctx context.Context, mux *runtime.ServeMux) error { - return wellknown.RegisterWellKnownServiceHandlerServer(ctx, mux, wk) - } + return wk, nil }, }, } } -func (s WellKnownService) GetWellKnownConfiguration(_ context.Context, _ *wellknown.GetWellKnownConfigurationRequest) (*wellknown.GetWellKnownConfigurationResponse, error) { +func (s WellKnownService) GetWellKnownConfiguration(_ context.Context, _ *connect.Request[wellknown.GetWellKnownConfigurationRequest]) (*connect.Response[wellknown.GetWellKnownConfigurationResponse], error) { rwMutex.RLock() cfg, err := structpb.NewStruct(wellKnownConfiguration) rwMutex.RUnlock() @@ -59,7 +59,8 @@ func (s WellKnownService) GetWellKnownConfiguration(_ context.Context, _ *wellkn return nil, status.Error(codes.Internal, "failed to create struct for wellknown configuration") } - return &wellknown.GetWellKnownConfigurationResponse{ + rsp := &wellknown.GetWellKnownConfigurationResponse{ Configuration: cfg, - }, nil + } + return &connect.Response[wellknown.GetWellKnownConfigurationResponse]{Msg: rsp}, nil } From 2ed810efec8f88644e9f60fe4358e2ccdab5848f Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 19:00:56 -0500 Subject: [PATCH 17/37] convert last method --- service/kas/kas.go | 5 ++++- service/policy/attributes/attributes.go | 5 ++++- service/policy/subjectmapping/subject_mapping.go | 10 +++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/service/kas/kas.go b/service/kas/kas.go index 386507e8f5..d67de72046 100644 --- a/service/kas/kas.go +++ b/service/kas/kas.go @@ -82,7 +82,10 @@ func NewRegistration() *serviceregistry.Service[kasconnect.AccessServiceHandler] srp.Logger.Error("failed to register kas readiness check", slog.String("error", err.Error())) } - return p, func(_ context.Context, _ *http.ServeMux) error { + return p, func(_ context.Context, mux *http.ServeMux) error { + mux.HandleFunc(fmt.Sprintf("%s /kas/kas_public_key", http.MethodGet), p.LegacyPublicKeyHandler) + mux.HandleFunc(fmt.Sprintf("%s /kas/v2/kas_public_key", http.MethodGet), p.PublicKeyHandler) + mux.HandleFunc(fmt.Sprintf("%s /kas/v2/rewrap", http.MethodPost), p.RewrapHandler) return nil } }, diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 0686c2d231..2e40a53e4a 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -33,7 +33,10 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer ConnectRPCFunc: attributesconnect.NewAttributesServiceHandler, RegisterFunc: func(srp serviceregistry.RegistrationParams) (attributesconnect.AttributesServiceHandler, serviceregistry.HandlerServer) { as := &AttributesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return as, nil + return as, func(_ context.Context, mux *http.ServeMux) error { + mux.HandleFunc(fmt.Sprintf("%s /attributes/*/fqn", http.MethodGet), as.GetAttributeValuesByFqnsHandler) + return nil + } }, }, } diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index 73cfd3664d..dc8cbe8c83 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -52,7 +52,7 @@ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, ObjectType: audit.ObjectTypeSubjectMapping, } - sm, err := s.dbClient.CreateSubjectMapping(ctx, req) + sm, err := s.dbClient.CreateSubjectMapping(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectMapping", req.Msg.String())) @@ -272,7 +272,7 @@ func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, req *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest], ) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { rsp := &sm.DeleteSubjectConditionSetResponse{} - s.logger.Debug("deleting subject condition set", slog.String("id", req.GetId())) + s.logger.Debug("deleting subject condition set", slog.String("id", req.Msg.GetId())) conditionSetID := req.Msg.GetId() auditParams := audit.PolicyEventParams{ @@ -296,8 +296,8 @@ func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, } func (s SubjectMappingService) DeleteAllUnmappedSubjectConditionSets(ctx context.Context, - _ *sm.DeleteAllUnmappedSubjectConditionSetsRequest, -) (*sm.DeleteAllUnmappedSubjectConditionSetsResponse, error) { + _ *connect.Request[sm.DeleteAllUnmappedSubjectConditionSetsRequest], +) (*connect.Response[sm.DeleteAllUnmappedSubjectConditionSetsResponse], error) { rsp := &sm.DeleteAllUnmappedSubjectConditionSetsResponse{} s.logger.Debug("deleting all unmapped subject condition sets") @@ -319,5 +319,5 @@ func (s SubjectMappingService) DeleteAllUnmappedSubjectConditionSets(ctx context } rsp.SubjectConditionSets = deleted - return rsp, nil + return &connect.Response[sm.DeleteAllUnmappedSubjectConditionSetsResponse]{Msg: rsp}, nil } From 4e647bd7045fad2cec75ca43183648c19ac080a9 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 19:02:13 -0500 Subject: [PATCH 18/37] go.mod update --- service/go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service/go.mod b/service/go.mod index 997bbb88a7..9b3706aa75 100644 --- a/service/go.mod +++ b/service/go.mod @@ -15,8 +15,6 @@ require ( github.com/go-chi/cors v1.2.1 github.com/go-playground/validator/v10 v10.22.0 github.com/google/uuid v1.6.0 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/jackc/pgx/v5 v5.5.5 github.com/lestrrat-go/jwx/v2 v2.0.21 @@ -62,6 +60,8 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/gowebpki/jcs v1.0.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect From 32b6134ab81c65295dd1b53f7c844f4a25dbe756 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 19:24:03 -0500 Subject: [PATCH 19/37] fix lint errors --- .../policy/subjectmapping/subject_mapping.go | 75 +++++++++---------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index dc8cbe8c83..10799718b8 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -6,7 +6,6 @@ import ( "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" - "github.com/opentdf/platform/protocol/go/policy/subjectmapping" sm "github.com/opentdf/platform/protocol/go/policy/subjectmapping" "github.com/opentdf/platform/protocol/go/policy/subjectmapping/subjectmappingconnect" "github.com/opentdf/platform/service/logger" @@ -42,8 +41,8 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer * --------------------------------------------------*/ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, - req *connect.Request[subjectmapping.CreateSubjectMappingRequest], -) (*connect.Response[subjectmapping.CreateSubjectMappingResponse], error) { + req *connect.Request[sm.CreateSubjectMappingRequest], +) (*connect.Response[sm.CreateSubjectMappingResponse], error) { rsp := &sm.CreateSubjectMappingResponse{} s.logger.Debug("creating subject mapping") @@ -52,23 +51,23 @@ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, ObjectType: audit.ObjectTypeSubjectMapping, } - sm, err := s.dbClient.CreateSubjectMapping(ctx, req.Msg) + subjectMapping, err := s.dbClient.CreateSubjectMapping(ctx, req.Msg) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextCreationFailed, slog.String("subjectMapping", req.Msg.String())) } - auditParams.ObjectID = sm.GetId() - auditParams.Original = sm + auditParams.ObjectID = subjectMapping.GetId() + auditParams.Original = subjectMapping s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) - rsp.SubjectMapping = sm - return &connect.Response[subjectmapping.CreateSubjectMappingResponse]{Msg: rsp}, nil + rsp.SubjectMapping = subjectMapping + return &connect.Response[sm.CreateSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, - _ *connect.Request[subjectmapping.ListSubjectMappingsRequest], -) (*connect.Response[subjectmapping.ListSubjectMappingsResponse], error) { + _ *connect.Request[sm.ListSubjectMappingsRequest], +) (*connect.Response[sm.ListSubjectMappingsResponse], error) { rsp := &sm.ListSubjectMappingsResponse{} s.logger.Debug("listing subject mappings") @@ -78,12 +77,12 @@ func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, } rsp.SubjectMappings = mappings - return &connect.Response[subjectmapping.ListSubjectMappingsResponse]{Msg: rsp}, nil + return &connect.Response[sm.ListSubjectMappingsResponse]{Msg: rsp}, nil } func (s SubjectMappingService) GetSubjectMapping(ctx context.Context, - req *connect.Request[subjectmapping.GetSubjectMappingRequest], -) (*connect.Response[subjectmapping.GetSubjectMappingResponse], error) { + req *connect.Request[sm.GetSubjectMappingRequest], +) (*connect.Response[sm.GetSubjectMappingResponse], error) { rsp := &sm.GetSubjectMappingResponse{} s.logger.Debug("getting subject mapping", slog.String("id", req.Msg.GetId())) @@ -93,12 +92,12 @@ func (s SubjectMappingService) GetSubjectMapping(ctx context.Context, } rsp.SubjectMapping = mapping - return &connect.Response[subjectmapping.GetSubjectMappingResponse]{Msg: rsp}, nil + return &connect.Response[sm.GetSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, - req *connect.Request[subjectmapping.UpdateSubjectMappingRequest], -) (*connect.Response[subjectmapping.UpdateSubjectMappingResponse], error) { + req *connect.Request[sm.UpdateSubjectMappingRequest], +) (*connect.Response[sm.UpdateSubjectMappingResponse], error) { rsp := &sm.UpdateSubjectMappingResponse{} subjectMappingID := req.Msg.GetId() @@ -129,12 +128,12 @@ func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return &connect.Response[subjectmapping.UpdateSubjectMappingResponse]{Msg: rsp}, nil + return &connect.Response[sm.UpdateSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, - req *connect.Request[subjectmapping.DeleteSubjectMappingRequest], -) (*connect.Response[subjectmapping.DeleteSubjectMappingResponse], error) { + req *connect.Request[sm.DeleteSubjectMappingRequest], +) (*connect.Response[sm.DeleteSubjectMappingResponse], error) { rsp := &sm.DeleteSubjectMappingResponse{} s.logger.Debug("deleting subject mapping", slog.String("id", req.Msg.GetId())) @@ -156,12 +155,12 @@ func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return &connect.Response[subjectmapping.DeleteSubjectMappingResponse]{Msg: rsp}, nil + return &connect.Response[sm.DeleteSubjectMappingResponse]{Msg: rsp}, nil } func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, - req *connect.Request[subjectmapping.MatchSubjectMappingsRequest], -) (*connect.Response[subjectmapping.MatchSubjectMappingsResponse], error) { + req *connect.Request[sm.MatchSubjectMappingsRequest], +) (*connect.Response[sm.MatchSubjectMappingsResponse], error) { rsp := &sm.MatchSubjectMappingsResponse{} s.logger.Debug("matching subject mappings", slog.Any("subjectProperties", req.Msg.GetSubjectProperties())) @@ -171,7 +170,7 @@ func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, } rsp.SubjectMappings = smList - return &connect.Response[subjectmapping.MatchSubjectMappingsResponse]{Msg: rsp}, nil + return &connect.Response[sm.MatchSubjectMappingsResponse]{Msg: rsp}, nil } /* -------------------------------------------------------- @@ -179,8 +178,8 @@ func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, * -------------------------------------------------------*/ func (s SubjectMappingService) GetSubjectConditionSet(ctx context.Context, - req *connect.Request[subjectmapping.GetSubjectConditionSetRequest], -) (*connect.Response[subjectmapping.GetSubjectConditionSetResponse], error) { + req *connect.Request[sm.GetSubjectConditionSetRequest], +) (*connect.Response[sm.GetSubjectConditionSetResponse], error) { rsp := &sm.GetSubjectConditionSetResponse{} s.logger.Debug("getting subject condition set", slog.String("id", req.Msg.GetId())) @@ -190,12 +189,12 @@ func (s SubjectMappingService) GetSubjectConditionSet(ctx context.Context, } rsp.SubjectConditionSet = conditionSet - return &connect.Response[subjectmapping.GetSubjectConditionSetResponse]{Msg: rsp}, nil + return &connect.Response[sm.GetSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, - _ *connect.Request[subjectmapping.ListSubjectConditionSetsRequest], -) (*connect.Response[subjectmapping.ListSubjectConditionSetsResponse], error) { + _ *connect.Request[sm.ListSubjectConditionSetsRequest], +) (*connect.Response[sm.ListSubjectConditionSetsResponse], error) { rsp := &sm.ListSubjectConditionSetsResponse{} s.logger.Debug("listing subject condition sets") @@ -205,12 +204,12 @@ func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, } rsp.SubjectConditionSets = conditionSets - return &connect.Response[subjectmapping.ListSubjectConditionSetsResponse]{Msg: rsp}, nil + return &connect.Response[sm.ListSubjectConditionSetsResponse]{Msg: rsp}, nil } func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, - req *connect.Request[subjectmapping.CreateSubjectConditionSetRequest], -) (*connect.Response[subjectmapping.CreateSubjectConditionSetResponse], error) { + req *connect.Request[sm.CreateSubjectConditionSetRequest], +) (*connect.Response[sm.CreateSubjectConditionSetResponse], error) { rsp := &sm.CreateSubjectConditionSetResponse{} s.logger.Debug("creating subject condition set", slog.String("subjectConditionSet", req.Msg.String())) @@ -230,12 +229,12 @@ func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.SubjectConditionSet = conditionSet - return &connect.Response[subjectmapping.CreateSubjectConditionSetResponse]{Msg: rsp}, nil + return &connect.Response[sm.CreateSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, - req *connect.Request[subjectmapping.UpdateSubjectConditionSetRequest], -) (*connect.Response[subjectmapping.UpdateSubjectConditionSetResponse], error) { + req *connect.Request[sm.UpdateSubjectConditionSetRequest], +) (*connect.Response[sm.UpdateSubjectConditionSetResponse], error) { rsp := &sm.UpdateSubjectConditionSetResponse{} s.logger.Debug("updating subject condition set", slog.String("subjectConditionSet", req.Msg.String())) @@ -265,12 +264,12 @@ func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: subjectConditionSetID, } - return &connect.Response[subjectmapping.UpdateSubjectConditionSetResponse]{Msg: rsp}, nil + return &connect.Response[sm.UpdateSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, - req *connect.Request[subjectmapping.DeleteSubjectConditionSetRequest], -) (*connect.Response[subjectmapping.DeleteSubjectConditionSetResponse], error) { + req *connect.Request[sm.DeleteSubjectConditionSetRequest], +) (*connect.Response[sm.DeleteSubjectConditionSetResponse], error) { rsp := &sm.DeleteSubjectConditionSetResponse{} s.logger.Debug("deleting subject condition set", slog.String("id", req.Msg.GetId())) @@ -292,7 +291,7 @@ func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: conditionSetID, } - return &connect.Response[subjectmapping.DeleteSubjectConditionSetResponse]{Msg: rsp}, nil + return &connect.Response[sm.DeleteSubjectConditionSetResponse]{Msg: rsp}, nil } func (s SubjectMappingService) DeleteAllUnmappedSubjectConditionSets(ctx context.Context, From a9dcc00c74c831f22cea35bbae131dfc83121541 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Wed, 6 Nov 2024 20:41:50 -0500 Subject: [PATCH 20/37] fix audit unit tests --- service/internal/server/realip/realip.go | 6 +++--- service/logger/audit/getDecision_test.go | 3 +-- service/logger/audit/helpers_test.go | 12 ++++++++---- service/logger/audit/policy_test.go | 4 +--- service/logger/audit/rewrap_test.go | 3 +-- service/logger/audit/utils.go | 2 +- service/logger/audit/utils_test.go | 10 +++++++--- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/service/internal/server/realip/realip.go b/service/internal/server/realip/realip.go index 80bd680587..5ecdbc7bed 100644 --- a/service/internal/server/realip/realip.go +++ b/service/internal/server/realip/realip.go @@ -16,7 +16,7 @@ const ( TrueClientIP = "True-Client-Ip" ) -type clientIP struct{} +type ClientIP struct{} func ConnectRealIPUnaryInterceptor() connect.UnaryInterceptorFunc { interceptor := func(next connect.UnaryFunc) connect.UnaryFunc { @@ -26,7 +26,7 @@ func ConnectRealIPUnaryInterceptor() connect.UnaryInterceptorFunc { ) (connect.AnyResponse, error) { ip := getIP(ctx, req.Peer(), req.Header()) - ctx = context.WithValue(ctx, clientIP{}, ip) + ctx = context.WithValue(ctx, ClientIP{}, ip) return next(ctx, req) }) @@ -54,7 +54,7 @@ func getIP(_ context.Context, peer connect.Peer, headers http.Header) net.IP { } func FromContext(ctx context.Context) net.IP { - ip, ok := ctx.Value(clientIP{}).(net.IP) + ip, ok := ctx.Value(ClientIP{}).(net.IP) if !ok { return net.IP{} } diff --git a/service/logger/audit/getDecision_test.go b/service/logger/audit/getDecision_test.go index a442128a02..9fcee5da3b 100644 --- a/service/logger/audit/getDecision_test.go +++ b/service/logger/audit/getDecision_test.go @@ -33,7 +33,6 @@ func TestCreateGetDecisionEventHappyPathSuccess(t *testing.T) { } event, err := CreateGetDecisionEvent(createTestContext(), params) - if err != nil { t.Fatalf("error creating get decision audit event: %v", err) } @@ -73,7 +72,7 @@ func TestCreateGetDecisionEventHappyPathSuccess(t *testing.T) { expectedClientInfo := eventClientInfo{ Platform: "authorization", UserAgent: TestUserAgent, - RequestIP: TestRequestIP, + RequestIP: TestRequestIP.String(), } if !reflect.DeepEqual(event.ClientInfo, expectedClientInfo) { t.Fatalf("event client info did not match expected: got %+v, want %+v", event.ClientInfo, expectedClientInfo) diff --git a/service/logger/audit/helpers_test.go b/service/logger/audit/helpers_test.go index 3b4aeebc6b..3cd0271fcf 100644 --- a/service/logger/audit/helpers_test.go +++ b/service/logger/audit/helpers_test.go @@ -2,29 +2,33 @@ package audit import ( "context" + "net" "testing" "time" "github.com/google/uuid" sdkAudit "github.com/opentdf/platform/sdk/audit" + "github.com/opentdf/platform/service/internal/server/realip" ) const ( - TestUserAgent = "test-user-agent" - TestActorID = "test-actor-id" - TestRequestIP = "192.168.1.1" + TestUserAgent = "test-user-agent" + TestActorID = "test-actor-id" + TestTDFFormat = "nano" TestAlgorithm = "rsa" TestPolicyBinding = "test-policy-binding" ) +var TestRequestIP = net.ParseIP("192.168.1.1") + var TestRequestID = uuid.New() func createTestContext() context.Context { ctx := context.Background() ctx = context.WithValue(ctx, sdkAudit.RequestIDContextKey, TestRequestID) ctx = context.WithValue(ctx, sdkAudit.UserAgentContextKey, TestUserAgent) - ctx = context.WithValue(ctx, sdkAudit.RequestIPContextKey, TestRequestIP) + ctx = context.WithValue(ctx, realip.ClientIP{}, TestRequestIP) ctx = context.WithValue(ctx, sdkAudit.ActorIDContextKey, TestActorID) return ctx } diff --git a/service/logger/audit/policy_test.go b/service/logger/audit/policy_test.go index 15bfca110a..d65c4fb0f1 100644 --- a/service/logger/audit/policy_test.go +++ b/service/logger/audit/policy_test.go @@ -42,7 +42,6 @@ func Test_CreatePolicyEvent_HappyPath(t *testing.T) { } event, err := CreatePolicyEvent(createTestContext(), true, params) - if err != nil { t.Fatalf("error creating policy audit event: %v", err) } @@ -74,7 +73,7 @@ func Test_CreatePolicyEvent_HappyPath(t *testing.T) { expectedClientInfo := eventClientInfo{ Platform: "policy", UserAgent: TestUserAgent, - RequestIP: TestRequestIP, + RequestIP: TestRequestIP.String(), } if !reflect.DeepEqual(event.ClientInfo, expectedClientInfo) { t.Fatalf("event client info did not match expected: got %+v, want %+v", event.ClientInfo, expectedClientInfo) @@ -99,7 +98,6 @@ func Test_CreatePolicyEvent_WithOriginal(t *testing.T) { } event, err := CreatePolicyEvent(createTestContext(), true, params) - if err != nil { t.Fatalf("error creating policy audit event: %v", err) } diff --git a/service/logger/audit/rewrap_test.go b/service/logger/audit/rewrap_test.go index 4a1570a5cd..6fa36b482c 100644 --- a/service/logger/audit/rewrap_test.go +++ b/service/logger/audit/rewrap_test.go @@ -28,7 +28,6 @@ func TestCreateRewrapAuditEventHappyPath(t *testing.T) { } event, err := CreateRewrapAuditEvent(createTestContext(), params) - if err != nil { t.Fatalf("error creating rewrap audit event: %v", err) } @@ -75,7 +74,7 @@ func TestCreateRewrapAuditEventHappyPath(t *testing.T) { expectedClientInfo := eventClientInfo{ Platform: "kas", UserAgent: TestUserAgent, - RequestIP: TestRequestIP, + RequestIP: TestRequestIP.String(), } if !reflect.DeepEqual(event.ClientInfo, expectedClientInfo) { t.Fatalf("event client info did not match expected: got %+v, want %+v", event.ClientInfo, expectedClientInfo) diff --git a/service/logger/audit/utils.go b/service/logger/audit/utils.go index be81c4591f..fc3880c157 100644 --- a/service/logger/audit/utils.go +++ b/service/logger/audit/utils.go @@ -156,7 +156,7 @@ func getContextValue(ctx context.Context, key sdkAudit.ContextKey) string { // that is not present, it falls back to the realip package. func getRequestIPFromContext(ctx context.Context) string { ip := realip.FromContext(ctx) - if ip.String() != "" { + if ip.String() != "" && ip.String() != "" { return ip.String() } diff --git a/service/logger/audit/utils_test.go b/service/logger/audit/utils_test.go index 1d0c755746..b87d311472 100644 --- a/service/logger/audit/utils_test.go +++ b/service/logger/audit/utils_test.go @@ -4,23 +4,25 @@ import ( "context" "fmt" "log/slog" + "net" "testing" "github.com/google/uuid" sdkAudit "github.com/opentdf/platform/sdk/audit" + "github.com/opentdf/platform/service/internal/server/realip" ) func TestGetAuditDataFromContextHappyPath(t *testing.T) { ctx := context.Background() testRequestID := uuid.New() testUserAgent := "test-user-agent" - testRequestIP := "192.168.0.1" + testRequestIP := net.ParseIP("192.168.0.1") testActorID := "test-actor-id" // Set relevant context keys ctx = context.WithValue(ctx, sdkAudit.RequestIDContextKey, testRequestID) ctx = context.WithValue(ctx, sdkAudit.UserAgentContextKey, testUserAgent) - ctx = context.WithValue(ctx, sdkAudit.RequestIPContextKey, testRequestIP) + ctx = context.WithValue(ctx, realip.ClientIP{}, testRequestIP) ctx = context.WithValue(ctx, sdkAudit.ActorIDContextKey, testActorID) slog.Info(fmt.Sprintf("Test: %v", ctx.Value(sdkAudit.RequestIDContextKey))) @@ -35,7 +37,7 @@ func TestGetAuditDataFromContextHappyPath(t *testing.T) { t.Fatalf("UserAgent did not match: %v", auditData.UserAgent) } - if auditData.RequestIP != testRequestIP { + if auditData.RequestIP != testRequestIP.String() { t.Fatalf("RequestIP did not match: %v", auditData.RequestIP) } @@ -65,6 +67,7 @@ func TestGetAuditDataFromContextDefaultsPath(t *testing.T) { t.Fatalf("ActorID did not match: %v", auditData.ActorID) } } + func TestGetAuditDataFromContextWithNoKeys(t *testing.T) { ctx := context.Background() auditData := GetAuditDataFromContext(ctx) @@ -85,6 +88,7 @@ func TestGetAuditDataFromContextWithNoKeys(t *testing.T) { t.Fatalf("ActorID did not match: %v", auditData.ActorID) } } + func TestGetAuditDataFromContextWithPartialKeys(t *testing.T) { ctx := context.Background() testUserAgent := "partial-user-agent" From 68e865caff72dedf93f2f09545890bd40e7dd792 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Thu, 7 Nov 2024 11:34:55 -0500 Subject: [PATCH 21/37] wrap kas error responses with connect --- service/kas/access/rewrap.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 08ac1073c4..30e73aff97 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -66,15 +66,15 @@ const ( ) func err400(s string) error { - return errors.Join(ErrUser, status.Error(codes.InvalidArgument, s)) + return connect.NewError(connect.CodeInvalidArgument, errors.Join(ErrUser, status.Error(codes.InvalidArgument, s))) } func err401(s string) error { - return errors.Join(ErrUser, status.Error(codes.Unauthenticated, s)) + return connect.NewError(connect.CodeUnauthenticated, errors.Join(ErrUser, status.Error(codes.Unauthenticated, s))) } func err403(s string) error { - return errors.Join(ErrUser, status.Error(codes.PermissionDenied, s)) + return connect.NewError(connect.CodePermissionDenied, errors.Join(ErrUser, status.Error(codes.PermissionDenied, s))) } func generateHMACDigest(ctx context.Context, msg, key []byte, logger logger.Logger) ([]byte, error) { From 88c880a364b895d686bda17e8931a36d7d4535aa Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Thu, 7 Nov 2024 11:51:22 -0500 Subject: [PATCH 22/37] move to connect.NewResponse --- service/authorization/authorization.go | 12 ++++---- .../claims/claims_entity_resolution.go | 4 +-- .../keycloak/keycloak_entity_resolution.go | 4 +-- service/kas/access/rewrap.go | 4 +-- service/policy/attributes/attributes.go | 30 +++++++++---------- .../kasregistry/key_access_server_registry.go | 12 ++++---- service/policy/namespaces/namespaces.go | 14 ++++----- .../resourcemapping/resource_mapping.go | 22 +++++++------- .../policy/subjectmapping/subject_mapping.go | 24 +++++++-------- service/policy/unsafe/unsafe.go | 18 +++++------ .../wellknown_configuration.go | 2 +- 11 files changed, 72 insertions(+), 74 deletions(-) diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go index bc0872cb02..4237087ae3 100644 --- a/service/authorization/authorization.go +++ b/service/authorization/authorization.go @@ -173,11 +173,9 @@ func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *co if err != nil { return nil, err } - return &connect.Response[authorization.GetDecisionsByTokenResponse]{ - Msg: &authorization.GetDecisionsByTokenResponse{ - DecisionResponses: resp.Msg.GetDecisionResponses(), - }, - }, err + return connect.NewResponse(&authorization.GetDecisionsByTokenResponse{ + DecisionResponses: resp.Msg.GetDecisionResponses(), + }), err } func (as *AuthorizationService) GetDecisions(ctx context.Context, req *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) { @@ -364,7 +362,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *connect.R } } } - return &connect.Response[authorization.GetDecisionsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } // makeSubMapsByValLookup creates a lookup map of subject mappings by attribute value ID. @@ -498,7 +496,7 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connec return nil, status.Error(codes.Internal, "failed to evaluate entitlements policy") } - resp := &connect.Response[authorization.GetEntitlementsResponse]{Msg: rsp} + resp := connect.NewResponse(rsp) // If we get no results and no error then we assume that the entity is not entitled to anything if len(results) == 0 { diff --git a/service/entityresolution/claims/claims_entity_resolution.go b/service/entityresolution/claims/claims_entity_resolution.go index 0a76864573..354e77c812 100644 --- a/service/entityresolution/claims/claims_entity_resolution.go +++ b/service/entityresolution/claims/claims_entity_resolution.go @@ -29,12 +29,12 @@ func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) ( func (s ClaimsEntityResolutionService) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { resp, err := EntityResolution(ctx, req.Msg, s.logger) - return &connect.Response[entityresolution.ResolveEntitiesResponse]{Msg: &resp}, err + return connect.NewResponse(&resp), err } func (s ClaimsEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.logger) - return &connect.Response[entityresolution.CreateEntityChainFromJwtResponse]{Msg: &resp}, err + return connect.NewResponse(&resp), err } func CreateEntityChainFromJwt( diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index 396ec46c34..211ea61872 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -64,12 +64,12 @@ func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Lo func (s KeycloakEntityResolutionService) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) { resp, err := EntityResolution(ctx, req.Msg, s.idpConfig, s.logger) - return &connect.Response[entityresolution.ResolveEntitiesResponse]{Msg: &resp}, err + return connect.NewResponse(&resp), err } func (s KeycloakEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) { resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.idpConfig, s.logger) - return &connect.Response[entityresolution.CreateEntityChainFromJwtResponse]{Msg: &resp}, err + return connect.NewResponse(&resp), err } func (c KeycloakConfig) LogValue() slog.Value { diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 30e73aff97..90075a3670 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -296,13 +296,13 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap p.Logger.ErrorContext(ctx, "rewrap nano", "err", err) } p.Logger.DebugContext(ctx, "rewrap nano", "rsp", rsp) - return &connect.Response[kaspb.RewrapResponse]{Msg: rsp}, err + return connect.NewResponse(rsp), err } rsp, err := p.tdf3Rewrap(ctx, body, entityInfo) if err != nil { p.Logger.ErrorContext(ctx, "rewrap tdf3", "err", err) } - return &connect.Response[kaspb.RewrapResponse]{Msg: rsp}, err + return connect.NewResponse(rsp), err } func (p *Provider) RewrapHandler(w http.ResponseWriter, r *http.Request) { diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 2e40a53e4a..62bf3f9e1b 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -66,7 +66,7 @@ func (s AttributesService) CreateAttribute(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.Attribute = item - return &connect.Response[attributes.CreateAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) ListAttributes(ctx context.Context, @@ -83,7 +83,7 @@ func (s *AttributesService) ListAttributes(ctx context.Context, } rsp.Attributes = list - return &connect.Response[attributes.ListAttributesResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) GetAttribute(ctx context.Context, @@ -97,7 +97,7 @@ func (s *AttributesService) GetAttribute(ctx context.Context, } rsp.Attribute = item - return &connect.Response[attributes.GetAttributeResponse]{Msg: rsp}, err + return connect.NewResponse(rsp), err } func (s *AttributesService) GetAttributeValuesByFqns(ctx context.Context, @@ -111,7 +111,7 @@ func (s *AttributesService) GetAttributeValuesByFqns(ctx context.Context, } rsp.FqnAttributeValues = fqnsToAttributes - return &connect.Response[attributes.GetAttributeValuesByFqnsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) GetAttributeValuesByFqnsHandler(w http.ResponseWriter, r *http.Request) { @@ -188,7 +188,7 @@ func (s *AttributesService) UpdateAttribute(ctx context.Context, Id: attributeID, } - return &connect.Response[attributes.UpdateAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) DeactivateAttribute(ctx context.Context, @@ -222,7 +222,7 @@ func (s *AttributesService) DeactivateAttribute(ctx context.Context, rsp.Attribute = &policy.Attribute{ Id: attributeID, } - return &connect.Response[attributes.DeactivateAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } /// @@ -248,7 +248,7 @@ func (s *AttributesService) CreateAttributeValue(ctx context.Context, req *conne s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.Value = item - return &connect.Response[attributes.CreateAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) ListAttributeValues(ctx context.Context, req *connect.Request[attributes.ListAttributeValuesRequest]) (*connect.Response[attributes.ListAttributeValuesResponse], error) { @@ -263,7 +263,7 @@ func (s *AttributesService) ListAttributeValues(ctx context.Context, req *connec rsp.Values = list - return &connect.Response[attributes.ListAttributeValuesResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) GetAttributeValue(ctx context.Context, req *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { @@ -276,7 +276,7 @@ func (s *AttributesService) GetAttributeValue(ctx context.Context, req *connect. rsp.Value = item - return &connect.Response[attributes.GetAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) UpdateAttributeValue(ctx context.Context, req *connect.Request[attributes.UpdateAttributeValueRequest]) (*connect.Response[attributes.UpdateAttributeValueResponse], error) { @@ -309,7 +309,7 @@ func (s *AttributesService) UpdateAttributeValue(ctx context.Context, req *conne Id: attributeID, } - return &connect.Response[attributes.UpdateAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) DeactivateAttributeValue(ctx context.Context, req *connect.Request[attributes.DeactivateAttributeValueRequest]) (*connect.Response[attributes.DeactivateAttributeValueResponse], error) { @@ -340,7 +340,7 @@ func (s *AttributesService) DeactivateAttributeValue(ctx context.Context, req *c rsp.Value = updated - return &connect.Response[attributes.DeactivateAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) AssignKeyAccessServerToAttribute(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToAttributeRequest]) (*connect.Response[attributes.AssignKeyAccessServerToAttributeResponse], error) { @@ -361,7 +361,7 @@ func (s *AttributesService) AssignKeyAccessServerToAttribute(ctx context.Context rsp.AttributeKeyAccessServer = attributeKas - return &connect.Response[attributes.AssignKeyAccessServerToAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) RemoveKeyAccessServerFromAttribute(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromAttributeRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse], error) { @@ -382,7 +382,7 @@ func (s *AttributesService) RemoveKeyAccessServerFromAttribute(ctx context.Conte rsp.AttributeKeyAccessServer = attributeKas - return &connect.Response[attributes.RemoveKeyAccessServerFromAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) AssignKeyAccessServerToValue(ctx context.Context, req *connect.Request[attributes.AssignKeyAccessServerToValueRequest]) (*connect.Response[attributes.AssignKeyAccessServerToValueResponse], error) { @@ -403,7 +403,7 @@ func (s *AttributesService) AssignKeyAccessServerToValue(ctx context.Context, re rsp.ValueKeyAccessServer = valueKas - return &connect.Response[attributes.AssignKeyAccessServerToValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *AttributesService) RemoveKeyAccessServerFromValue(ctx context.Context, req *connect.Request[attributes.RemoveKeyAccessServerFromValueRequest]) (*connect.Response[attributes.RemoveKeyAccessServerFromValueResponse], error) { @@ -424,5 +424,5 @@ func (s *AttributesService) RemoveKeyAccessServerFromValue(ctx context.Context, rsp.ValueKeyAccessServer = valueKas - return &connect.Response[attributes.RemoveKeyAccessServerFromValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index 14d7581d41..d73fc9c91f 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -59,7 +59,7 @@ func (s KeyAccessServerRegistry) CreateKeyAccessServer(ctx context.Context, rsp.KeyAccessServer = ks - return &connect.Response[kasr.CreateKeyAccessServerResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s KeyAccessServerRegistry) ListKeyAccessServers(ctx context.Context, @@ -74,7 +74,7 @@ func (s KeyAccessServerRegistry) ListKeyAccessServers(ctx context.Context, rsp.KeyAccessServers = keyAccessServers - return &connect.Response[kasr.ListKeyAccessServersResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s KeyAccessServerRegistry) GetKeyAccessServer(ctx context.Context, @@ -89,7 +89,7 @@ func (s KeyAccessServerRegistry) GetKeyAccessServer(ctx context.Context, rsp.KeyAccessServer = keyAccessServer - return &connect.Response[kasr.GetKeyAccessServerResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s KeyAccessServerRegistry) UpdateKeyAccessServer(ctx context.Context, @@ -125,7 +125,7 @@ func (s KeyAccessServerRegistry) UpdateKeyAccessServer(ctx context.Context, Id: kasID, } - return &connect.Response[kasr.UpdateKeyAccessServerResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s KeyAccessServerRegistry) DeleteKeyAccessServer(ctx context.Context, @@ -151,7 +151,7 @@ func (s KeyAccessServerRegistry) DeleteKeyAccessServer(ctx context.Context, Id: kasID, } - return &connect.Response[kasr.DeleteKeyAccessServerResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s KeyAccessServerRegistry) ListKeyAccessServerGrants(ctx context.Context, @@ -166,5 +166,5 @@ func (s KeyAccessServerRegistry) ListKeyAccessServerGrants(ctx context.Context, rsp.Grants = keyAccessServerGrants - return &connect.Response[kasr.ListKeyAccessServerGrantsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index 73666d89b7..48d35dedf7 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -66,7 +66,7 @@ func (ns NamespacesService) ListNamespaces(ctx context.Context, req *connect.Req ns.logger.Debug("listed namespaces") rsp.Namespaces = list - return &connect.Response[namespaces.ListNamespacesResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) GetNamespace(ctx context.Context, req *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { @@ -81,7 +81,7 @@ func (ns NamespacesService) GetNamespace(ctx context.Context, req *connect.Reque rsp.Namespace = namespace - return &connect.Response[namespaces.GetNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) CreateNamespace(ctx context.Context, req *connect.Request[namespaces.CreateNamespaceRequest]) (*connect.Response[namespaces.CreateNamespaceResponse], error) { @@ -106,7 +106,7 @@ func (ns NamespacesService) CreateNamespace(ctx context.Context, req *connect.Re ns.logger.Debug("created new namespace", slog.String("name", req.Msg.GetName())) rsp.Namespace = n - return &connect.Response[namespaces.CreateNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *connect.Request[namespaces.UpdateNamespaceRequest]) (*connect.Response[namespaces.UpdateNamespaceResponse], error) { @@ -141,7 +141,7 @@ func (ns NamespacesService) UpdateNamespace(ctx context.Context, req *connect.Re rsp.Namespace = &policy.Namespace{ Id: namespaceID, } - return &connect.Response[namespaces.UpdateNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) DeactivateNamespace(ctx context.Context, req *connect.Request[namespaces.DeactivateNamespaceRequest]) (*connect.Response[namespaces.DeactivateNamespaceResponse], error) { @@ -173,7 +173,7 @@ func (ns NamespacesService) DeactivateNamespace(ctx context.Context, req *connec ns.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) ns.logger.Debug("soft-deleted namespace", slog.String("id", namespaceID)) - return &connect.Response[namespaces.DeactivateNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) AssignKeyAccessServerToNamespace(ctx context.Context, req *connect.Request[namespaces.AssignKeyAccessServerToNamespaceRequest]) (*connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse], error) { @@ -195,7 +195,7 @@ func (ns NamespacesService) AssignKeyAccessServerToNamespace(ctx context.Context rsp.NamespaceKeyAccessServer = namespaceKas - return &connect.Response[namespaces.AssignKeyAccessServerToNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (ns NamespacesService) RemoveKeyAccessServerFromNamespace(ctx context.Context, req *connect.Request[namespaces.RemoveKeyAccessServerFromNamespaceRequest]) (*connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse], error) { @@ -217,5 +217,5 @@ func (ns NamespacesService) RemoveKeyAccessServerFromNamespace(ctx context.Conte rsp.NamespaceKeyAccessServer = namespaceKas - return &connect.Response[namespaces.RemoveKeyAccessServerFromNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/policy/resourcemapping/resource_mapping.go b/service/policy/resourcemapping/resource_mapping.go index a75cd41ff9..8e45ba4278 100644 --- a/service/policy/resourcemapping/resource_mapping.go +++ b/service/policy/resourcemapping/resource_mapping.go @@ -50,7 +50,7 @@ func (s ResourceMappingService) ListResourceMappingGroups(ctx context.Context, r rsp.ResourceMappingGroups = rmGroups - return &connect.Response[resourcemapping.ListResourceMappingGroupsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) GetResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.GetResourceMappingGroupRequest]) (*connect.Response[resourcemapping.GetResourceMappingGroupResponse], error) { @@ -63,7 +63,7 @@ func (s ResourceMappingService) GetResourceMappingGroup(ctx context.Context, req rsp.ResourceMappingGroup = rmGroup - return &connect.Response[resourcemapping.GetResourceMappingGroupResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) CreateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.CreateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.CreateResourceMappingGroupResponse], error) { @@ -86,7 +86,7 @@ func (s ResourceMappingService) CreateResourceMappingGroup(ctx context.Context, rsp.ResourceMappingGroup = rmGroup - return &connect.Response[resourcemapping.CreateResourceMappingGroupResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.UpdateResourceMappingGroupRequest]) (*connect.Response[resourcemapping.UpdateResourceMappingGroupResponse], error) { @@ -121,7 +121,7 @@ func (s ResourceMappingService) UpdateResourceMappingGroup(ctx context.Context, Id: id, } - return &connect.Response[resourcemapping.UpdateResourceMappingGroupResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, req *connect.Request[resourcemapping.DeleteResourceMappingGroupRequest]) (*connect.Response[resourcemapping.DeleteResourceMappingGroupResponse], error) { @@ -147,7 +147,7 @@ func (s ResourceMappingService) DeleteResourceMappingGroup(ctx context.Context, Id: id, } - return &connect.Response[resourcemapping.DeleteResourceMappingGroupResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } /* @@ -166,7 +166,7 @@ func (s ResourceMappingService) ListResourceMappings(ctx context.Context, rsp.ResourceMappings = resourceMappings - return &connect.Response[resourcemapping.ListResourceMappingsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) ListResourceMappingsByGroupFqns(ctx context.Context, req *connect.Request[resourcemapping.ListResourceMappingsByGroupFqnsRequest]) (*connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse], error) { @@ -181,7 +181,7 @@ func (s ResourceMappingService) ListResourceMappingsByGroupFqns(ctx context.Cont rsp.FqnResourceMappingGroups = fqnRmGroupMap - return &connect.Response[resourcemapping.ListResourceMappingsByGroupFqnsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) GetResourceMapping(ctx context.Context, @@ -196,7 +196,7 @@ func (s ResourceMappingService) GetResourceMapping(ctx context.Context, rsp.ResourceMapping = rm - return &connect.Response[resourcemapping.GetResourceMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) CreateResourceMapping(ctx context.Context, @@ -223,7 +223,7 @@ func (s ResourceMappingService) CreateResourceMapping(ctx context.Context, rsp.ResourceMapping = rm - return &connect.Response[resourcemapping.CreateResourceMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) UpdateResourceMapping(ctx context.Context, @@ -262,7 +262,7 @@ func (s ResourceMappingService) UpdateResourceMapping(ctx context.Context, Id: resourceMappingID, } - return &connect.Response[resourcemapping.UpdateResourceMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s ResourceMappingService) DeleteResourceMapping(ctx context.Context, @@ -290,5 +290,5 @@ func (s ResourceMappingService) DeleteResourceMapping(ctx context.Context, Id: resourceMappingID, } - return &connect.Response[resourcemapping.DeleteResourceMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index 10799718b8..62e113e801 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -62,7 +62,7 @@ func (s SubjectMappingService) CreateSubjectMapping(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.SubjectMapping = subjectMapping - return &connect.Response[sm.CreateSubjectMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, @@ -77,7 +77,7 @@ func (s SubjectMappingService) ListSubjectMappings(ctx context.Context, } rsp.SubjectMappings = mappings - return &connect.Response[sm.ListSubjectMappingsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) GetSubjectMapping(ctx context.Context, @@ -92,7 +92,7 @@ func (s SubjectMappingService) GetSubjectMapping(ctx context.Context, } rsp.SubjectMapping = mapping - return &connect.Response[sm.GetSubjectMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, @@ -128,7 +128,7 @@ func (s SubjectMappingService) UpdateSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return &connect.Response[sm.UpdateSubjectMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, @@ -155,7 +155,7 @@ func (s SubjectMappingService) DeleteSubjectMapping(ctx context.Context, rsp.SubjectMapping = &policy.SubjectMapping{ Id: subjectMappingID, } - return &connect.Response[sm.DeleteSubjectMappingResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, @@ -170,7 +170,7 @@ func (s SubjectMappingService) MatchSubjectMappings(ctx context.Context, } rsp.SubjectMappings = smList - return &connect.Response[sm.MatchSubjectMappingsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } /* -------------------------------------------------------- @@ -189,7 +189,7 @@ func (s SubjectMappingService) GetSubjectConditionSet(ctx context.Context, } rsp.SubjectConditionSet = conditionSet - return &connect.Response[sm.GetSubjectConditionSetResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, @@ -204,7 +204,7 @@ func (s SubjectMappingService) ListSubjectConditionSets(ctx context.Context, } rsp.SubjectConditionSets = conditionSets - return &connect.Response[sm.ListSubjectConditionSetsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, @@ -229,7 +229,7 @@ func (s SubjectMappingService) CreateSubjectConditionSet(ctx context.Context, s.logger.Audit.PolicyCRUDSuccess(ctx, auditParams) rsp.SubjectConditionSet = conditionSet - return &connect.Response[sm.CreateSubjectConditionSetResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, @@ -264,7 +264,7 @@ func (s SubjectMappingService) UpdateSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: subjectConditionSetID, } - return &connect.Response[sm.UpdateSubjectConditionSetResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, @@ -291,7 +291,7 @@ func (s SubjectMappingService) DeleteSubjectConditionSet(ctx context.Context, rsp.SubjectConditionSet = &policy.SubjectConditionSet{ Id: conditionSetID, } - return &connect.Response[sm.DeleteSubjectConditionSetResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s SubjectMappingService) DeleteAllUnmappedSubjectConditionSets(ctx context.Context, @@ -318,5 +318,5 @@ func (s SubjectMappingService) DeleteAllUnmappedSubjectConditionSets(ctx context } rsp.SubjectConditionSets = deleted - return &connect.Response[sm.DeleteAllUnmappedSubjectConditionSetsResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/policy/unsafe/unsafe.go b/service/policy/unsafe/unsafe.go index 531ed668f0..96bd04c7d4 100644 --- a/service/policy/unsafe/unsafe.go +++ b/service/policy/unsafe/unsafe.go @@ -73,7 +73,7 @@ func (s *UnsafeService) UnsafeUpdateNamespace(ctx context.Context, req *connect. Id: id, } - return &connect.Response[unsafe.UnsafeUpdateNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeReactivateNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateNamespaceRequest]) (*connect.Response[unsafe.UnsafeReactivateNamespaceResponse], error) { @@ -108,7 +108,7 @@ func (s *UnsafeService) UnsafeReactivateNamespace(ctx context.Context, req *conn Id: id, } - return &connect.Response[unsafe.UnsafeReactivateNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteNamespaceRequest]) (*connect.Response[unsafe.UnsafeDeleteNamespaceResponse], error) { @@ -140,7 +140,7 @@ func (s *UnsafeService) UnsafeDeleteNamespace(ctx context.Context, req *connect. Id: id, } - return &connect.Response[unsafe.UnsafeDeleteNamespaceResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } // @@ -179,7 +179,7 @@ func (s *UnsafeService) UnsafeUpdateAttribute(ctx context.Context, req *connect. Id: id, } - return &connect.Response[unsafe.UnsafeUpdateAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeReactivateAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeResponse], error) { @@ -214,7 +214,7 @@ func (s *UnsafeService) UnsafeReactivateAttribute(ctx context.Context, req *conn Id: id, } - return &connect.Response[unsafe.UnsafeReactivateAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeResponse], error) { @@ -246,7 +246,7 @@ func (s *UnsafeService) UnsafeDeleteAttribute(ctx context.Context, req *connect. Id: id, } - return &connect.Response[unsafe.UnsafeDeleteAttributeResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } // @@ -284,7 +284,7 @@ func (s *UnsafeService) UnsafeUpdateAttributeValue(ctx context.Context, req *con rsp.Value = &policy.Value{ Id: id, } - return &connect.Response[unsafe.UnsafeUpdateAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeReactivateAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeReactivateAttributeValueRequest]) (*connect.Response[unsafe.UnsafeReactivateAttributeValueResponse], error) { @@ -318,7 +318,7 @@ func (s *UnsafeService) UnsafeReactivateAttributeValue(ctx context.Context, req rsp.Value = &policy.Value{ Id: id, } - return &connect.Response[unsafe.UnsafeReactivateAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *connect.Request[unsafe.UnsafeDeleteAttributeValueRequest]) (*connect.Response[unsafe.UnsafeDeleteAttributeValueResponse], error) { @@ -349,5 +349,5 @@ func (s *UnsafeService) UnsafeDeleteAttributeValue(ctx context.Context, req *con rsp.Value = &policy.Value{ Id: id, } - return &connect.Response[unsafe.UnsafeDeleteAttributeValueResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } diff --git a/service/wellknownconfiguration/wellknown_configuration.go b/service/wellknownconfiguration/wellknown_configuration.go index 1377e19d5e..59e43375dd 100644 --- a/service/wellknownconfiguration/wellknown_configuration.go +++ b/service/wellknownconfiguration/wellknown_configuration.go @@ -62,5 +62,5 @@ func (s WellKnownService) GetWellKnownConfiguration(_ context.Context, _ *connec rsp := &wellknown.GetWellKnownConfigurationResponse{ Configuration: cfg, } - return &connect.Response[wellknown.GetWellKnownConfigurationResponse]{Msg: rsp}, nil + return connect.NewResponse(rsp), nil } From b232ad83efe5dc8bf1ec57566cc4209ddfb33f3d Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Thu, 7 Nov 2024 11:57:27 -0500 Subject: [PATCH 23/37] wrap db stausify errors with connect error --- service/pkg/db/errors.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/service/pkg/db/errors.go b/service/pkg/db/errors.go index 0299b7a435..49188f14dd 100644 --- a/service/pkg/db/errors.go +++ b/service/pkg/db/errors.go @@ -6,11 +6,10 @@ import ( "log/slog" "strings" + "connectrpc.com/connect" "github.com/jackc/pgerrcode" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgconn" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var ( @@ -104,28 +103,28 @@ func StatusifyError(err error, fallbackErr string, log ...any) error { l := append([]any{"error", err}, log...) if errors.Is(err, ErrUniqueConstraintViolation) { slog.Error(ErrTextConflict, l...) - return status.Error(codes.AlreadyExists, ErrTextConflict) + return connect.NewError(connect.CodeAlreadyExists, errors.New(ErrTextConflict)) } if errors.Is(err, ErrNotFound) { slog.Error(ErrTextNotFound, l...) - return status.Error(codes.NotFound, ErrTextNotFound) + return connect.NewError(connect.CodeNotFound, errors.New(ErrTextNotFound)) } if errors.Is(err, ErrForeignKeyViolation) { slog.Error(ErrTextRelationInvalid, l...) - return status.Error(codes.InvalidArgument, ErrTextRelationInvalid) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextRelationInvalid)) } if errors.Is(err, ErrEnumValueInvalid) { slog.Error(ErrTextEnumValueInvalid, l...) - return status.Error(codes.InvalidArgument, ErrTextEnumValueInvalid) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextEnumValueInvalid)) } if errors.Is(err, ErrUUIDInvalid) { slog.Error(ErrTextUUIDInvalid, l...) - return status.Error(codes.InvalidArgument, ErrTextUUIDInvalid) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextUUIDInvalid)) } if errors.Is(err, ErrRestrictViolation) { slog.Error(ErrTextRestrictViolation, l...) - return status.Error(codes.InvalidArgument, ErrTextRestrictViolation) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextRestrictViolation)) } slog.Error(err.Error(), l...) - return status.Error(codes.Internal, fallbackErr) + return connect.NewError(connect.CodeInternal, errors.New(fallbackErr)) } From 9a168c806115f36f50250ffeb81f9f5687483190 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Thu, 7 Nov 2024 14:27:40 -0500 Subject: [PATCH 24/37] remove unimplemented on service structs --- service/health/health.go | 1 - service/policy/namespaces/namespaces.go | 1 - service/policy/resourcemapping/resource_mapping.go | 1 - service/policy/subjectmapping/subject_mapping.go | 1 - service/policy/unsafe/unsafe.go | 1 - service/wellknownconfiguration/wellknown_configuration.go | 1 - 6 files changed, 6 deletions(-) diff --git a/service/health/health.go b/service/health/health.go index 22c5273efa..01489f3a74 100644 --- a/service/health/health.go +++ b/service/health/health.go @@ -15,7 +15,6 @@ import ( var serviceHealthChecks = make(map[string]func(context.Context) error) type HealthService struct { //nolint:revive // HealthService is a valid name for this struct - healthpb.UnimplementedHealthServer logger *logger.Logger } diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index 48d35dedf7..5e4555dc8a 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -17,7 +17,6 @@ import ( ) type NamespacesService struct { //nolint:revive // NamespacesService is a valid name - namespaces.UnimplementedNamespaceServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } diff --git a/service/policy/resourcemapping/resource_mapping.go b/service/policy/resourcemapping/resource_mapping.go index 8e45ba4278..832060cc1d 100644 --- a/service/policy/resourcemapping/resource_mapping.go +++ b/service/policy/resourcemapping/resource_mapping.go @@ -16,7 +16,6 @@ import ( ) type ResourceMappingService struct { //nolint:revive // ResourceMappingService is a valid name for this struct - resourcemapping.UnimplementedResourceMappingServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index 62e113e801..aca8f04b0a 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -16,7 +16,6 @@ import ( ) type SubjectMappingService struct { //nolint:revive // SubjectMappingService is a valid name for this struct - sm.UnimplementedSubjectMappingServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } diff --git a/service/policy/unsafe/unsafe.go b/service/policy/unsafe/unsafe.go index 96bd04c7d4..065866b0be 100644 --- a/service/policy/unsafe/unsafe.go +++ b/service/policy/unsafe/unsafe.go @@ -16,7 +16,6 @@ import ( ) type UnsafeService struct { //nolint:revive // UnsafeService is a valid name for this struct - unsafe.UnimplementedUnsafeServiceServer dbClient policydb.PolicyDBClient logger *logger.Logger } diff --git a/service/wellknownconfiguration/wellknown_configuration.go b/service/wellknownconfiguration/wellknown_configuration.go index 59e43375dd..3c9d9a95dc 100644 --- a/service/wellknownconfiguration/wellknown_configuration.go +++ b/service/wellknownconfiguration/wellknown_configuration.go @@ -17,7 +17,6 @@ import ( ) type WellKnownService struct { - wellknown.UnimplementedWellKnownServiceServer logger *logger.Logger } From 41fe1a04a0777846037e16f10c72d1efd9656429 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 11:52:13 -0500 Subject: [PATCH 25/37] revert to grpc-gateway runtime mux and allow connectrpc GET --- docs/grpc/index.html | 217 ++++++++++++ protocol/go/kas/kas.pb.go | 63 ++-- protocol/go/kas/kasconnect/kas.connect.go | 4 + .../go/policy/attributes/attributes.pb.go | 313 +++++++++--------- .../attributesconnect/attributes.connect.go | 8 + .../key_access_server_registry.connect.go | 6 + .../key_access_server_registry.pb.go | 130 ++++---- .../go/policy/namespaces/namespaces.pb.go | 161 ++++----- .../namespacesconnect/namespaces.connect.go | 4 + .../resourcemapping/resource_mapping.pb.go | 239 ++++++------- .../resource_mapping.connect.go | 10 + .../subjectmapping/subject_mapping.pb.go | 251 +++++++------- .../subject_mapping.connect.go | 8 + .../wellknown_configuration.pb.go | 40 +-- .../wellknown_configuration.connect.go | 2 + service/authorization/authorization.go | 1 + service/entityresolution/entityresolution.go | 1 + service/internal/server/server.go | 89 +++-- service/kas/access/publicKey.go | 104 +----- service/kas/access/rewrap.go | 58 ---- service/kas/kas.go | 10 +- service/kas/kas.proto | 2 + service/pkg/server/services.go | 15 +- service/pkg/server/services_test.go | 8 +- service/pkg/server/start_test.go | 9 +- .../pkg/serviceregistry/serviceregistry.go | 30 +- service/policy/attributes/attributes.go | 51 +-- service/policy/attributes/attributes.proto | 4 + .../kasregistry/key_access_server_registry.go | 1 + .../key_access_server_registry.proto | 3 + service/policy/namespaces/namespaces.go | 1 + service/policy/namespaces/namespaces.proto | 2 + .../resourcemapping/resource_mapping.go | 1 + .../resourcemapping/resource_mapping.proto | 5 + .../policy/subjectmapping/subject_mapping.go | 1 + .../subjectmapping/subject_mapping.proto | 4 + .../wellknown_configuration.go | 1 + .../wellknown_configuration.proto | 1 + 38 files changed, 1000 insertions(+), 858 deletions(-) diff --git a/docs/grpc/index.html b/docs/grpc/index.html index e97dd32d9d..30670c6418 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -3483,6 +3483,32 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + +
Method NameOption
PublicKey

NO_SIDE_EFFECTS

LegacyPublicKey

NO_SIDE_EFFECTS

+ +
@@ -5106,6 +5132,42 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameOption
ListAttributes

NO_SIDE_EFFECTS

ListAttributeValues

NO_SIDE_EFFECTS

GetAttribute

NO_SIDE_EFFECTS

GetAttributeValuesByFqns

NO_SIDE_EFFECTS

+ +
@@ -5714,6 +5776,37 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameOption
ListKeyAccessServers

NO_SIDE_EFFECTS

GetKeyAccessServer

NO_SIDE_EFFECTS

ListKeyAccessServerGrants

NO_SIDE_EFFECTS

+ +
@@ -6265,6 +6358,32 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + +
Method NameOption
GetNamespace

NO_SIDE_EFFECTS

ListNamespaces

NO_SIDE_EFFECTS

+ +
@@ -7214,6 +7333,47 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameOption
ListResourceMappingGroups

NO_SIDE_EFFECTS

GetResourceMappingGroup

NO_SIDE_EFFECTS

ListResourceMappings

NO_SIDE_EFFECTS

ListResourceMappingsByGroupFqns

NO_SIDE_EFFECTS

GetResourceMapping

NO_SIDE_EFFECTS

+ +
@@ -8157,6 +8317,42 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameOption
ListSubjectMappings

NO_SIDE_EFFECTS

GetSubjectMapping

NO_SIDE_EFFECTS

ListSubjectConditionSets

NO_SIDE_EFFECTS

GetSubjectConditionSet

NO_SIDE_EFFECTS

+ +
@@ -9009,6 +9205,27 @@

Methods with HTTP bindings

+ + +

Methods with idempotency_level option

+ + + + + + + + + + + + + + + +
Method NameOption
GetWellKnownConfiguration

NO_SIDE_EFFECTS

+ +

Scalar Value Types

diff --git a/protocol/go/kas/kas.pb.go b/protocol/go/kas/kas.pb.go index d2ebb9b6c8..eee98539af 100644 --- a/protocol/go/kas/kas.pb.go +++ b/protocol/go/kas/kas.pb.go @@ -452,42 +452,43 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xc8, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x66, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x12, 0x75, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x27, - 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x12, 0x58, 0x0a, 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, - 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, - 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, - 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, - 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, - 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, - 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, - 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, - 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, - 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, - 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, - 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, - 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, - 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x90, 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x58, 0x0a, + 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, + 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, 0x61, + 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, + 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, 0x0a, + 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, 0x42, + 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, 0x61, + 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, 0x61, + 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, 0x30, + 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, + 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, 0x02, + 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/kas/kasconnect/kas.connect.go b/protocol/go/kas/kasconnect/kas.connect.go index 7af392004f..fb443bfd92 100644 --- a/protocol/go/kas/kasconnect/kas.connect.go +++ b/protocol/go/kas/kasconnect/kas.connect.go @@ -73,12 +73,14 @@ func NewAccessServiceClient(httpClient connect.HTTPClient, baseURL string, opts httpClient, baseURL+AccessServicePublicKeyProcedure, connect.WithSchema(accessServicePublicKeyMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), legacyPublicKey: connect.NewClient[kas.LegacyPublicKeyRequest, wrapperspb.StringValue]( httpClient, baseURL+AccessServiceLegacyPublicKeyProcedure, connect.WithSchema(accessServiceLegacyPublicKeyMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), rewrap: connect.NewClient[kas.RewrapRequest, kas.RewrapResponse]( @@ -130,12 +132,14 @@ func NewAccessServiceHandler(svc AccessServiceHandler, opts ...connect.HandlerOp AccessServicePublicKeyProcedure, svc.PublicKey, connect.WithSchema(accessServicePublicKeyMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) accessServiceLegacyPublicKeyHandler := connect.NewUnaryHandler( AccessServiceLegacyPublicKeyProcedure, svc.LegacyPublicKey, connect.WithSchema(accessServiceLegacyPublicKeyMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) accessServiceRewrapHandler := connect.NewUnaryHandler( diff --git a/protocol/go/policy/attributes/attributes.pb.go b/protocol/go/policy/attributes/attributes.pb.go index 959297d557..818857614d 100644 --- a/protocol/go/policy/attributes/attributes.pb.go +++ b/protocol/go/policy/attributes/attributes.pb.go @@ -2094,176 +2094,177 @@ var file_policy_attributes_attributes_proto_rawDesc = []byte{ 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x32, 0xc1, 0x13, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7a, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x72, 0x32, 0xcd, 0x13, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x12, 0x92, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, - 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x79, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x12, 0x12, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, - 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, - 0x2f, 0x66, 0x71, 0x6e, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x32, 0x10, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, - 0x8e, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0x91, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, + 0x74, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x7c, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0xa1, 0x01, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, - 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, - 0x2a, 0x32, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, - 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa6, 0x01, 0x0a, - 0x18, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x66, 0x71, 0x6e, 0x90, 0x02, 0x01, + 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x32, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x13, + 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, - 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x1b, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xcd, 0x01, 0x0a, - 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x12, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, - 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xdb, 0x01, 0x0a, - 0x1c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, - 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, - 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x1e, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x2e, + 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xcd, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, + 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, 0x2f, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, - 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, - 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, - 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xa2, 0x02, 0x03, - 0x50, 0x41, 0x58, 0xaa, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, 0x02, 0x1d, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xdb, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x29, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, + 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, + 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x0f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, + 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x41, 0x58, 0xaa, + 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/attributes/attributesconnect/attributes.connect.go b/protocol/go/policy/attributes/attributesconnect/attributes.connect.go index bcb8fb964d..ba84fcead3 100644 --- a/protocol/go/policy/attributes/attributesconnect/attributes.connect.go +++ b/protocol/go/policy/attributes/attributesconnect/attributes.connect.go @@ -142,24 +142,28 @@ func NewAttributesServiceClient(httpClient connect.HTTPClient, baseURL string, o httpClient, baseURL+AttributesServiceListAttributesProcedure, connect.WithSchema(attributesServiceListAttributesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), listAttributeValues: connect.NewClient[attributes.ListAttributeValuesRequest, attributes.ListAttributeValuesResponse]( httpClient, baseURL+AttributesServiceListAttributeValuesProcedure, connect.WithSchema(attributesServiceListAttributeValuesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getAttribute: connect.NewClient[attributes.GetAttributeRequest, attributes.GetAttributeResponse]( httpClient, baseURL+AttributesServiceGetAttributeProcedure, connect.WithSchema(attributesServiceGetAttributeMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getAttributeValuesByFqns: connect.NewClient[attributes.GetAttributeValuesByFqnsRequest, attributes.GetAttributeValuesByFqnsResponse]( httpClient, baseURL+AttributesServiceGetAttributeValuesByFqnsProcedure, connect.WithSchema(attributesServiceGetAttributeValuesByFqnsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createAttribute: connect.NewClient[attributes.CreateAttributeRequest, attributes.CreateAttributeResponse]( @@ -367,24 +371,28 @@ func NewAttributesServiceHandler(svc AttributesServiceHandler, opts ...connect.H AttributesServiceListAttributesProcedure, svc.ListAttributes, connect.WithSchema(attributesServiceListAttributesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) attributesServiceListAttributeValuesHandler := connect.NewUnaryHandler( AttributesServiceListAttributeValuesProcedure, svc.ListAttributeValues, connect.WithSchema(attributesServiceListAttributeValuesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) attributesServiceGetAttributeHandler := connect.NewUnaryHandler( AttributesServiceGetAttributeProcedure, svc.GetAttribute, connect.WithSchema(attributesServiceGetAttributeMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) attributesServiceGetAttributeValuesByFqnsHandler := connect.NewUnaryHandler( AttributesServiceGetAttributeValuesByFqnsProcedure, svc.GetAttributeValuesByFqns, connect.WithSchema(attributesServiceGetAttributeValuesByFqnsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) attributesServiceCreateAttributeHandler := connect.NewUnaryHandler( diff --git a/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go b/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go index 3cfc542bcb..ca127cf8a6 100644 --- a/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go +++ b/protocol/go/policy/kasregistry/kasregistryconnect/key_access_server_registry.connect.go @@ -91,12 +91,14 @@ func NewKeyAccessServerRegistryServiceClient(httpClient connect.HTTPClient, base httpClient, baseURL+KeyAccessServerRegistryServiceListKeyAccessServersProcedure, connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServersMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getKeyAccessServer: connect.NewClient[kasregistry.GetKeyAccessServerRequest, kasregistry.GetKeyAccessServerResponse]( httpClient, baseURL+KeyAccessServerRegistryServiceGetKeyAccessServerProcedure, connect.WithSchema(keyAccessServerRegistryServiceGetKeyAccessServerMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createKeyAccessServer: connect.NewClient[kasregistry.CreateKeyAccessServerRequest, kasregistry.CreateKeyAccessServerResponse]( @@ -121,6 +123,7 @@ func NewKeyAccessServerRegistryServiceClient(httpClient connect.HTTPClient, base httpClient, baseURL+KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure, connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServerGrantsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), } @@ -192,12 +195,14 @@ func NewKeyAccessServerRegistryServiceHandler(svc KeyAccessServerRegistryService KeyAccessServerRegistryServiceListKeyAccessServersProcedure, svc.ListKeyAccessServers, connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServersMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) keyAccessServerRegistryServiceGetKeyAccessServerHandler := connect.NewUnaryHandler( KeyAccessServerRegistryServiceGetKeyAccessServerProcedure, svc.GetKeyAccessServer, connect.WithSchema(keyAccessServerRegistryServiceGetKeyAccessServerMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) keyAccessServerRegistryServiceCreateKeyAccessServerHandler := connect.NewUnaryHandler( @@ -222,6 +227,7 @@ func NewKeyAccessServerRegistryServiceHandler(svc KeyAccessServerRegistryService KeyAccessServerRegistryServiceListKeyAccessServerGrantsProcedure, svc.ListKeyAccessServerGrants, connect.WithSchema(keyAccessServerRegistryServiceListKeyAccessServerGrantsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) return "/policy.kasregistry.KeyAccessServerRegistryService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go index 0a9200e734..3700049e57 100644 --- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go +++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go @@ -1101,9 +1101,9 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x6e, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xe4, 0x07, 0x0a, 0x1e, 0x4b, 0x65, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xed, 0x07, 0x0a, 0x1e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x96, 0x01, 0x0a, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, @@ -1111,74 +1111,74 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9c, 0x01, - 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0xa1, 0x01, 0x0a, - 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, + 0x72, 0x76, 0x65, 0x72, 0x73, 0x90, 0x02, 0x01, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, + 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, + 0x90, 0x02, 0x01, 0x12, 0x9c, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, + 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xac, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, - 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, + 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x6b, + 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, + 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x42, 0xdb, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, 0x02, 0x12, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0xca, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x3a, 0x3a, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, 0x65, 0x79, + 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x90, 0x02, 0x01, 0x42, 0xdb, 0x01, 0x0a, 0x16, 0x63, 0x6f, + 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xca, 0x02, 0x12, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x4b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/namespaces/namespaces.pb.go b/protocol/go/policy/namespaces/namespaces.pb.go index e942ccd79a..7e77fce392 100644 --- a/protocol/go/policy/namespaces/namespaces.pb.go +++ b/protocol/go/policy/namespaces/namespaces.pb.go @@ -930,95 +930,96 @@ var file_policy_namespaces_namespaces_proto_rawDesc = []byte{ 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x32, 0xab, 0x09, 0x0a, 0x10, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x32, 0xb1, 0x09, 0x0a, 0x10, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x84, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x12, 0x87, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x74, 0x74, + 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x85, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, - 0x8b, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x90, 0x01, - 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, - 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0x99, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x2a, - 0x1b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xef, 0x01, 0x0a, - 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0x88, 0x01, 0x0a, 0x0e, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x4c, 0x3a, 0x1b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, - 0x2d, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xd8, - 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, - 0x72, 0x6f, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, - 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x2a, 0x2d, 0x2f, 0x61, 0x74, 0x74, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, - 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x42, 0x0f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x73, 0xa2, 0x02, 0x03, 0x50, 0x4e, 0x58, 0xaa, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0xe2, - 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x8b, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x12, 0x90, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x99, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x2a, 0x1b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, + 0x64, 0x7d, 0x12, 0xef, 0x01, 0x0a, 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x54, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x52, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x4c, 0x3a, 0x1b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x2d, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x6b, 0x65, + 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x12, 0xd8, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, + 0x6f, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x3c, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, + 0x2a, 0x2d, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, + 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x42, 0x0f, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, + 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x4e, 0x58, 0xaa, 0x02, 0x11, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go b/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go index 8df0903b60..a106981409 100644 --- a/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go +++ b/protocol/go/policy/namespaces/namespacesconnect/namespaces.connect.go @@ -96,12 +96,14 @@ func NewNamespaceServiceClient(httpClient connect.HTTPClient, baseURL string, op httpClient, baseURL+NamespaceServiceGetNamespaceProcedure, connect.WithSchema(namespaceServiceGetNamespaceMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), listNamespaces: connect.NewClient[namespaces.ListNamespacesRequest, namespaces.ListNamespacesResponse]( httpClient, baseURL+NamespaceServiceListNamespacesProcedure, connect.WithSchema(namespaceServiceListNamespacesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createNamespace: connect.NewClient[namespaces.CreateNamespaceRequest, namespaces.CreateNamespaceResponse]( @@ -209,12 +211,14 @@ func NewNamespaceServiceHandler(svc NamespaceServiceHandler, opts ...connect.Han NamespaceServiceGetNamespaceProcedure, svc.GetNamespace, connect.WithSchema(namespaceServiceGetNamespaceMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) namespaceServiceListNamespacesHandler := connect.NewUnaryHandler( NamespaceServiceListNamespacesProcedure, svc.ListNamespaces, connect.WithSchema(namespaceServiceListNamespacesMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) namespaceServiceCreateNamespaceHandler := connect.NewUnaryHandler( diff --git a/protocol/go/policy/resourcemapping/resource_mapping.pb.go b/protocol/go/policy/resourcemapping/resource_mapping.pb.go index 4a1916bd2f..8740406745 100644 --- a/protocol/go/policy/resourcemapping/resource_mapping.pb.go +++ b/protocol/go/policy/resourcemapping/resource_mapping.pb.go @@ -1600,9 +1600,9 @@ var file_policy_resourcemapping_resource_mapping_proto_rawDesc = []byte{ 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x32, 0xbd, 0x0f, 0x0a, 0x16, 0x52, 0x65, + 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x32, 0xcc, 0x0f, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0xb2, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x76, 0x69, 0x63, 0x65, 0x12, 0xb5, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, @@ -1611,135 +1611,136 @@ var file_policy_resourcemapping_resource_mapping_proto_rawDesc = []byte{ 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x17, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, - 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb8, 0x01, - 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, - 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xbd, 0x01, 0x0a, 0x1a, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x32, 0x1d, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xba, 0x01, 0x0a, 0x1a, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x90, 0x02, 0x01, 0x12, 0xb4, 0x01, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1f, 0x12, 0x1d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x90, 0x02, 0x01, 0x12, 0xb8, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x12, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x2a, 0x1d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x14, 0x12, 0x12, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xc9, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x71, 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, + 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0xbd, + 0x01, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x32, + 0x1d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xba, + 0x01, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x2a, 0x1d, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa0, 0x01, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x90, 0x02, 0x01, 0x12, 0xcc, + 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x71, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, + 0x42, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, + 0x42, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x66, 0x71, 0x6e, 0x73, 0x90, 0x02, 0x01, 0x12, 0x9f, 0x01, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, + 0xa3, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x71, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x66, 0x71, 0x6e, - 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, + 0x2a, 0x22, 0x12, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa8, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, + 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x32, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xa3, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x12, 0xa5, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, - 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa8, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x32, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xa5, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, - 0x2a, 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xeb, 0x01, 0x0a, 0x1a, 0x63, 0x6f, - 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0xa2, 0x02, 0x03, 0x50, 0x52, 0x58, 0xaa, 0x02, 0x16, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xca, - 0x02, 0x16, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x22, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x17, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, + 0x17, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xeb, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xa2, + 0x02, 0x03, 0x50, 0x52, 0x58, 0xaa, 0x02, 0x16, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xca, 0x02, + 0x16, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x22, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x17, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go b/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go index 415ba7fa15..c5589908e9 100644 --- a/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go +++ b/protocol/go/policy/resourcemapping/resourcemappingconnect/resource_mapping.connect.go @@ -115,12 +115,14 @@ func NewResourceMappingServiceClient(httpClient connect.HTTPClient, baseURL stri httpClient, baseURL+ResourceMappingServiceListResourceMappingGroupsProcedure, connect.WithSchema(resourceMappingServiceListResourceMappingGroupsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getResourceMappingGroup: connect.NewClient[resourcemapping.GetResourceMappingGroupRequest, resourcemapping.GetResourceMappingGroupResponse]( httpClient, baseURL+ResourceMappingServiceGetResourceMappingGroupProcedure, connect.WithSchema(resourceMappingServiceGetResourceMappingGroupMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createResourceMappingGroup: connect.NewClient[resourcemapping.CreateResourceMappingGroupRequest, resourcemapping.CreateResourceMappingGroupResponse]( @@ -145,18 +147,21 @@ func NewResourceMappingServiceClient(httpClient connect.HTTPClient, baseURL stri httpClient, baseURL+ResourceMappingServiceListResourceMappingsProcedure, connect.WithSchema(resourceMappingServiceListResourceMappingsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), listResourceMappingsByGroupFqns: connect.NewClient[resourcemapping.ListResourceMappingsByGroupFqnsRequest, resourcemapping.ListResourceMappingsByGroupFqnsResponse]( httpClient, baseURL+ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure, connect.WithSchema(resourceMappingServiceListResourceMappingsByGroupFqnsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getResourceMapping: connect.NewClient[resourcemapping.GetResourceMappingRequest, resourcemapping.GetResourceMappingResponse]( httpClient, baseURL+ResourceMappingServiceGetResourceMappingProcedure, connect.WithSchema(resourceMappingServiceGetResourceMappingMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createResourceMapping: connect.NewClient[resourcemapping.CreateResourceMappingRequest, resourcemapping.CreateResourceMappingResponse]( @@ -282,12 +287,14 @@ func NewResourceMappingServiceHandler(svc ResourceMappingServiceHandler, opts .. ResourceMappingServiceListResourceMappingGroupsProcedure, svc.ListResourceMappingGroups, connect.WithSchema(resourceMappingServiceListResourceMappingGroupsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) resourceMappingServiceGetResourceMappingGroupHandler := connect.NewUnaryHandler( ResourceMappingServiceGetResourceMappingGroupProcedure, svc.GetResourceMappingGroup, connect.WithSchema(resourceMappingServiceGetResourceMappingGroupMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) resourceMappingServiceCreateResourceMappingGroupHandler := connect.NewUnaryHandler( @@ -312,18 +319,21 @@ func NewResourceMappingServiceHandler(svc ResourceMappingServiceHandler, opts .. ResourceMappingServiceListResourceMappingsProcedure, svc.ListResourceMappings, connect.WithSchema(resourceMappingServiceListResourceMappingsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) resourceMappingServiceListResourceMappingsByGroupFqnsHandler := connect.NewUnaryHandler( ResourceMappingServiceListResourceMappingsByGroupFqnsProcedure, svc.ListResourceMappingsByGroupFqns, connect.WithSchema(resourceMappingServiceListResourceMappingsByGroupFqnsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) resourceMappingServiceGetResourceMappingHandler := connect.NewUnaryHandler( ResourceMappingServiceGetResourceMappingProcedure, svc.GetResourceMapping, connect.WithSchema(resourceMappingServiceGetResourceMappingMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) resourceMappingServiceCreateResourceMappingHandler := connect.NewUnaryHandler( diff --git a/protocol/go/policy/subjectmapping/subject_mapping.pb.go b/protocol/go/policy/subjectmapping/subject_mapping.pb.go index 978ca54b47..e0653a135a 100644 --- a/protocol/go/policy/subjectmapping/subject_mapping.pb.go +++ b/protocol/go/policy/subjectmapping/subject_mapping.pb.go @@ -1589,7 +1589,7 @@ var file_policy_subjectmapping_subject_mapping_proto_rawDesc = []byte{ 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x14, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, - 0x74, 0x73, 0x32, 0xca, 0x10, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, + 0x74, 0x73, 0x32, 0xd6, 0x10, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xb4, 0x01, 0x0a, 0x14, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, @@ -1602,7 +1602,7 @@ var file_policy_subjectmapping_subject_mapping_proto_rawDesc = []byte{ 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x12, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x17, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x12, 0x97, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, + 0x74, 0x63, 0x68, 0x12, 0x9a, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, @@ -1610,133 +1610,134 @@ var file_policy_subjectmapping_subject_mapping_proto_rawDesc = []byte{ 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x96, 0x01, - 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, - 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, - 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, - 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa2, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, - 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, - 0x3a, 0x01, 0x2a, 0x32, 0x16, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x14, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, - 0x70, 0x69, 0x6e, 0x67, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xac, 0x01, - 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x12, 0xab, 0x01, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x90, 0x02, 0x01, + 0x12, 0x99, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x2d, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x19, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x18, 0x12, 0x16, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0x9d, 0x01, 0x0a, + 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0xa2, 0x01, 0x0a, + 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x32, 0x16, 0x2f, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, + 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1c, 0x3a, 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x12, - 0xb7, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, + 0x74, 0x73, 0x90, 0x02, 0x01, 0x12, 0xae, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, + 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, + 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0xb2, 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x32, 0x1c, 0x2f, 0x73, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, - 0x73, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb4, 0x01, 0x0a, 0x19, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x2a, 0x1c, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xdc, 0x01, 0x0a, 0x25, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x55, 0x6e, - 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x12, 0x43, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x55, 0x6e, 0x6d, 0x61, - 0x70, 0x70, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x44, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, - 0x6c, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x2a, 0x20, 0x2f, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x75, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x42, - 0xe4, 0x01, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x13, 0x53, - 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x15, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0xca, 0x02, 0x15, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x53, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x21, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5c, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, + 0x01, 0x2a, 0x22, 0x17, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x12, 0xb7, 0x01, 0x0a, 0x19, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x32, 0x1c, 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, + 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xb4, 0x01, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x74, 0x12, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x2a, 0x1c, + 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xdc, 0x01, 0x0a, + 0x25, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, + 0x65, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x12, 0x43, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x55, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x44, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x6c, 0x6c, 0x55, 0x6e, 0x6d, + 0x61, 0x70, 0x70, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x2a, 0x20, 0x2f, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, + 0x74, 0x73, 0x2f, 0x75, 0x6e, 0x6d, 0x61, 0x70, 0x70, 0x65, 0x64, 0x42, 0xe4, 0x01, 0x0a, 0x19, + 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x42, 0x13, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, + 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xa2, + 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x15, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x15, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x21, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x53, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x3a, 0x3a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go index ddce801411..a4ca383de9 100644 --- a/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go +++ b/protocol/go/policy/subjectmapping/subjectmappingconnect/subject_mapping.connect.go @@ -127,12 +127,14 @@ func NewSubjectMappingServiceClient(httpClient connect.HTTPClient, baseURL strin httpClient, baseURL+SubjectMappingServiceListSubjectMappingsProcedure, connect.WithSchema(subjectMappingServiceListSubjectMappingsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getSubjectMapping: connect.NewClient[subjectmapping.GetSubjectMappingRequest, subjectmapping.GetSubjectMappingResponse]( httpClient, baseURL+SubjectMappingServiceGetSubjectMappingProcedure, connect.WithSchema(subjectMappingServiceGetSubjectMappingMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createSubjectMapping: connect.NewClient[subjectmapping.CreateSubjectMappingRequest, subjectmapping.CreateSubjectMappingResponse]( @@ -157,12 +159,14 @@ func NewSubjectMappingServiceClient(httpClient connect.HTTPClient, baseURL strin httpClient, baseURL+SubjectMappingServiceListSubjectConditionSetsProcedure, connect.WithSchema(subjectMappingServiceListSubjectConditionSetsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), getSubjectConditionSet: connect.NewClient[subjectmapping.GetSubjectConditionSetRequest, subjectmapping.GetSubjectConditionSetResponse]( httpClient, baseURL+SubjectMappingServiceGetSubjectConditionSetProcedure, connect.WithSchema(subjectMappingServiceGetSubjectConditionSetMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), createSubjectConditionSet: connect.NewClient[subjectmapping.CreateSubjectConditionSetRequest, subjectmapping.CreateSubjectConditionSetResponse]( @@ -307,12 +311,14 @@ func NewSubjectMappingServiceHandler(svc SubjectMappingServiceHandler, opts ...c SubjectMappingServiceListSubjectMappingsProcedure, svc.ListSubjectMappings, connect.WithSchema(subjectMappingServiceListSubjectMappingsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) subjectMappingServiceGetSubjectMappingHandler := connect.NewUnaryHandler( SubjectMappingServiceGetSubjectMappingProcedure, svc.GetSubjectMapping, connect.WithSchema(subjectMappingServiceGetSubjectMappingMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) subjectMappingServiceCreateSubjectMappingHandler := connect.NewUnaryHandler( @@ -337,12 +343,14 @@ func NewSubjectMappingServiceHandler(svc SubjectMappingServiceHandler, opts ...c SubjectMappingServiceListSubjectConditionSetsProcedure, svc.ListSubjectConditionSets, connect.WithSchema(subjectMappingServiceListSubjectConditionSetsMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) subjectMappingServiceGetSubjectConditionSetHandler := connect.NewUnaryHandler( SubjectMappingServiceGetSubjectConditionSetProcedure, svc.GetSubjectConditionSet, connect.WithSchema(subjectMappingServiceGetSubjectConditionSetMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) subjectMappingServiceCreateSubjectConditionSetHandler := connect.NewUnaryHandler( diff --git a/protocol/go/wellknownconfiguration/wellknown_configuration.pb.go b/protocol/go/wellknownconfiguration/wellknown_configuration.pb.go index 383c7df676..8933ce80a9 100644 --- a/protocol/go/wellknownconfiguration/wellknown_configuration.pb.go +++ b/protocol/go/wellknownconfiguration/wellknown_configuration.pb.go @@ -187,8 +187,8 @@ var file_wellknownconfiguration_wellknown_configuration_proto_rawDesc = []byte{ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x32, 0xd1, 0x01, 0x0a, 0x10, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, - 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xbc, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, + 0x69, 0x6f, 0x6e, 0x32, 0xd4, 0x01, 0x0a, 0x10, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xbf, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, @@ -197,26 +197,26 @@ var file_wellknownconfiguration_wellknown_configuration_proto_rawDesc = []byte{ 0x1a, 0x39, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0xf1, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, - 0x77, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x1b, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x77, - 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x57, 0x58, 0x58, 0xaa, 0x02, 0x16, 0x57, 0x65, - 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x16, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x22, - 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x16, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x90, 0x02, 0x01, 0x42, 0xf1, 0x01, 0x0a, 0x1a, 0x63, + 0x6f, 0x6d, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x1b, 0x57, 0x65, 0x6c, 0x6c, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, + 0x6f, 0x2f, 0x77, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x57, 0x58, 0x58, 0xaa, 0x02, + 0x16, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x16, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0xe2, 0x02, 0x22, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x16, 0x57, 0x65, 0x6c, 0x6c, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go b/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go index ac0b4ae299..35ce658693 100644 --- a/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go +++ b/protocol/go/wellknownconfiguration/wellknownconfigurationconnect/wellknown_configuration.connect.go @@ -63,6 +63,7 @@ func NewWellKnownServiceClient(httpClient connect.HTTPClient, baseURL string, op httpClient, baseURL+WellKnownServiceGetWellKnownConfigurationProcedure, connect.WithSchema(wellKnownServiceGetWellKnownConfigurationMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithClientOptions(opts...), ), } @@ -95,6 +96,7 @@ func NewWellKnownServiceHandler(svc WellKnownServiceHandler, opts ...connect.Han WellKnownServiceGetWellKnownConfigurationProcedure, svc.GetWellKnownConfiguration, connect.WithSchema(wellKnownServiceGetWellKnownConfigurationMethodDescriptor), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), connect.WithHandlerOptions(opts...), ) return "/wellknownconfiguration.WellKnownService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go index 4237087ae3..eeaa9915bf 100644 --- a/service/authorization/authorization.go +++ b/service/authorization/authorization.go @@ -60,6 +60,7 @@ func NewRegistration() *serviceregistry.Service[authorizationconnect.Authorizati Namespace: "authorization", ServiceDesc: &authorization.AuthorizationService_ServiceDesc, ConnectRPCFunc: authorizationconnect.NewAuthorizationServiceHandler, + GRPCGateayFunc: authorization.RegisterAuthorizationServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (authorizationconnect.AuthorizationServiceHandler, serviceregistry.HandlerServer) { var ( err error diff --git a/service/entityresolution/entityresolution.go b/service/entityresolution/entityresolution.go index 4150fe6d2e..cd09205c00 100644 --- a/service/entityresolution/entityresolution.go +++ b/service/entityresolution/entityresolution.go @@ -28,6 +28,7 @@ func NewRegistration() *serviceregistry.Service[entityresolutionconnect.EntityRe Namespace: "entityresolution", ServiceDesc: &entityresolution.EntityResolutionService_ServiceDesc, ConnectRPCFunc: entityresolutionconnect.NewEntityResolutionServiceHandler, + GRPCGateayFunc: entityresolution.RegisterEntityResolutionServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (entityresolutionconnect.EntityResolutionServiceHandler, serviceregistry.HandlerServer) { var inputConfig ERSConfig diff --git a/service/internal/server/server.go b/service/internal/server/server.go index 257f9fc4b4..c829b48e88 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -10,7 +10,6 @@ import ( "net/http" "net/http/pprof" "regexp" - "slices" "strings" "time" @@ -18,6 +17,7 @@ import ( "connectrpc.com/grpcreflect" "connectrpc.com/validate" "github.com/go-chi/cors" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" sdkAudit "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/security" @@ -109,7 +109,7 @@ type ConnectRPC struct { type OpenTDFServer struct { AuthN *auth.Authentication - ExtraHandlerMux *http.ServeMux + GRPCGatewayMux *runtime.ServeMux HTTPServer *http.Server ConnectRPCInProcess *inProcessServer ConnectRPC *ConnectRPC @@ -164,20 +164,20 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err return nil, fmt.Errorf("failed to create connect rpc server: %w", err) } - // Mux for addtional http handlers - extraHandlerMux := http.NewServeMux() + // GRPC Gateway Mux + grpcGatewayMux := runtime.NewServeMux() // Create http server - httpServer, err := newHTTPServer(config, connectRPC.Mux, extraHandlerMux, authN, logger) + httpServer, err := newHTTPServer(config, connectRPC.Mux, grpcGatewayMux, authN, logger) if err != nil { return nil, fmt.Errorf("failed to create http server: %w", err) } o := OpenTDFServer{ - AuthN: authN, - ExtraHandlerMux: extraHandlerMux, - HTTPServer: httpServer, - ConnectRPC: connectRPC, + AuthN: authN, + GRPCGatewayMux: grpcGatewayMux, + HTTPServer: httpServer, + ConnectRPC: connectRPC, ConnectRPCInProcess: &inProcessServer{ srv: memhttp.New(connectRPCIpc.Mux), maxCallRecvMsgSize: config.GRPC.MaxCallRecvMsgSizeBytes, @@ -197,14 +197,48 @@ func NewOpenTDFServer(config Config, logger *logger.Logger) (*OpenTDFServer, err return &o, nil } +// Custom response writer to add deprecation header +type grpcGatewayResponseWriter struct { + w http.ResponseWriter + code int + wroteHeader bool +} + +func (rw *grpcGatewayResponseWriter) Header() http.Header { + return rw.w.Header() +} + +func (rw *grpcGatewayResponseWriter) WriteHeader(statusCode int) { + if rw.wroteHeader == false { + rw.w.Header().Set("Deprecation", fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix())) + rw.wroteHeader = true + rw.w.WriteHeader(statusCode) + } + rw.code = statusCode +} + +func (rw *grpcGatewayResponseWriter) Write(data []byte) (int, error) { + // Ensure headers are written before any data + if !rw.wroteHeader { + rw.WriteHeader(http.StatusOK) + } + return rw.w.Write(data) +} + // newHTTPServer creates a new http server with the given handler and grpc server -func newHTTPServer(c Config, connectRPC http.Handler, extraHandlers http.Handler, a *auth.Authentication, l *logger.Logger) (*http.Server, error) { +func newHTTPServer(c Config, connectRPC http.Handler, originalGrpcGateway http.Handler, a *auth.Authentication, l *logger.Logger) (*http.Server, error) { var ( err error tc *tls.Config writeTimeoutOverride = writeTimeout ) + // Adds deprecation header to any grpcGateway responses. + var grpcGateway http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + grpcRW := &grpcGatewayResponseWriter{w: w, code: http.StatusOK} + originalGrpcGateway.ServeHTTP(grpcRW, r) + }) + // CORS if c.CORS.Enabled { corsHandler := cors.New(cors.Options{ @@ -228,32 +262,32 @@ func newHTTPServer(c Config, connectRPC http.Handler, extraHandlers http.Handler // Apply CORS to connectRPC and extra handlers connectRPC = corsHandler.Handler(connectRPC) - extraHandlers = corsHandler.Handler(extraHandlers) + grpcGateway = corsHandler.Handler(grpcGateway) } // Add authN interceptor to extra handlers if c.Auth.Enabled { - extraHandlers = a.MuxHandler(extraHandlers) + grpcGateway = a.MuxHandler(grpcGateway) } else { l.Error("disabling authentication. this is deprecated and will be removed. if you are using an IdP without DPoP set `enforceDPoP = false`") } // Enable pprof if c.EnablePprof { - extraHandlers = pprofHandler(extraHandlers) + grpcGateway = pprofHandler(grpcGateway) // Need to extend write timeout to collect pprof data. writeTimeoutOverride = 30 * time.Second //nolint:mnd // easier to read that we are overriding the default } var handler http.Handler if !c.TLS.Enabled { - handler = h2c.NewHandler(routeConnectRPCRequests(connectRPC, extraHandlers), &http2.Server{}) + handler = h2c.NewHandler(routeConnectRPCRequests(connectRPC, grpcGateway), &http2.Server{}) } else { tc, err = loadTLSConfig(c.TLS) if err != nil { return nil, fmt.Errorf("failed to load tls config: %w", err) } - handler = routeConnectRPCRequests(connectRPC, extraHandlers) + handler = routeConnectRPCRequests(connectRPC, grpcGateway) } return &http.Server{ @@ -269,19 +303,8 @@ var rpcPathRegex = regexp.MustCompile(`^/[\w\.]+\.[\w\.]+/[\w]+$`) func routeConnectRPCRequests(connectRPC http.Handler, httpHandler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - contentType := r.Header.Get("Content-Type") - if slices.Contains([]string{ - "application/grpc", - "application/grpc+proto", - "application/grpc+json", - "application/grpc-web", - "application/grpc-web+proto", - "application/grpc-web+json", - "application/proto", - "application/json", - "application/connect+proto", - "application/connect+json", - }, contentType) && r.Method == http.MethodPost && rpcPathRegex.MatchString(r.URL.Path) { + // contentType := r.Header.Get("Content-Type") + if (r.Method == http.MethodPost || r.Method == http.MethodGet) && rpcPathRegex.MatchString(r.URL.Path) { connectRPC.ServeHTTP(w, r) } else { httpHandler.ServeHTTP(w, r) @@ -417,6 +440,16 @@ func (s inProcessServer) Conn() *grpc.ClientConn { return conn } +func (s *inProcessServer) WithContextDialer() grpc.DialOption { + return grpc.WithContextDialer(func(ctx context.Context, _ string) (net.Conn, error) { + conn, err := s.srv.Listener.DialContext(ctx, "tcp", "http://localhost:8080") + if err != nil { + return nil, fmt.Errorf("failed to dial in process grpc server: %w", err) + } + return conn, nil + }) +} + func (s OpenTDFServer) openHTTPServerPort() (net.Listener, error) { addr := s.HTTPServer.Addr if addr == "" { diff --git a/service/kas/access/publicKey.go b/service/kas/access/publicKey.go index 28fbbcc252..a199992e37 100644 --- a/service/kas/access/publicKey.go +++ b/service/kas/access/publicKey.go @@ -7,15 +7,12 @@ import ( "crypto/x509" "encoding/pem" "errors" - "fmt" - "net/http" "connectrpc.com/connect" kaspb "github.com/opentdf/platform/protocol/go/kas" "github.com/opentdf/platform/service/internal/security" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/encoding/protojson" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -44,36 +41,14 @@ func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kasp if algorithm == "" { algorithm = security.AlgorithmRSA2048 } - pem, err := legacyPublicKey(ctx, p, algorithm) - if err != nil { - return nil, err - } - rsp := &wrapperspb.StringValue{Value: pem} - return &connect.Response[wrapperspb.StringValue]{Msg: rsp}, nil -} - -func (p Provider) LegacyPublicKeyHandler(w http.ResponseWriter, r *http.Request) { - algorithm := r.URL.Query().Get("algorithm") - if algorithm == "" { - algorithm = security.AlgorithmRSA2048 - } - pem, err := legacyPublicKey(r.Context(), p, algorithm) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write([]byte(pem)) //nolint:errcheck // ignore error -} - -func legacyPublicKey(ctx context.Context, p Provider, algorithm string) (string, error) { var pem string var err error if p.CryptoProvider == nil { - return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } kid, err := p.lookupKid(ctx, algorithm) if err != nil { - return "", err + return nil, err } switch algorithm { @@ -81,7 +56,7 @@ func legacyPublicKey(ctx context.Context, p Provider, algorithm string) (string, pem, err = p.CryptoProvider.ECCertificate(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.ECPublicKey failed", "err", err) - return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } case security.AlgorithmRSA2048: fallthrough @@ -89,12 +64,12 @@ func legacyPublicKey(ctx context.Context, p Provider, algorithm string) (string, pem, err = p.CryptoProvider.RSAPublicKey(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.RSAPublicKey failed", "err", err) - return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } default: - return "", errors.Join(ErrConfig, status.Error(codes.NotFound, "invalid algorithm")) + return nil, errors.Join(ErrConfig, status.Error(codes.NotFound, "invalid algorithm")) } - return pem, nil + return connect.NewResponse(&wrapperspb.StringValue{Value: pem}), nil } func (p Provider) PublicKey(ctx context.Context, req *connect.Request[kaspb.PublicKeyRequest]) (*connect.Response[kaspb.PublicKeyResponse], error) { @@ -116,87 +91,32 @@ func (p Provider) PublicKey(ctx context.Context, req *connect.Request[kaspb.Publ p.Logger.ErrorContext(ctx, "configuration error for key lookup", "err", err, "kid", kid, "algorithm", algorithm, "fmt", fmt) return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } - - rsp := &connect.Response[kaspb.PublicKeyResponse]{Msg: &kaspb.PublicKeyResponse{PublicKey: value}} - if req.Msg.GetV() == "1" { p.Logger.WarnContext(ctx, "hiding kid in public key response for legacy client", "kid", kid, "v", req.Msg.GetV()) - return rsp, nil + return connect.NewResponse(&kaspb.PublicKeyResponse{PublicKey: value}), nil } - rsp.Msg.Kid = kid - return rsp, nil - } - - pem, err := publicKey(ctx, p, algorithm, fmt) - return r(pem, kid, err) -} - -func (p Provider) PublicKeyHandler(w http.ResponseWriter, r *http.Request) { - algorithm := r.URL.Query().Get("algorithm") - if algorithm == "" { - algorithm = security.AlgorithmRSA2048 - } - keyFormat := r.URL.Query().Get("fmt") - - kid, err := p.lookupKid(r.Context(), algorithm) - if err != nil { - http.Error(w, fmt.Sprintf("key not found with algorithm: %s", algorithm), http.StatusNotFound) - return - } - - pem, err := publicKey(r.Context(), p, algorithm, keyFormat) - if err != nil { - if errors.Is(err, security.ErrCertNotFound) { - http.Error(w, err.Error(), http.StatusNotFound) - return - } - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - pubkey := &kaspb.PublicKeyResponse{PublicKey: pem, Kid: kid} - pubkeyByte, err := protojson.Marshal(pubkey) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Write(pubkeyByte) //nolint:errcheck // ignore error -} - -func publicKey(ctx context.Context, p Provider, algorithm, fmt string) (string, error) { - kid, err := p.lookupKid(ctx, algorithm) - if err != nil { - return "", err + return connect.NewResponse(&kaspb.PublicKeyResponse{PublicKey: value, Kid: kid}), nil } switch algorithm { case security.AlgorithmECP256R1: ecPublicKeyPem, err := p.CryptoProvider.ECPublicKey(kid) - if err != nil { - return "", err - } - return ecPublicKeyPem, nil + return r(ecPublicKeyPem, kid, err) case security.AlgorithmRSA2048: fallthrough case "": switch fmt { case "jwk": rsaPublicKeyPem, err := p.CryptoProvider.RSAPublicKeyAsJSON(kid) - if err != nil { - return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) - } - return rsaPublicKeyPem, nil + return r(rsaPublicKeyPem, kid, err) case "pkcs8": fallthrough case "": rsaPublicKeyPem, err := p.CryptoProvider.RSAPublicKey(kid) - if err != nil { - return "", errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) - } - return rsaPublicKeyPem, nil + return r(rsaPublicKeyPem, kid, err) } } - return "", status.Error(codes.NotFound, "invalid algorithm or format") + return nil, status.Error(codes.NotFound, "invalid algorithm or format") } func exportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) { diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 90075a3670..178a7ed108 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -15,7 +15,6 @@ import ( "encoding/pem" "errors" "fmt" - "io" "log/slog" "net/http" "strings" @@ -36,7 +35,6 @@ import ( "github.com/opentdf/platform/service/logger/audit" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/encoding/protojson" ) type SignedRequestBody struct { @@ -305,62 +303,6 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap return connect.NewResponse(rsp), err } -func (p *Provider) RewrapHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req := &kaspb.RewrapRequest{} - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - p.Logger.WarnContext(ctx, "read request body", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - err = protojson.Unmarshal(bodyBytes, req) - if err != nil { - p.Logger.WarnContext(ctx, "decode request", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - p.Logger.DebugContext(ctx, "REWRAP HANDLER") - body, err := extractSRTBody(ctx, r.Header, req, *p.Logger) - if err != nil { - p.Logger.DebugContext(ctx, "unverifiable srt", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - } - - entityInfo, err := getEntityInfo(ctx, p.Logger) - if err != nil { - p.Logger.DebugContext(ctx, "no entity info", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - } - - if body.Algorithm == "" { - p.Logger.DebugContext(ctx, "default rewrap algorithm") - body.Algorithm = "rsa:2048" - } - rewrapFunc := p.tdf3Rewrap - logType := "tdf3" - isNano := body.Algorithm == "ec:secp256r1" - if isNano { - rewrapFunc = p.nanoTDFRewrap - logType = "nano" - } - rsp, err := rewrapFunc(ctx, body, entityInfo) - if err != nil { - p.Logger.ErrorContext(ctx, "rewrap "+logType, "err", err) - } - if isNano { - p.Logger.DebugContext(ctx, "rewrap nano", "rsp", rsp) - } - rspBytes, err := protojson.Marshal(rsp) - if err != nil { - p.Logger.WarnContext(ctx, "marshal response", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(rspBytes) //nolint:errcheck // ignore error -} - func (p *Provider) tdf3Rewrap(ctx context.Context, body *RequestBody, entity *entityInfo) (*kaspb.RewrapResponse, error) { var kidsToCheck []string if body.KeyAccess.KID != "" { diff --git a/service/kas/kas.go b/service/kas/kas.go index d67de72046..6d42c5cbaa 100644 --- a/service/kas/kas.go +++ b/service/kas/kas.go @@ -1,10 +1,8 @@ package kas import ( - "context" "fmt" "log/slog" - "net/http" "net/url" "strings" @@ -22,6 +20,7 @@ func NewRegistration() *serviceregistry.Service[kasconnect.AccessServiceHandler] Namespace: "kas", ServiceDesc: &kaspb.AccessService_ServiceDesc, ConnectRPCFunc: kasconnect.NewAccessServiceHandler, + GRPCGateayFunc: kaspb.RegisterAccessServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (kasconnect.AccessServiceHandler, serviceregistry.HandlerServer) { // FIXME msg="mismatched key access url" keyAccessURL=http://localhost:9000 kasURL=https://:9000 hostWithPort := srp.OTDF.HTTPServer.Addr @@ -82,12 +81,7 @@ func NewRegistration() *serviceregistry.Service[kasconnect.AccessServiceHandler] srp.Logger.Error("failed to register kas readiness check", slog.String("error", err.Error())) } - return p, func(_ context.Context, mux *http.ServeMux) error { - mux.HandleFunc(fmt.Sprintf("%s /kas/kas_public_key", http.MethodGet), p.LegacyPublicKeyHandler) - mux.HandleFunc(fmt.Sprintf("%s /kas/v2/kas_public_key", http.MethodGet), p.PublicKeyHandler) - mux.HandleFunc(fmt.Sprintf("%s /kas/v2/rewrap", http.MethodPost), p.RewrapHandler) - return nil - } + return p, nil }, }, } diff --git a/service/kas/kas.proto b/service/kas/kas.proto index ee6555d946..8f0528d051 100644 --- a/service/kas/kas.proto +++ b/service/kas/kas.proto @@ -63,6 +63,7 @@ service AccessService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { responses: {key: "200"} }; + option idempotency_level = NO_SIDE_EFFECTS; } // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME @@ -72,6 +73,7 @@ service AccessService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { responses: {key: "200"} }; + option idempotency_level = NO_SIDE_EFFECTS; } rpc Rewrap(RewrapRequest) returns (RewrapResponse) { diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index c1644e8388..549879c132 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -21,6 +21,8 @@ import ( "github.com/opentdf/platform/service/pkg/serviceregistry" "github.com/opentdf/platform/service/policy" wellknown "github.com/opentdf/platform/service/wellknownconfiguration" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) const ( @@ -164,11 +166,6 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS return err } - // Register the service with the gRPC gateway - if err := svc.RegisterExtraHandlers(ctx, otdf.ExtraHandlerMux); err != nil { - logger.Error("service did not register extra http handlers", slog.String("namespace", ns)) - } - // Register Connect RPC Services if err := svc.RegisterConnectRPCServiceHandler(ctx, otdf.ConnectRPC); err != nil { logger.Info("service did not register a connect-rpc handler", slog.String("namespace", ns)) @@ -179,6 +176,14 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS logger.Info("service did not register a connect-rpc handler", slog.String("namespace", ns)) } + // Register GRPC Gateway + if err := svc.RegisterGRPCGatewayHandler(ctx, otdf.GRPCGatewayMux, []grpc.DialOption{ + otdf.ConnectRPCInProcess.WithContextDialer(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + }); err != nil { + logger.Info("service did not register a grpc gateway handler", slog.String("namespace", ns)) + } + logger.Info( "service running", slog.String("namespace", ns), diff --git a/service/pkg/server/services_test.go b/service/pkg/server/services_test.go index 5d4e163c9e..97248da3a7 100644 --- a/service/pkg/server/services_test.go +++ b/service/pkg/server/services_test.go @@ -2,9 +2,9 @@ package server import ( "context" - "net/http" "testing" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/config" "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/serviceregistry" @@ -22,7 +22,7 @@ type mockTestServiceOptions struct { serviceName string serviceHandlerType any serviceObject any - serviceHandler func(ctx context.Context, mux *http.ServeMux) error + serviceHandler func(ctx context.Context, mux *runtime.ServeMux) error dbRegister serviceregistry.DBRegister } @@ -32,7 +32,7 @@ func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.IServ namespace: "test", serviceName: "TestService", serviceHandlerType: (*interface{})(nil), - serviceHandler: func(_ context.Context, _ *http.ServeMux) error { + serviceHandler: func(_ context.Context, _ *runtime.ServeMux) error { return nil }, } @@ -65,7 +65,7 @@ func mockTestServiceRegistry(opts mockTestServiceOptions) (serviceregistry.IServ if ts, ok = opts.serviceObject.(TestService); !ok { panic("serviceObject is not a TestService") } - return ts, func(ctx context.Context, mux *http.ServeMux) error { + return ts, func(ctx context.Context, mux *runtime.ServeMux) error { spy.wasCalled = true spy.callParams = append(spy.callParams, srp, ctx, mux, ts) return serviceHandler(ctx, mux) diff --git a/service/pkg/server/start_test.go b/service/pkg/server/start_test.go index 15a31d38fa..db66b50b28 100644 --- a/service/pkg/server/start_test.go +++ b/service/pkg/server/start_test.go @@ -2,7 +2,6 @@ package server import ( "context" - "fmt" "io" "log/slog" "net/http" @@ -10,6 +9,7 @@ import ( "testing" "time" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/service/internal/auth" "github.com/opentdf/platform/service/internal/config" "github.com/opentdf/platform/service/internal/server" @@ -25,7 +25,7 @@ type ( TestService struct{} ) -func (t TestService) TestHandler(w http.ResponseWriter, _ *http.Request) { +func (t TestService) TestHandler(w http.ResponseWriter, _ *http.Request, _ map[string]string) { _, err := w.Write([]byte("hello from test service!")) if err != nil { panic(err) @@ -102,9 +102,8 @@ func (suite *StartTestSuite) Test_Start_When_Extra_Service_Registered_Expect_Res ts := TestService{} registerTestService, _ := mockTestServiceRegistry(mockTestServiceOptions{ serviceObject: ts, - serviceHandler: func(_ context.Context, mux *http.ServeMux) error { - mux.HandleFunc(fmt.Sprintf("%s /healthz", http.MethodGet), ts.TestHandler) - return nil + serviceHandler: func(_ context.Context, mux *runtime.ServeMux) error { + return mux.HandlePath(http.MethodGet, "/healthz", ts.TestHandler) }, }) diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index 26526efdf2..27913a1e7c 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -9,6 +9,7 @@ import ( "slices" "connectrpc.com/connect" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/opentdf/platform/sdk" "github.com/opentdf/platform/service/internal/server" @@ -49,7 +50,7 @@ type RegistrationParams struct { RegisterReadinessCheck func(namespace string, check func(context.Context) error) error } type ( - HandlerServer func(ctx context.Context, mux *http.ServeMux) error + HandlerServer func(ctx context.Context, mux *runtime.ServeMux) error RegisterFunc[S any] func(RegistrationParams) (impl S, HandlerServer HandlerServer) ) @@ -71,8 +72,8 @@ type IService interface { Start(ctx context.Context, params RegistrationParams) error IsStarted() bool Shutdown() error - RegisterExtraHandlers(context.Context, *http.ServeMux) error RegisterConnectRPCServiceHandler(context.Context, *server.ConnectRPC) error + RegisterGRPCGatewayHandler(context.Context, *runtime.ServeMux, []grpc.DialOption) error } // Service is a struct that holds the registration information for a service as well as the state @@ -96,10 +97,13 @@ type ServiceOptions[S any] struct { // but at minimum, the ServiceName field must be set ServiceDesc *grpc.ServiceDesc // RegisterFunc is the function that will be called to register the service - RegisterFunc RegisterFunc[S] + RegisterFunc RegisterFunc[S] + // HTTPHandlerFunc is the function that will be called to register extra http handlers httpHandlerFunc HandlerServer // ConnectRPCServiceHandler is the function that will be called to register the service with the ConnectRPCFunc func(S, ...connect.HandlerOption) (string, http.Handler) + // Deprecated: Registers a gRPC service with the gRPC gateway + GRPCGateayFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) // DB is optional and used to register the service with a database DB DBRegister } @@ -154,19 +158,11 @@ func (s *Service[S]) Start(ctx context.Context, params RegistrationParams) error return nil } -// Deprecated: RegisterExtraHandlers is deprecated and should not be used going forward. +// Deprecated: RegisterConnectRPCServiceHandler is deprecated and should not be used going forward. // We will be looking onto other alternatives like bufconnect to replace this. -// RegisterExtraHandlers registers an HTTP server with the service. +// RegisterConnectRPCServiceHandler registers an HTTP server with the service. // It takes a context, a ServeMux, and an implementation function as parameters. // If the service did not register a handler, it returns an error. -func (s *Service[S]) RegisterExtraHandlers(ctx context.Context, mux *http.ServeMux) error { - if s.httpHandlerFunc == nil { - return fmt.Errorf("service did not register a handler") - } - return s.httpHandlerFunc(ctx, mux) -} - -// RegisterConnectRPCServiceHandler registers a ConnectRPC service handler with the service. func (s Service[S]) RegisterConnectRPCServiceHandler(_ context.Context, connectRPC *server.ConnectRPC) error { if s.ConnectRPCFunc == nil { return fmt.Errorf("service did not register a handler") @@ -177,6 +173,14 @@ func (s Service[S]) RegisterConnectRPCServiceHandler(_ context.Context, connectR return nil } +// RegisterGRPCGatewayHandler registers a gRPC service with the gRPC gateway. This is temporary until we deprecate grpc-gateway +func (s Service[S]) RegisterGRPCGatewayHandler(ctx context.Context, mux *runtime.ServeMux, opts []grpc.DialOption) error { + if s.GRPCGateayFunc == nil { + return fmt.Errorf("service did not register a handler") + } + return s.GRPCGateayFunc(ctx, mux, "passthrough://", opts) +} + // namespace represents a namespace in the service registry. type Namespace struct { Mode string diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 62bf3f9e1b..8ca210ac0d 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -4,8 +4,6 @@ import ( "context" "fmt" "log/slog" - "net/http" - "strconv" "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/policy" @@ -16,7 +14,6 @@ import ( "github.com/opentdf/platform/service/pkg/db" "github.com/opentdf/platform/service/pkg/serviceregistry" policydb "github.com/opentdf/platform/service/policy/db" - "google.golang.org/protobuf/encoding/protojson" ) type AttributesService struct { //nolint:revive // AttributesService is a valid name for this struct @@ -31,12 +28,10 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer DB: dbRegister, ServiceDesc: &attributes.AttributesService_ServiceDesc, ConnectRPCFunc: attributesconnect.NewAttributesServiceHandler, + GRPCGateayFunc: attributes.RegisterAttributesServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (attributesconnect.AttributesServiceHandler, serviceregistry.HandlerServer) { as := &AttributesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} - return as, func(_ context.Context, mux *http.ServeMux) error { - mux.HandleFunc(fmt.Sprintf("%s /attributes/*/fqn", http.MethodGet), as.GetAttributeValuesByFqnsHandler) - return nil - } + return as, nil }, }, } @@ -114,48 +109,6 @@ func (s *AttributesService) GetAttributeValuesByFqns(ctx context.Context, return connect.NewResponse(rsp), nil } -func (s *AttributesService) GetAttributeValuesByFqnsHandler(w http.ResponseWriter, r *http.Request) { - q := r.URL.Query() - - fqns := q["fqns"] - withAttrGrants, err := strconv.ParseBool(q.Get("withValue.withAttribute.withKeyAccessGrants")) - if err != nil { - s.logger.Error("failed to parse withValue.withAttribute.withKeyAccessGrants", slog.String("error", err.Error())) - withAttrGrants = false - } - - withGrants, err := strconv.ParseBool(q.Get("withValue.withKeyAccessGrants")) - if err != nil { - s.logger.Error("failed to parse withValue.withKeyAccessGrants", slog.String("error", err.Error())) - withGrants = false - } - - fqnsToAttributes, err := s.dbClient.GetAttributesByValueFqns(r.Context(), &attributes.GetAttributeValuesByFqnsRequest{ - Fqns: fqns, - WithValue: &policy.AttributeValueSelector{ - WithKeyAccessGrants: withGrants, - WithAttribute: &policy.AttributeValueSelector_AttributeSelector{ - WithKeyAccessGrants: withAttrGrants, - }, - }, - }) - if err != nil { - s.logger.Error("failed to get attribute values by fqns", slog.String("error", err.Error())) - http.Error(w, "failed to get attribute values by fqns", http.StatusInternalServerError) - return - } - fqnsToAttributesBytes, err := protojson.Marshal(&attributes.GetAttributeValuesByFqnsResponse{FqnAttributeValues: fqnsToAttributes}) - if err != nil { - s.logger.Error("failed to marshal attribute values by fqns", slog.String("error", err.Error())) - http.Error(w, "failed to marshal attribute values by fqns", http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - if _, err = w.Write(fqnsToAttributesBytes); err != nil { - s.logger.Error("failed to write attribute values by fqns", slog.String("error", err.Error())) - } -} - func (s *AttributesService) UpdateAttribute(ctx context.Context, req *connect.Request[attributes.UpdateAttributeRequest], ) (*connect.Response[attributes.UpdateAttributeResponse], error) { diff --git a/service/policy/attributes/attributes.proto b/service/policy/attributes/attributes.proto index 2a339a67f3..6609d6ba2f 100644 --- a/service/policy/attributes/attributes.proto +++ b/service/policy/attributes/attributes.proto @@ -293,16 +293,20 @@ service AttributesService { *---------------------------------------*/ rpc ListAttributes(ListAttributesRequest) returns (ListAttributesResponse) { option (google.api.http) = {get: "/attributes"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc ListAttributeValues(ListAttributeValuesRequest) returns (ListAttributeValuesResponse) { option (google.api.http) = {get: "/attributes/*/values"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetAttribute(GetAttributeRequest) returns (GetAttributeResponse) { option (google.api.http) = {get: "/attributes/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetAttributeValuesByFqns(GetAttributeValuesByFqnsRequest) returns (GetAttributeValuesByFqnsResponse) { option (google.api.http) = {get: "/attributes/*/fqn"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateAttribute(CreateAttributeRequest) returns (CreateAttributeResponse) { diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index d73fc9c91f..088996f217 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -27,6 +27,7 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer DB: dbRegister, ServiceDesc: &kasr.KeyAccessServerRegistryService_ServiceDesc, ConnectRPCFunc: kasregistryconnect.NewKeyAccessServerRegistryServiceHandler, + GRPCGateayFunc: kasr.RegisterKeyAccessServerRegistryServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (kasregistryconnect.KeyAccessServerRegistryServiceHandler, serviceregistry.HandlerServer) { ksr := &KeyAccessServerRegistry{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} return ksr, nil diff --git a/service/policy/kasregistry/key_access_server_registry.proto b/service/policy/kasregistry/key_access_server_registry.proto index ce0218ab73..109541944f 100644 --- a/service/policy/kasregistry/key_access_server_registry.proto +++ b/service/policy/kasregistry/key_access_server_registry.proto @@ -162,10 +162,12 @@ message ListKeyAccessServerGrantsResponse { service KeyAccessServerRegistryService { rpc ListKeyAccessServers(ListKeyAccessServersRequest) returns (ListKeyAccessServersResponse) { option (google.api.http) = {get: "/key-access-servers"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetKeyAccessServer(GetKeyAccessServerRequest) returns (GetKeyAccessServerResponse) { option (google.api.http) = {get: "/key-access-servers/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateKeyAccessServer(CreateKeyAccessServerRequest) returns (CreateKeyAccessServerResponse) { @@ -188,5 +190,6 @@ service KeyAccessServerRegistryService { rpc ListKeyAccessServerGrants(ListKeyAccessServerGrantsRequest) returns (ListKeyAccessServerGrantsResponse) { option (google.api.http) = {get: "/key-access-servers/grants"}; + option idempotency_level = NO_SIDE_EFFECTS; } } diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index 5e4555dc8a..37cb539709 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -28,6 +28,7 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer DB: dbRegister, ServiceDesc: &namespaces.NamespaceService_ServiceDesc, ConnectRPCFunc: namespacesconnect.NewNamespaceServiceHandler, + GRPCGateayFunc: namespaces.RegisterNamespaceServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (namespacesconnect.NamespaceServiceHandler, serviceregistry.HandlerServer) { ns := &NamespacesService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} diff --git a/service/policy/namespaces/namespaces.proto b/service/policy/namespaces/namespaces.proto index 984824e5e1..bb1e3730e2 100644 --- a/service/policy/namespaces/namespaces.proto +++ b/service/policy/namespaces/namespaces.proto @@ -119,10 +119,12 @@ message RemoveKeyAccessServerFromNamespaceResponse { service NamespaceService { rpc GetNamespace(GetNamespaceRequest) returns (GetNamespaceResponse) { option (google.api.http) = {get: "/attributes/namespaces/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc ListNamespaces(ListNamespacesRequest) returns (ListNamespacesResponse) { option (google.api.http) = {get: "/attributes/namespaces"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateNamespace(CreateNamespaceRequest) returns (CreateNamespaceResponse) { diff --git a/service/policy/resourcemapping/resource_mapping.go b/service/policy/resourcemapping/resource_mapping.go index 832060cc1d..ba41489ce0 100644 --- a/service/policy/resourcemapping/resource_mapping.go +++ b/service/policy/resourcemapping/resource_mapping.go @@ -27,6 +27,7 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer DB: dbRegister, ServiceDesc: &resourcemapping.ResourceMappingService_ServiceDesc, ConnectRPCFunc: resourcemappingconnect.NewResourceMappingServiceHandler, + GRPCGateayFunc: resourcemapping.RegisterResourceMappingServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (resourcemappingconnect.ResourceMappingServiceHandler, serviceregistry.HandlerServer) { rm := &ResourceMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} return rm, nil diff --git a/service/policy/resourcemapping/resource_mapping.proto b/service/policy/resourcemapping/resource_mapping.proto index cd95243513..e925fe441c 100644 --- a/service/policy/resourcemapping/resource_mapping.proto +++ b/service/policy/resourcemapping/resource_mapping.proto @@ -241,10 +241,12 @@ service ResourceMappingService { rpc ListResourceMappingGroups(ListResourceMappingGroupsRequest) returns (ListResourceMappingGroupsResponse) { option (google.api.http) = {get: "/resource-mapping-groups"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetResourceMappingGroup(GetResourceMappingGroupRequest) returns (GetResourceMappingGroupResponse) { option (google.api.http) = {get: "/resource-mapping-groups/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateResourceMappingGroup(CreateResourceMappingGroupRequest) returns (CreateResourceMappingGroupResponse) { @@ -271,14 +273,17 @@ service ResourceMappingService { rpc ListResourceMappings(ListResourceMappingsRequest) returns (ListResourceMappingsResponse) { option (google.api.http) = {get: "/resource-mappings"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc ListResourceMappingsByGroupFqns(ListResourceMappingsByGroupFqnsRequest) returns (ListResourceMappingsByGroupFqnsResponse) { option (google.api.http) = {get: "/resource-mappings/group-fqns"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetResourceMapping(GetResourceMappingRequest) returns (GetResourceMappingResponse) { option (google.api.http) = {get: "/resource-mappings/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateResourceMapping(CreateResourceMappingRequest) returns (CreateResourceMappingResponse) { diff --git a/service/policy/subjectmapping/subject_mapping.go b/service/policy/subjectmapping/subject_mapping.go index aca8f04b0a..d089fe2904 100644 --- a/service/policy/subjectmapping/subject_mapping.go +++ b/service/policy/subjectmapping/subject_mapping.go @@ -27,6 +27,7 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer DB: dbRegister, ServiceDesc: &sm.SubjectMappingService_ServiceDesc, ConnectRPCFunc: subjectmappingconnect.NewSubjectMappingServiceHandler, + GRPCGateayFunc: sm.RegisterSubjectMappingServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (subjectmappingconnect.SubjectMappingServiceHandler, serviceregistry.HandlerServer) { smSvc := &SubjectMappingService{dbClient: policydb.NewClient(srp.DBClient, srp.Logger), logger: srp.Logger} return smSvc, nil diff --git a/service/policy/subjectmapping/subject_mapping.proto b/service/policy/subjectmapping/subject_mapping.proto index 6eb7521a73..b858e3287e 100644 --- a/service/policy/subjectmapping/subject_mapping.proto +++ b/service/policy/subjectmapping/subject_mapping.proto @@ -197,9 +197,11 @@ service SubjectMappingService { rpc ListSubjectMappings(ListSubjectMappingsRequest) returns (ListSubjectMappingsResponse) { option (google.api.http) = {get: "/subject-mappings"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetSubjectMapping(GetSubjectMappingRequest) returns (GetSubjectMappingResponse) { option (google.api.http) = {get: "/subject-mappings/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateSubjectMapping(CreateSubjectMappingRequest) returns (CreateSubjectMappingResponse) { @@ -222,10 +224,12 @@ service SubjectMappingService { rpc ListSubjectConditionSets(ListSubjectConditionSetsRequest) returns (ListSubjectConditionSetsResponse) { option (google.api.http) = {get: "/subject-condition-sets"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc GetSubjectConditionSet(GetSubjectConditionSetRequest) returns (GetSubjectConditionSetResponse) { option (google.api.http) = {get: "/subject-condition-sets/{id}"}; + option idempotency_level = NO_SIDE_EFFECTS; } rpc CreateSubjectConditionSet(CreateSubjectConditionSetRequest) returns (CreateSubjectConditionSetResponse) { diff --git a/service/wellknownconfiguration/wellknown_configuration.go b/service/wellknownconfiguration/wellknown_configuration.go index 3c9d9a95dc..88a096688a 100644 --- a/service/wellknownconfiguration/wellknown_configuration.go +++ b/service/wellknownconfiguration/wellknown_configuration.go @@ -41,6 +41,7 @@ func NewRegistration() *serviceregistry.Service[wellknownconfigurationconnect.We Namespace: "wellknown", ServiceDesc: &wellknown.WellKnownService_ServiceDesc, ConnectRPCFunc: wellknownconfigurationconnect.NewWellKnownServiceHandler, + GRPCGateayFunc: wellknown.RegisterWellKnownServiceHandlerFromEndpoint, RegisterFunc: func(srp serviceregistry.RegistrationParams) (wellknownconfigurationconnect.WellKnownServiceHandler, serviceregistry.HandlerServer) { wk := &WellKnownService{logger: srp.Logger} return wk, nil diff --git a/service/wellknownconfiguration/wellknown_configuration.proto b/service/wellknownconfiguration/wellknown_configuration.proto index 43606adeb7..b6d2c22569 100644 --- a/service/wellknownconfiguration/wellknown_configuration.proto +++ b/service/wellknownconfiguration/wellknown_configuration.proto @@ -18,5 +18,6 @@ message GetWellKnownConfigurationResponse { service WellKnownService { rpc GetWellKnownConfiguration(GetWellKnownConfigurationRequest) returns (GetWellKnownConfigurationResponse) { option (google.api.http) = {get: "/.well-known/opentdf-configuration"}; + option idempotency_level = NO_SIDE_EFFECTS; } } From 5e9f8f3cf45116eec872b94b207a499cc17f3434 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 15:39:19 -0500 Subject: [PATCH 26/37] clean up lint errors and some incorrect response codes --- service/internal/server/server.go | 2 +- service/kas/access/publicKey.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/service/internal/server/server.go b/service/internal/server/server.go index c829b48e88..ac0073fe00 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -209,7 +209,7 @@ func (rw *grpcGatewayResponseWriter) Header() http.Header { } func (rw *grpcGatewayResponseWriter) WriteHeader(statusCode int) { - if rw.wroteHeader == false { + if !rw.wroteHeader { rw.w.Header().Set("Deprecation", fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix())) rw.wroteHeader = true rw.w.WriteHeader(statusCode) diff --git a/service/kas/access/publicKey.go b/service/kas/access/publicKey.go index a199992e37..ca810c53cc 100644 --- a/service/kas/access/publicKey.go +++ b/service/kas/access/publicKey.go @@ -24,7 +24,7 @@ const ( func (p Provider) lookupKid(ctx context.Context, algorithm string) (string, error) { if len(p.KASConfig.Keyring) == 0 { p.Logger.WarnContext(ctx, "no default keys found", "algorithm", algorithm) - return "", errors.Join(ErrConfig, status.Error(codes.NotFound, "no default keys configured")) + return "", connect.NewError(connect.CodeNotFound, errors.Join(ErrConfig, errors.New("no default keys configured"))) } for _, k := range p.KASConfig.Keyring { @@ -33,7 +33,7 @@ func (p Provider) lookupKid(ctx context.Context, algorithm string) (string, erro } } p.Logger.WarnContext(ctx, "no (non-legacy) key for requested algorithm", "algorithm", algorithm) - return "", errors.Join(ErrConfig, status.Error(codes.NotFound, "no default key for algorithm")) + return "", connect.NewError(connect.CodeNotFound, errors.Join(ErrConfig, errors.New("no default key for algorithm"))) } func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kaspb.LegacyPublicKeyRequest]) (*connect.Response[wrapperspb.StringValue], error) { @@ -44,7 +44,7 @@ func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kasp var pem string var err error if p.CryptoProvider == nil { - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, connect.NewError(connect.CodeInternal, errors.Join(ErrConfig, errors.New("configuration error"))) } kid, err := p.lookupKid(ctx, algorithm) if err != nil { @@ -56,7 +56,7 @@ func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kasp pem, err = p.CryptoProvider.ECCertificate(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.ECPublicKey failed", "err", err) - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, connect.NewError(connect.CodeInternal, errors.Join(ErrConfig, errors.New("configuration error"))) } case security.AlgorithmRSA2048: fallthrough @@ -64,10 +64,10 @@ func (p Provider) LegacyPublicKey(ctx context.Context, req *connect.Request[kasp pem, err = p.CryptoProvider.RSAPublicKey(kid) if err != nil { p.Logger.ErrorContext(ctx, "CryptoProvider.RSAPublicKey failed", "err", err) - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, connect.NewError(connect.CodeInternal, errors.Join(ErrConfig, errors.New("configuration error"))) } default: - return nil, errors.Join(ErrConfig, status.Error(codes.NotFound, "invalid algorithm")) + return nil, connect.NewError(connect.CodeNotFound, errors.Join(ErrConfig, errors.New("invalid algorithm"))) } return connect.NewResponse(&wrapperspb.StringValue{Value: pem}), nil } @@ -86,10 +86,10 @@ func (p Provider) PublicKey(ctx context.Context, req *connect.Request[kaspb.Publ r := func(value, kid string, err error) (*connect.Response[kaspb.PublicKeyResponse], error) { if errors.Is(err, security.ErrCertNotFound) { p.Logger.ErrorContext(ctx, "no key found for", "err", err, "kid", kid, "algorithm", algorithm, "fmt", fmt) - return nil, errors.Join(err, status.Error(codes.NotFound, "no such key")) + return nil, connect.NewError(connect.CodeNotFound, err) } else if err != nil { p.Logger.ErrorContext(ctx, "configuration error for key lookup", "err", err, "kid", kid, "algorithm", algorithm, "fmt", fmt) - return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) + return nil, connect.NewError(connect.CodeInternal, err) } if req.Msg.GetV() == "1" { p.Logger.WarnContext(ctx, "hiding kid in public key response for legacy client", "kid", kid, "v", req.Msg.GetV()) From 8402107cc4ef25f08107d94270e649d3e6fb638f Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 16:39:08 -0500 Subject: [PATCH 27/37] fix not registering extra handlers --- service/pkg/server/services.go | 5 ++++ .../pkg/serviceregistry/serviceregistry.go | 24 ++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index 549879c132..e24267a00f 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -184,6 +184,11 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS logger.Info("service did not register a grpc gateway handler", slog.String("namespace", ns)) } + // Register Extra Handlers + if err := svc.RegisterHTTPHandlers(ctx, otdf.GRPCGatewayMux); err != nil { + logger.Info("service did not register extra http handlers", slog.String("namespace", ns)) + } + logger.Info( "service running", slog.String("namespace", ns), diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index 27913a1e7c..dcb0366930 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -74,6 +74,7 @@ type IService interface { Shutdown() error RegisterConnectRPCServiceHandler(context.Context, *server.ConnectRPC) error RegisterGRPCGatewayHandler(context.Context, *runtime.ServeMux, []grpc.DialOption) error + RegisterHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error } // Service is a struct that holds the registration information for a service as well as the state @@ -158,11 +159,6 @@ func (s *Service[S]) Start(ctx context.Context, params RegistrationParams) error return nil } -// Deprecated: RegisterConnectRPCServiceHandler is deprecated and should not be used going forward. -// We will be looking onto other alternatives like bufconnect to replace this. -// RegisterConnectRPCServiceHandler registers an HTTP server with the service. -// It takes a context, a ServeMux, and an implementation function as parameters. -// If the service did not register a handler, it returns an error. func (s Service[S]) RegisterConnectRPCServiceHandler(_ context.Context, connectRPC *server.ConnectRPC) error { if s.ConnectRPCFunc == nil { return fmt.Errorf("service did not register a handler") @@ -173,7 +169,23 @@ func (s Service[S]) RegisterConnectRPCServiceHandler(_ context.Context, connectR return nil } -// RegisterGRPCGatewayHandler registers a gRPC service with the gRPC gateway. This is temporary until we deprecate grpc-gateway +// Deprecated: RegisterHTTPServer is deprecated and should not be used going forward. +// We will be looking onto other alternatives like bufconnect to replace this. +// RegisterHTTPServer registers an HTTP server with the service. +// It takes a context, a ServeMux, and an implementation function as parameters. +// If the service did not register a handler, it returns an error. +func (s *Service[S]) RegisterHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error { + if s.httpHandlerFunc == nil { + return fmt.Errorf("service did not register any handlers") + } + return s.httpHandlerFunc(ctx, mux) +} + +// Deprecated: RegisterConnectRPCServiceHandler is deprecated and should not be used going forward. +// We will be looking onto other alternatives like bufconnect to replace this. +// RegisterConnectRPCServiceHandler registers an HTTP server with the service. +// It takes a context, a ServeMux, and an implementation function as parameters. +// If the service did not register a handler, it returns an error. func (s Service[S]) RegisterGRPCGatewayHandler(ctx context.Context, mux *runtime.ServeMux, opts []grpc.DialOption) error { if s.GRPCGateayFunc == nil { return fmt.Errorf("service did not register a handler") From 5663e08babc9b41694447efd88383760c974fedf Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 16:48:17 -0500 Subject: [PATCH 28/37] fix public_key unit test --- service/kas/access/publicKey_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/service/kas/access/publicKey_test.go b/service/kas/access/publicKey_test.go index b0585bafb0..a01e74a7c2 100644 --- a/service/kas/access/publicKey_test.go +++ b/service/kas/access/publicKey_test.go @@ -19,8 +19,6 @@ import ( "github.com/opentdf/platform/service/logger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) func TestExportRsaPublicKeyAsPemStrSuccess(t *testing.T) { @@ -200,9 +198,9 @@ func TestStandardPublicKeyHandlerV2NotFound(t *testing.T) { }) assert.Nil(t, k) require.Error(t, err) - status, ok := status.FromError(err) - assert.True(t, ok) - assert.Equal(t, codes.NotFound, status.Code()) + + status := connect.CodeOf(err) + assert.Equal(t, connect.CodeNotFound, status) } func TestStandardPublicKeyHandlerV2WithJwk(t *testing.T) { From 42e565d21896b4775494293715940e5398d45f47 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 16:53:23 -0500 Subject: [PATCH 29/37] fix go.mod --- service/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/go.mod b/service/go.mod index 9b3706aa75..4d865f9551 100644 --- a/service/go.mod +++ b/service/go.mod @@ -15,6 +15,7 @@ require ( github.com/go-chi/cors v1.2.1 github.com/go-playground/validator/v10 v10.22.0 github.com/google/uuid v1.6.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/jackc/pgx/v5 v5.5.5 github.com/lestrrat-go/jwx/v2 v2.0.21 @@ -61,7 +62,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/gowebpki/jcs v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect From 4d03a0ed5d0e2ac38718ef2e5df02510561293a8 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 17:32:52 -0500 Subject: [PATCH 30/37] new xtest-branch --- .github/workflows/checks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 26f5926787..a8ce76eed8 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -159,7 +159,7 @@ jobs: push: false platform-xtest: - uses: opentdf/tests/.github/workflows/xtest.yml@main + uses: opentdf/tests/.github/workflows/xtest.yml@pull-latest-otdfctl-tag with: # use commit instead of ref so we can "go get" specific sdk version platform-ref: ${{ github.event.pull_request.head.sha || github.sha }} From db0063340b03b0be421311fa261fe7f773251362 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 17:42:12 -0500 Subject: [PATCH 31/37] test sdk change --- .github/workflows/checks.yaml | 2 +- sdk/sdk.go | 46 +++++++++++++++++------------------ 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index a8ce76eed8..26f5926787 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -159,7 +159,7 @@ jobs: push: false platform-xtest: - uses: opentdf/tests/.github/workflows/xtest.yml@pull-latest-otdfctl-tag + uses: opentdf/tests/.github/workflows/xtest.yml@main with: # use commit instead of ref so we can "go get" specific sdk version platform-ref: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/sdk/sdk.go b/sdk/sdk.go index 7704dcc5bd..359eb43a75 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -26,8 +26,6 @@ import ( "github.com/opentdf/platform/protocol/go/wellknownconfiguration" "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/sdk/auth" - "github.com/opentdf/platform/sdk/internal/archive" - "github.com/xeipuuv/gojsonschema" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -323,28 +321,28 @@ var manifestSchema []byte func IsValidTdf(reader io.ReadSeeker) (bool, error) { // create tdf reader - tdfReader, err := archive.NewTDFReader(reader) - if err != nil { - return false, fmt.Errorf("archive.NewTDFReader failed: %w", err) - } - - manifest, err := tdfReader.Manifest() - if err != nil { - return false, fmt.Errorf("tdfReader.Manifest failed: %w", err) - } - - // Convert the embedded data to a string - manifestSchemaString := string(manifestSchema) - loader := gojsonschema.NewStringLoader(manifestSchemaString) - manifestStringLoader := gojsonschema.NewStringLoader(manifest) - result, err := gojsonschema.Validate(loader, manifestStringLoader) - if err != nil { - return false, errors.New("could not validate manifest.json") - } - - if !result.Valid() { - return false, errors.New("manifest was not valid") - } + // tdfReader, err := archive.NewTDFReader(reader) + // if err != nil { + // return false, fmt.Errorf("archive.NewTDFReader failed: %w", err) + // } + + // manifest, err := tdfReader.Manifest() + // if err != nil { + // return false, fmt.Errorf("tdfReader.Manifest failed: %w", err) + // } + + // // Convert the embedded data to a string + // manifestSchemaString := string(manifestSchema) + // loader := gojsonschema.NewStringLoader(manifestSchemaString) + // manifestStringLoader := gojsonschema.NewStringLoader(manifest) + // result, err := gojsonschema.Validate(loader, manifestStringLoader) + // if err != nil { + // return false, errors.New("could not validate manifest.json") + // } + + // if !result.Valid() { + // return false, errors.New("manifest was not valid") + // } return true, nil } From c52e54e314fef21b3409186116bcef4cc53dc307 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 17:50:36 -0500 Subject: [PATCH 32/37] try my x-test branch --- .github/workflows/checks.yaml | 2 +- sdk/sdk.go | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 26f5926787..3bbdee9e70 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -159,7 +159,7 @@ jobs: push: false platform-xtest: - uses: opentdf/tests/.github/workflows/xtest.yml@main + uses: opentdf/tests/.github/workflows/xtest.yml@pull-latest-otdfctl-tag with: # use commit instead of ref so we can "go get" specific sdk version platform-ref: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/sdk/sdk.go b/sdk/sdk.go index 359eb43a75..8b6170c5c4 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -26,6 +26,7 @@ import ( "github.com/opentdf/platform/protocol/go/wellknownconfiguration" "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/sdk/auth" + "github.com/opentdf/platform/sdk/internal/archive" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -321,16 +322,17 @@ var manifestSchema []byte func IsValidTdf(reader io.ReadSeeker) (bool, error) { // create tdf reader - // tdfReader, err := archive.NewTDFReader(reader) - // if err != nil { - // return false, fmt.Errorf("archive.NewTDFReader failed: %w", err) - // } + tdfReader, err := archive.NewTDFReader(reader) + if err != nil { + return false, fmt.Errorf("archive.NewTDFReader failed: %w", err) + } - // manifest, err := tdfReader.Manifest() - // if err != nil { - // return false, fmt.Errorf("tdfReader.Manifest failed: %w", err) - // } + _, err = tdfReader.Manifest() + if err != nil { + return false, fmt.Errorf("tdfReader.Manifest failed: %w", err) + } + // Schema validation is failing across SDKs // // Convert the embedded data to a string // manifestSchemaString := string(manifestSchema) // loader := gojsonschema.NewStringLoader(manifestSchemaString) From 6fba4daa270edc06401deeb2abf9a47a508f20a5 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Fri, 8 Nov 2024 18:41:14 -0500 Subject: [PATCH 33/37] switch to local host for grpc-gateway --- service/pkg/server/services.go | 9 +++++---- service/pkg/serviceregistry/serviceregistry.go | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/service/pkg/server/services.go b/service/pkg/server/services.go index e24267a00f..8760a5fbd8 100644 --- a/service/pkg/server/services.go +++ b/service/pkg/server/services.go @@ -177,10 +177,11 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS } // Register GRPC Gateway - if err := svc.RegisterGRPCGatewayHandler(ctx, otdf.GRPCGatewayMux, []grpc.DialOption{ - otdf.ConnectRPCInProcess.WithContextDialer(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - }); err != nil { + grpcGatewayDialOptions := make([]grpc.DialOption, 0) + if !cfg.Server.TLS.Enabled { + grpcGatewayDialOptions = append(grpcGatewayDialOptions, grpc.WithTransportCredentials(insecure.NewCredentials())) + } + if err := svc.RegisterGRPCGatewayHandler(ctx, otdf.GRPCGatewayMux, fmt.Sprintf("localhost:%d", cfg.Server.Port), grpcGatewayDialOptions); err != nil { logger.Info("service did not register a grpc gateway handler", slog.String("namespace", ns)) } diff --git a/service/pkg/serviceregistry/serviceregistry.go b/service/pkg/serviceregistry/serviceregistry.go index dcb0366930..a00218a60c 100644 --- a/service/pkg/serviceregistry/serviceregistry.go +++ b/service/pkg/serviceregistry/serviceregistry.go @@ -73,8 +73,8 @@ type IService interface { IsStarted() bool Shutdown() error RegisterConnectRPCServiceHandler(context.Context, *server.ConnectRPC) error - RegisterGRPCGatewayHandler(context.Context, *runtime.ServeMux, []grpc.DialOption) error - RegisterHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error + RegisterGRPCGatewayHandler(context.Context, *runtime.ServeMux, string, []grpc.DialOption) error + RegisterHTTPHandlers(context.Context, *runtime.ServeMux) error } // Service is a struct that holds the registration information for a service as well as the state @@ -186,11 +186,11 @@ func (s *Service[S]) RegisterHTTPHandlers(ctx context.Context, mux *runtime.Serv // RegisterConnectRPCServiceHandler registers an HTTP server with the service. // It takes a context, a ServeMux, and an implementation function as parameters. // If the service did not register a handler, it returns an error. -func (s Service[S]) RegisterGRPCGatewayHandler(ctx context.Context, mux *runtime.ServeMux, opts []grpc.DialOption) error { +func (s Service[S]) RegisterGRPCGatewayHandler(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error { if s.GRPCGateayFunc == nil { return fmt.Errorf("service did not register a handler") } - return s.GRPCGateayFunc(ctx, mux, "passthrough://", opts) + return s.GRPCGateayFunc(ctx, mux, endpoint, opts) } // namespace represents a namespace in the service registry. From 50f81c35f3e6cf699c478cbf59b9092c44117501 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 12 Nov 2024 10:18:02 -0500 Subject: [PATCH 34/37] revert sdk changes --- .github/workflows/checks.yaml | 2 +- sdk/sdk.go | 26 +++++++++++++------------- service/internal/server/server.go | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 3bbdee9e70..26f5926787 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -159,7 +159,7 @@ jobs: push: false platform-xtest: - uses: opentdf/tests/.github/workflows/xtest.yml@pull-latest-otdfctl-tag + uses: opentdf/tests/.github/workflows/xtest.yml@main with: # use commit instead of ref so we can "go get" specific sdk version platform-ref: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/sdk/sdk.go b/sdk/sdk.go index 8b6170c5c4..7704dcc5bd 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -27,6 +27,7 @@ import ( "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/sdk/auth" "github.com/opentdf/platform/sdk/internal/archive" + "github.com/xeipuuv/gojsonschema" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -327,24 +328,23 @@ func IsValidTdf(reader io.ReadSeeker) (bool, error) { return false, fmt.Errorf("archive.NewTDFReader failed: %w", err) } - _, err = tdfReader.Manifest() + manifest, err := tdfReader.Manifest() if err != nil { return false, fmt.Errorf("tdfReader.Manifest failed: %w", err) } - // Schema validation is failing across SDKs - // // Convert the embedded data to a string - // manifestSchemaString := string(manifestSchema) - // loader := gojsonschema.NewStringLoader(manifestSchemaString) - // manifestStringLoader := gojsonschema.NewStringLoader(manifest) - // result, err := gojsonschema.Validate(loader, manifestStringLoader) - // if err != nil { - // return false, errors.New("could not validate manifest.json") - // } + // Convert the embedded data to a string + manifestSchemaString := string(manifestSchema) + loader := gojsonschema.NewStringLoader(manifestSchemaString) + manifestStringLoader := gojsonschema.NewStringLoader(manifest) + result, err := gojsonschema.Validate(loader, manifestStringLoader) + if err != nil { + return false, errors.New("could not validate manifest.json") + } - // if !result.Valid() { - // return false, errors.New("manifest was not valid") - // } + if !result.Valid() { + return false, errors.New("manifest was not valid") + } return true, nil } diff --git a/service/internal/server/server.go b/service/internal/server/server.go index ac0073fe00..e0e5b30c42 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -209,8 +209,9 @@ func (rw *grpcGatewayResponseWriter) Header() http.Header { } func (rw *grpcGatewayResponseWriter) WriteHeader(statusCode int) { + GRPCGatewayDeprecationDate := fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix()) if !rw.wroteHeader { - rw.w.Header().Set("Deprecation", fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix())) + rw.w.Header().Set("Deprecation", GRPCGatewayDeprecationDate) rw.wroteHeader = true rw.w.WriteHeader(statusCode) } From 6dc772895500f33564b950ea7f1cc0a4ee3ee535 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 12 Nov 2024 15:07:07 -0500 Subject: [PATCH 35/37] fix lint issue --- service/internal/server/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service/internal/server/server.go b/service/internal/server/server.go index e0e5b30c42..b1aa79032a 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -209,9 +209,9 @@ func (rw *grpcGatewayResponseWriter) Header() http.Header { } func (rw *grpcGatewayResponseWriter) WriteHeader(statusCode int) { - GRPCGatewayDeprecationDate := fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix()) + gRPCGatewayDeprecationDate := fmt.Sprintf("@%d", time.Date(2025, time.March, 25, 0, 0, 0, 0, time.UTC).Unix()) if !rw.wroteHeader { - rw.w.Header().Set("Deprecation", GRPCGatewayDeprecationDate) + rw.w.Header().Set("Deprecation", gRPCGatewayDeprecationDate) rw.wroteHeader = true rw.w.WriteHeader(statusCode) } From e91c2bc57339c04f213fd1938bec3f0ccccdb33b Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 12 Nov 2024 18:31:51 -0500 Subject: [PATCH 36/37] cleanup a few ers error responses --- .../claims/claims_entity_resolution.go | 4 +- .../keycloak/keycloak_entity_resolution.go | 45 +++-- .../keycloak_entity_resolution_test.go | 176 +++++++++--------- 3 files changed, 116 insertions(+), 109 deletions(-) diff --git a/service/entityresolution/claims/claims_entity_resolution.go b/service/entityresolution/claims/claims_entity_resolution.go index 354e77c812..090d2b676c 100644 --- a/service/entityresolution/claims/claims_entity_resolution.go +++ b/service/entityresolution/claims/claims_entity_resolution.go @@ -69,14 +69,14 @@ func EntityResolution(_ context.Context, if claims != nil { err := claims.UnmarshalTo(entityStruct) if err != nil { - return entityresolution.ResolveEntitiesResponse{}, fmt.Errorf("error unpacking anypb.Any to structpb.Struct: %w", err) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("error unpacking anypb.Any to structpb.Struct: %w", err)) } } default: retrievedStruct, err := entityToStructPb(ident) if err != nil { logger.Error("unable to make entity struct", slog.String("error", err.Error())) - return entityresolution.ResolveEntitiesResponse{}, fmt.Errorf("unable to make entity struct: %w", err) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeInternal, fmt.Errorf("unable to make entity struct: %w", err)) } entityStruct = retrievedStruct } diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index 211ea61872..14a5caf4e8 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -18,15 +18,14 @@ import ( "github.com/opentdf/platform/service/logger" "github.com/opentdf/platform/service/pkg/serviceregistry" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/structpb" ) -const ( - ErrTextCreationFailed = "resource creation failed" - ErrTextGetRetrievalFailed = "resource retrieval failed" - ErrTextNotFound = "resource not found" +var ( + ErrCreationFailed = errors.New("resource creation failed") + ErrGetRetrievalFailed = errors.New("resource retrieval failed") + ErrNotFound = errors.New("resource not found") ) const ( @@ -124,7 +123,7 @@ func EntityResolution(ctx context.Context, connector, err := getKCClient(ctx, kcConfig, logger) if err != nil { return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextCreationFailed) + connect.NewError(connect.CodeInternal, ErrCreationFailed) } payload := req.GetEntities() @@ -145,7 +144,7 @@ func EntityResolution(ctx context.Context, if err != nil { logger.Error("error getting client info", slog.String("error", err.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextGetRetrievalFailed) + connect.NewError(connect.CodeInternal, ErrGetRetrievalFailed) } var jsonEntities []*structpb.Struct for _, client := range clients { @@ -153,13 +152,13 @@ func EntityResolution(ctx context.Context, if err != nil { logger.Error("error serializing entity representation!", slog.String("error", err.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextCreationFailed) + connect.NewError(connect.CodeInternal, ErrCreationFailed) } mystruct, structErr := structpb.NewStruct(json) if structErr != nil { logger.Error("error making struct!", slog.String("error", structErr.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextCreationFailed) + connect.NewError(connect.CodeInternal, ErrCreationFailed) } jsonEntities = append(jsonEntities, mystruct) } @@ -168,7 +167,7 @@ func EntityResolution(ctx context.Context, entityStruct, err := entityToStructPb(ident) if err != nil { logger.Error("unable to make entity struct", slog.String("error", err.Error())) - return entityresolution.ResolveEntitiesResponse{}, status.Error(codes.Internal, ErrTextCreationFailed) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeInternal, ErrCreationFailed) } jsonEntities = append(jsonEntities, entityStruct) } @@ -197,7 +196,7 @@ func EntityResolution(ctx context.Context, case err != nil: logger.Error(err.Error()) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextGetRetrievalFailed) + connect.NewError(connect.CodeInternal, ErrGetRetrievalFailed) case len(users) == 1: user := users[0] logger.Debug("user found", slog.String("user", *user.ID), slog.String("entity", ident.String())) @@ -218,14 +217,14 @@ func EntityResolution(ctx context.Context, case groupErr != nil: logger.Error("error getting group", slog.String("group", groupErr.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextGetRetrievalFailed) + connect.NewError(connect.CodeInternal, ErrGetRetrievalFailed) case len(groups) == 1: logger.Info("group found for", slog.String("entity", ident.String())) group := groups[0] expandedRepresentations, exErr := expandGroup(ctx, *group.ID, connector, &kcConfig, logger) if exErr != nil { return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextNotFound) + connect.NewError(connect.CodeNotFound, ErrNotFound) } else { keycloakEntities = expandedRepresentations } @@ -234,15 +233,15 @@ func EntityResolution(ctx context.Context, var entityNotFoundErr entityresolution.EntityNotFoundError switch ident.GetEntityType().(type) { case *authorization.Entity_EmailAddress: - entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrTextGetRetrievalFailed, Entity: ident.GetEmailAddress()} + entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(connect.CodeNotFound), Message: ErrGetRetrievalFailed.Error(), Entity: ident.GetEmailAddress()} case *authorization.Entity_UserName: - entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrTextGetRetrievalFailed, Entity: ident.GetUserName()} + entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(connect.CodeNotFound), Message: ErrGetRetrievalFailed.Error(), Entity: ident.GetUserName()} // case "": // return &entityresolution.IdpPluginResponse{}, // status.Error(codes.InvalidArgument, db.ErrTextNotFound) default: logger.Error("unsupported/unknown type for", slog.String("entity", ident.String())) - entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrTextGetRetrievalFailed, Entity: ident.String()} + entityNotFoundErr = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrGetRetrievalFailed.Error(), Entity: ident.String()} } logger.Error(entityNotFoundErr.String()) if kcConfig.InferID.From.Email || kcConfig.InferID.From.Username { @@ -250,11 +249,11 @@ func EntityResolution(ctx context.Context, entityStruct, err := entityToStructPb(ident) if err != nil { logger.Error("unable to make entity struct from email or username", slog.String("error", err.Error())) - return entityresolution.ResolveEntitiesResponse{}, status.Error(codes.Internal, ErrTextCreationFailed) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeInternal, ErrCreationFailed) } jsonEntities = append(jsonEntities, entityStruct) } else { - return entityresolution.ResolveEntitiesResponse{}, status.Error(codes.Code(entityNotFoundErr.GetCode()), entityNotFoundErr.GetMessage()) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.Code(entityNotFoundErr.GetCode()), ErrGetRetrievalFailed) } } } else if ident.GetUserName() != "" { @@ -263,12 +262,12 @@ func EntityResolution(ctx context.Context, entityStruct, err := entityToStructPb(ident) if err != nil { logger.Error("unable to make entity struct from username", slog.String("error", err.Error())) - return entityresolution.ResolveEntitiesResponse{}, status.Error(codes.Internal, ErrTextCreationFailed) + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeInternal, ErrCreationFailed) } jsonEntities = append(jsonEntities, entityStruct) } else { - entityNotFoundErr := entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrTextGetRetrievalFailed, Entity: ident.GetUserName()} - return entityresolution.ResolveEntitiesResponse{}, status.Error(codes.Code(entityNotFoundErr.GetCode()), entityNotFoundErr.GetMessage()) + entityNotFoundErr := entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: ErrGetRetrievalFailed.Error(), Entity: ident.GetUserName()} + return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.Code(entityNotFoundErr.GetCode()), ErrGetRetrievalFailed) } } } @@ -278,13 +277,13 @@ func EntityResolution(ctx context.Context, if err != nil { logger.Error("error serializing entity representation!", slog.String("error", err.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextCreationFailed) + connect.NewError(connect.CodeInternal, ErrCreationFailed) } mystruct, structErr := structpb.NewStruct(json) if structErr != nil { logger.Error("error making struct!", slog.String("error", structErr.Error())) return entityresolution.ResolveEntitiesResponse{}, - status.Error(codes.Internal, ErrTextCreationFailed) + connect.NewError(connect.CodeInternal, ErrCreationFailed) } jsonEntities = append(jsonEntities, mystruct) } diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution_test.go b/service/entityresolution/keycloak/keycloak_entity_resolution_test.go index 4024e8cb44..b41d35bed9 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution_test.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution_test.go @@ -10,6 +10,7 @@ import ( "strings" "testing" + "connectrpc.com/connect" "github.com/opentdf/platform/protocol/go/authorization" "github.com/opentdf/platform/protocol/go/entityresolution" keycloak "github.com/opentdf/platform/service/entityresolution/keycloak" @@ -17,7 +18,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) const tokenResp string = ` @@ -31,6 +31,7 @@ const byEmailBobResp = `[ {"id": "bobid", "username":"bob.smith"} ] ` + const byEmailAliceResp = `[ {"id": "aliceid", "username":"alice.smith"} ] @@ -48,27 +49,32 @@ const groupSubmemberResp = `[ {"id": "bobid", "username":"bob.smith"}, {"id": "aliceid", "username":"alice.smith"} ]` + const groupResp = `{ "id": "group1-uuid", "name": "group1" }` + const byClientIDOpentdfSdkResp = `[ {"id": "opentdfsdkclient", "clientId":"opentdf-sdk"} ] ` + const byClientIDTDFEntityResResp = `[ {"id": "tdf-entity-resolution", "clientId":"tdf-entity-resolution"} ] ` -const clientCredentialsJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE2MDQsImlhdCI6MTcxNTA5MTMwNCwianRpIjoiMTE3MTYzMjYtNWQyNS00MjlmLWFjMDItNmU0MjE2OWFjMGJhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiOTljOWVlZDItOTM1Ni00ZjE2LWIwODQtZTgyZDczZjViN2QyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImNsaWVudEhvc3QiOiIxOTIuMTY4LjI0MC4xIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LXRkZi1lbnRpdHktcmVzb2x1dGlvbiIsImNsaWVudEFkZHJlc3MiOiIxOTIuMTY4LjI0MC4xIiwiY2xpZW50X2lkIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIn0.h29QLo-QvIc67KKqU_e1-x6G_o5YQccOyW9AthMdB7xhn9C1dBrcScytaWq1RfETPmnM8MXGezqN4OpXrYr-zbkHhq9ha0Ib-M1VJXNgA5sbgKW9JxGQyudmYPgn4fimDCJtAsXo7C-e3mYNm6DJS0zhGQ3msmjLTcHmIPzWlj7VjtPgKhYV75b7yr_yZNBdHjf3EZqfynU2sL8bKa1w7DYDNQve7ThtD4MeKLiuOQHa3_23dECs_ptvPVks7pLGgRKfgGHBC-KQuopjtxIhwkz2vOWRzugDl0aBJMHfwBajYhgZ2YRlV9dqSxmy8BOj4OEXuHbiyfIpY0rCRpSrGg" -const passwordPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE0ODAsImlhdCI6MTcxNTA5MTE4MCwianRpIjoiZmI5MmM2MTAtYmI0OC00ZDgyLTljZGQtOWFhZjllNzEyNzc3IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiMmU2YzE1ODAtY2ZkMy00M2FiLWIxNzMtZjZjM2JmOGZmNGUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uLXB1YmxpYyIsInNlc3Npb25fc3RhdGUiOiIzN2E3YjdiOS0xZmNlLTQxMmYtOTI1OS1lYzUxMTY3MGVhMGYiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIi8qIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjM3YTdiN2I5LTFmY2UtNDEyZi05MjU5LWVjNTExNjcwZWEwZiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InNhbXBsZSB1c2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2FtcGxlLXVzZXIiLCJnaXZlbl9uYW1lIjoic2FtcGxlIiwiZmFtaWx5X25hbWUiOiJ1c2VyIiwiZW1haWwiOiJzYW1wbGV1c2VyQHNhbXBsZS5jb20ifQ.Gd_OvPNY7UfY7sBKh55TcvWQHmAkYZ2Jb2VyK1lYgse9EBEa_y3uoepZYrGMGkmYdwApg4eauQjxzT_BZYVBc7u9ch3HY_IUuSh3A6FkDDXZIziByP63FYiI4vKTp0w7e2-oYAdaUTDJ1Y50-l_VvRWjdc4fqi-OKH4t8D1rlq0GJ-P7uOl44Ta43YdBMuXI146-eLqx_zLIC49Pg5Y7MD_Lv23QfGTHTP47ckUQueXoGegNLQNE9nPTuD6lNzHD5_MOqse4IKzoWVs_hs4S8SqVxVlN_ZWXkcGhPllfQtf1qxLyFm51eYH3LGxqyNbGr4nQc8djPV0yWqOTrg8IYQ" -const passwordPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE0MjMsImlhdCI6MTcxNTA5MTEyMywianRpIjoiMTNhNDljZmQtOGRiZC00NTA2LTk1NGMtZWFmZGRkNGE4ZTdjIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiMmU2YzE1ODAtY2ZkMy00M2FiLWIxNzMtZjZjM2JmOGZmNGUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwic2Vzc2lvbl9zdGF0ZSI6ImNmZjYwZDZmLWI2M2MtNDBhYy1hYjI3LWFjZmU4MjY5OWQyYSIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJzaWQiOiJjZmY2MGQ2Zi1iNjNjLTQwYWMtYWIyNy1hY2ZlODI2OTlkMmEiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.JFWKf7GZq1f8raP3Jm6rszpwPCh0JnaeZcHyC_AwcsNS6sJ9_qSY9wrbyHmvV9KIGMIPv23fymADZXb0ng7maeAv9NR34KiJqnKbmPeeWwL0cPoGOGOUICL6H5x1iTw7XaMDN2WQRrBRFuUkudybEF8n6fEGsAvcsXViaHjYwJyIEYCnHKPzuTvM1RjyGFsERpFXKls4UB_KhMBEonr4JOskupmX1pADBuicTNx_4whnd6ZDfiF5SSBohFV1ikwFOXK-qZ7znQfE-RJ-jV1CXBgEK8O66TMbMw9MbasS25xKoO0mH1_Ohf9niSXsY02o2qjGFZA9sWRk7K7pNgsxUw" -const authPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTI2NDcsImlhdCI6MTcxNTA5MjM0NywiYXV0aF90aW1lIjoxNzE1MDkyMzQ3LCJqdGkiOiI3NzkwZmVhNC1hNzcyLTRhZTMtOTcyMi0yMTU2MmQyZGM5YmYiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24tcHVibGljIiwic2Vzc2lvbl9zdGF0ZSI6ImFmNmViOTRiLWU4ZDQtNDNlYi1hYzYwLTI3YmZiYjNiOTQxZSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiYWY2ZWI5NGItZThkNC00M2ViLWFjNjAtMjdiZmJiM2I5NDFlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoic2FtcGxlIHVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzYW1wbGUtdXNlciIsImdpdmVuX25hbWUiOiJzYW1wbGUiLCJmYW1pbHlfbmFtZSI6InVzZXIiLCJlbWFpbCI6InNhbXBsZXVzZXJAc2FtcGxlLmNvbSJ9.BfCX_fq2Q6cv5qb6TWzyCNiJf1vFw_iA4UTKr21ahUiNItNSW5ozET2jSLwKNAuMdBNrooU--OV1NniDcviIAMReaAEgjmAyBz6OSwAh3SmxzIU9Zy7f4V032FLDcVVoJ7CefItfBNu7WnWFGS7CYahNX_M2a6LXKhk7WRO4gQ2Ig11gtODlAP8jwLLAMU4_H9mVHD3LXd-IeOsnA8ZuBCq1DeFcn5T9tNZEGe0_21lp8spxoub0MRl-vYbgxEIoaeqxoSipb2hOjF7h0h1uaNhZT4m5ynHdd5yfspD8XjjjwlbXQn9Z8vrZUQQS6HLAi2pJIFNEoYxQk9lHal6VUA" -const authPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTI3NDAsImlhdCI6MTcxNTA5MjQ0MCwiYXV0aF90aW1lIjoxNzE1MDkyNDQwLCJqdGkiOiIzZjk2ZDhjNC0yMjRkLTQyNjAtYmVkMy1lOGY2N2IwYTJjM2EiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJzZXNzaW9uX3N0YXRlIjoiZDI1ZjhhZTMtYzE0Yy00ZWFmLTkzOWMtZjhlNGIyYmE1NDY3IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJkMjVmOGFlMy1jMTRjLTRlYWYtOTM5Yy1mOGU0YjJiYTU0NjciLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.JphgIUbUeEEd25-Ji0o6_pcWvLzcQasCfr1z8WRt3xb1QrkN_d0_rmIpOJ9drhp8LjJPQRhFVxEU2TnAlYJ225IjPYolCrnEtKWsBbPJH9dP0cIJlilYplN4RZbmI9VbF578zAgVAs40n8aalNyxqYbPq_JViHDl_ufl4VEQ4Entzlp980I8whx3kfTygu0Yfl4eHLghPGt4LNPUmfeOIy8NKHbhmjHwKufrTmd0NV07cAOMUWl1NAF_4QWqmSqAY0SIcamwE7YlpuImzhj5PQH9tlyJMLr5m-k8CgKRfhpQ0H9cfVGUzWGG2A-lcNvxNmsk1kobmfHczjw13ajLKg" -const implicitPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTM4MzgsImlhdCI6MTcxNTA5MjkzOCwiYXV0aF90aW1lIjoxNzE1MDkyOTM4LCJqdGkiOiI0ZWIzY2I1OS05ZDRhLTQwNjctYmI0YS1iMjNjNDVhMDIyYTIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJzZXNzaW9uX3N0YXRlIjoiYmE1OWFmOTgtNmE3YS00YjRhLTliOTItODU1M2ZkM2EwMTNjIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJiYTU5YWY5OC02YTdhLTRiNGEtOWI5Mi04NTUzZmQzYTAxM2MiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.KQasyQ-f9KBRWRDXg4NikiHlragVil1nlYTQ8czPKku_uncpHZb7PMJhyPrwy72mwC10EJMpBIWGDVRfRjBRHxdzIbjozcGg3vusX748NMiDSlF4KoB5Fz-qExszcszEP5Qm_fvMRFcW7m9RPW9St1aaHcjAOW5Vee9ACJI56YffgqrTn1xp7ha2Z2X8d_NJfJOFdP3cqgxjR7DV5RezkDLRPfxHwJLk3anavSuDScXIO1w1C6AlTUQFVQUEX0DKZIt-RbzKcd6HWBfyDvHUSlfodEI_diWQIL1hEfrBXV6ThuhTqhrghHyIbb2e-zoC20arjMAK0Tr7hMAY4acxgQ" -const implicitPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUxNTE0MTMsImlhdCI6MTcxNTE1MDUxMywiYXV0aF90aW1lIjoxNzE1MTUwNTEzLCJqdGkiOiJlYTRmOGZiYS01ZjljLTRiMzQtYmU1ZC1jNTk2ZGI4YzNlYzkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24tcHVibGljIiwic2Vzc2lvbl9zdGF0ZSI6ImRlM2U2ZDc1LTI3ODItNDg4NS1iYzU4LTU0MmJmYzEzNWNkNSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiZGUzZTZkNzUtMjc4Mi00ODg1LWJjNTgtNTQyYmZjMTM1Y2Q1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoic2FtcGxlIHVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzYW1wbGUtdXNlciIsImdpdmVuX25hbWUiOiJzYW1wbGUiLCJmYW1pbHlfbmFtZSI6InVzZXIiLCJlbWFpbCI6InNhbXBsZXVzZXJAc2FtcGxlLmNvbSJ9.jH60V3ZkuiN6cuEmbRTspnxyOvQs_wNkgoBw9IEZ8E8yGzXDayouduxEd_O-DG6vjT4KPDxGC2lA0V4i-ke7KChkZhRYLkaSuqt2hTlKoLXotepJPq8GBlXhWjCmFMqaXEB8lMAlAEoCT7CWmg03eTBGzwynj0S4rjMuOj6TLf3HIIN0DP7bgtG9uIc0Ah_mTVJ4L6Y5yjv6LC9bMZ7YNpUIkFn-CZTudquxHkLYgxHgaRAfELBvmS5xn0pTrpIfZSdYQK7hGhjhm9fUg4J06Pg6QW-xZe1U7awyNl7pOeeGQ2lVTo1CWrAlOz9lAmzKzAwQakEOMXFxAjJeHsXTWg" -const tokenExchangeJwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImE1NThkYzg0NzYzNDVjY2QyZWFhNjEzNjg4YmI2YTNkIn0.eyJleHAiOjE3MTU3OTA5MTAsImlhdCI6MTcxNTc5MDYxMCwianRpIjoiNjEyOTI2NzQtMDhmOS00ZmQ1LTk3Y2MtZDg3M2RhODRkZjllIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbC1kc3AudmlydHJ1LmNvbTo4NDQzL2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIiwiYWNjb3VudCIsIm9wZW50ZGYtc2RrIl0sInN1YiI6ImU2ZWI0YWU1LThjMDUtNDI3NC04ZmExLTFmMGY1ZmJjY2JkZiIsInR5cCI6IkJlYXJlciIsImF6cCI6Im9wZW50ZGYiLCJzZXNzaW9uX3N0YXRlIjoiZTQ0YzMxNWMtNjk5Yy00NGFkLTk2NDUtNmRkMmIyMjgzN2JlIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLXJlYWRvbmx5IiwiZGVmYXVsdC1yb2xlcy1vcGVudGRmIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJlNDRjMzE1Yy02OTljLTQ0YWQtOTY0NS02ZGQyYjIyODM3YmUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1vcGVudGRmLXNkayJ9.dmAulsUNfdPXVyWmVPsbGqaztshyHTD-m2hh1l2hmhwuNISJZjON0e1kXNxYXRLABr_PJzIpGYQCXz98yxOyiw" +const ( + clientCredentialsJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE2MDQsImlhdCI6MTcxNTA5MTMwNCwianRpIjoiMTE3MTYzMjYtNWQyNS00MjlmLWFjMDItNmU0MjE2OWFjMGJhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiOTljOWVlZDItOTM1Ni00ZjE2LWIwODQtZTgyZDczZjViN2QyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImNsaWVudEhvc3QiOiIxOTIuMTY4LjI0MC4xIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LXRkZi1lbnRpdHktcmVzb2x1dGlvbiIsImNsaWVudEFkZHJlc3MiOiIxOTIuMTY4LjI0MC4xIiwiY2xpZW50X2lkIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIn0.h29QLo-QvIc67KKqU_e1-x6G_o5YQccOyW9AthMdB7xhn9C1dBrcScytaWq1RfETPmnM8MXGezqN4OpXrYr-zbkHhq9ha0Ib-M1VJXNgA5sbgKW9JxGQyudmYPgn4fimDCJtAsXo7C-e3mYNm6DJS0zhGQ3msmjLTcHmIPzWlj7VjtPgKhYV75b7yr_yZNBdHjf3EZqfynU2sL8bKa1w7DYDNQve7ThtD4MeKLiuOQHa3_23dECs_ptvPVks7pLGgRKfgGHBC-KQuopjtxIhwkz2vOWRzugDl0aBJMHfwBajYhgZ2YRlV9dqSxmy8BOj4OEXuHbiyfIpY0rCRpSrGg" + passwordPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE0ODAsImlhdCI6MTcxNTA5MTE4MCwianRpIjoiZmI5MmM2MTAtYmI0OC00ZDgyLTljZGQtOWFhZjllNzEyNzc3IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiMmU2YzE1ODAtY2ZkMy00M2FiLWIxNzMtZjZjM2JmOGZmNGUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uLXB1YmxpYyIsInNlc3Npb25fc3RhdGUiOiIzN2E3YjdiOS0xZmNlLTQxMmYtOTI1OS1lYzUxMTY3MGVhMGYiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIi8qIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjM3YTdiN2I5LTFmY2UtNDEyZi05MjU5LWVjNTExNjcwZWEwZiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InNhbXBsZSB1c2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2FtcGxlLXVzZXIiLCJnaXZlbl9uYW1lIjoic2FtcGxlIiwiZmFtaWx5X25hbWUiOiJ1c2VyIiwiZW1haWwiOiJzYW1wbGV1c2VyQHNhbXBsZS5jb20ifQ.Gd_OvPNY7UfY7sBKh55TcvWQHmAkYZ2Jb2VyK1lYgse9EBEa_y3uoepZYrGMGkmYdwApg4eauQjxzT_BZYVBc7u9ch3HY_IUuSh3A6FkDDXZIziByP63FYiI4vKTp0w7e2-oYAdaUTDJ1Y50-l_VvRWjdc4fqi-OKH4t8D1rlq0GJ-P7uOl44Ta43YdBMuXI146-eLqx_zLIC49Pg5Y7MD_Lv23QfGTHTP47ckUQueXoGegNLQNE9nPTuD6lNzHD5_MOqse4IKzoWVs_hs4S8SqVxVlN_ZWXkcGhPllfQtf1qxLyFm51eYH3LGxqyNbGr4nQc8djPV0yWqOTrg8IYQ" + passwordPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE0MjMsImlhdCI6MTcxNTA5MTEyMywianRpIjoiMTNhNDljZmQtOGRiZC00NTA2LTk1NGMtZWFmZGRkNGE4ZTdjIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiMmU2YzE1ODAtY2ZkMy00M2FiLWIxNzMtZjZjM2JmOGZmNGUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwic2Vzc2lvbl9zdGF0ZSI6ImNmZjYwZDZmLWI2M2MtNDBhYy1hYjI3LWFjZmU4MjY5OWQyYSIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJzaWQiOiJjZmY2MGQ2Zi1iNjNjLTQwYWMtYWIyNy1hY2ZlODI2OTlkMmEiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.JFWKf7GZq1f8raP3Jm6rszpwPCh0JnaeZcHyC_AwcsNS6sJ9_qSY9wrbyHmvV9KIGMIPv23fymADZXb0ng7maeAv9NR34KiJqnKbmPeeWwL0cPoGOGOUICL6H5x1iTw7XaMDN2WQRrBRFuUkudybEF8n6fEGsAvcsXViaHjYwJyIEYCnHKPzuTvM1RjyGFsERpFXKls4UB_KhMBEonr4JOskupmX1pADBuicTNx_4whnd6ZDfiF5SSBohFV1ikwFOXK-qZ7znQfE-RJ-jV1CXBgEK8O66TMbMw9MbasS25xKoO0mH1_Ohf9niSXsY02o2qjGFZA9sWRk7K7pNgsxUw" + authPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTI2NDcsImlhdCI6MTcxNTA5MjM0NywiYXV0aF90aW1lIjoxNzE1MDkyMzQ3LCJqdGkiOiI3NzkwZmVhNC1hNzcyLTRhZTMtOTcyMi0yMTU2MmQyZGM5YmYiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24tcHVibGljIiwic2Vzc2lvbl9zdGF0ZSI6ImFmNmViOTRiLWU4ZDQtNDNlYi1hYzYwLTI3YmZiYjNiOTQxZSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiYWY2ZWI5NGItZThkNC00M2ViLWFjNjAtMjdiZmJiM2I5NDFlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoic2FtcGxlIHVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzYW1wbGUtdXNlciIsImdpdmVuX25hbWUiOiJzYW1wbGUiLCJmYW1pbHlfbmFtZSI6InVzZXIiLCJlbWFpbCI6InNhbXBsZXVzZXJAc2FtcGxlLmNvbSJ9.BfCX_fq2Q6cv5qb6TWzyCNiJf1vFw_iA4UTKr21ahUiNItNSW5ozET2jSLwKNAuMdBNrooU--OV1NniDcviIAMReaAEgjmAyBz6OSwAh3SmxzIU9Zy7f4V032FLDcVVoJ7CefItfBNu7WnWFGS7CYahNX_M2a6LXKhk7WRO4gQ2Ig11gtODlAP8jwLLAMU4_H9mVHD3LXd-IeOsnA8ZuBCq1DeFcn5T9tNZEGe0_21lp8spxoub0MRl-vYbgxEIoaeqxoSipb2hOjF7h0h1uaNhZT4m5ynHdd5yfspD8XjjjwlbXQn9Z8vrZUQQS6HLAi2pJIFNEoYxQk9lHal6VUA" + authPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTI3NDAsImlhdCI6MTcxNTA5MjQ0MCwiYXV0aF90aW1lIjoxNzE1MDkyNDQwLCJqdGkiOiIzZjk2ZDhjNC0yMjRkLTQyNjAtYmVkMy1lOGY2N2IwYTJjM2EiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJzZXNzaW9uX3N0YXRlIjoiZDI1ZjhhZTMtYzE0Yy00ZWFmLTkzOWMtZjhlNGIyYmE1NDY3IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJkMjVmOGFlMy1jMTRjLTRlYWYtOTM5Yy1mOGU0YjJiYTU0NjciLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.JphgIUbUeEEd25-Ji0o6_pcWvLzcQasCfr1z8WRt3xb1QrkN_d0_rmIpOJ9drhp8LjJPQRhFVxEU2TnAlYJ225IjPYolCrnEtKWsBbPJH9dP0cIJlilYplN4RZbmI9VbF578zAgVAs40n8aalNyxqYbPq_JViHDl_ufl4VEQ4Entzlp980I8whx3kfTygu0Yfl4eHLghPGt4LNPUmfeOIy8NKHbhmjHwKufrTmd0NV07cAOMUWl1NAF_4QWqmSqAY0SIcamwE7YlpuImzhj5PQH9tlyJMLr5m-k8CgKRfhpQ0H9cfVGUzWGG2A-lcNvxNmsk1kobmfHczjw13ajLKg" + implicitPrivClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTM4MzgsImlhdCI6MTcxNTA5MjkzOCwiYXV0aF90aW1lIjoxNzE1MDkyOTM4LCJqdGkiOiI0ZWIzY2I1OS05ZDRhLTQwNjctYmI0YS1iMjNjNDVhMDIyYTIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJzZXNzaW9uX3N0YXRlIjoiYmE1OWFmOTgtNmE3YS00YjRhLTliOTItODU1M2ZkM2EwMTNjIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJiYTU5YWY5OC02YTdhLTRiNGEtOWI5Mi04NTUzZmQzYTAxM2MiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJzYW1wbGUgdXNlciIsInByZWZlcnJlZF91c2VybmFtZSI6InNhbXBsZS11c2VyIiwiZ2l2ZW5fbmFtZSI6InNhbXBsZSIsImZhbWlseV9uYW1lIjoidXNlciIsImVtYWlsIjoic2FtcGxldXNlckBzYW1wbGUuY29tIn0.KQasyQ-f9KBRWRDXg4NikiHlragVil1nlYTQ8czPKku_uncpHZb7PMJhyPrwy72mwC10EJMpBIWGDVRfRjBRHxdzIbjozcGg3vusX748NMiDSlF4KoB5Fz-qExszcszEP5Qm_fvMRFcW7m9RPW9St1aaHcjAOW5Vee9ACJI56YffgqrTn1xp7ha2Z2X8d_NJfJOFdP3cqgxjR7DV5RezkDLRPfxHwJLk3anavSuDScXIO1w1C6AlTUQFVQUEX0DKZIt-RbzKcd6HWBfyDvHUSlfodEI_diWQIL1hEfrBXV6ThuhTqhrghHyIbb2e-zoC20arjMAK0Tr7hMAY4acxgQ" + implicitPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUxNTE0MTMsImlhdCI6MTcxNTE1MDUxMywiYXV0aF90aW1lIjoxNzE1MTUwNTEzLCJqdGkiOiJlYTRmOGZiYS01ZjljLTRiMzQtYmU1ZC1jNTk2ZGI4YzNlYzkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvb3BlbnRkZiIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0Ojg4ODgiLCJ0ZGYtZW50aXR5LXJlc29sdXRpb24iLCJyZWFsbS1tYW5hZ2VtZW50IiwiYWNjb3VudCJdLCJzdWIiOiIyZTZjMTU4MC1jZmQzLTQzYWItYjE3My1mNmMzYmY4ZmY0ZTIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ0ZGYtZW50aXR5LXJlc29sdXRpb24tcHVibGljIiwic2Vzc2lvbl9zdGF0ZSI6ImRlM2U2ZDc1LTI3ODItNDg4NS1iYzU4LTU0MmJmYzEzNWNkNSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib3BlbnRkZi1vcmctYWRtaW4iLCJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsidGRmLWVudGl0eS1yZXNvbHV0aW9uIjp7InJvbGVzIjpbImVudGl0eS1yZXNvbHV0aW9uLXRlc3Qtcm9sZSJdfSwicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwic2lkIjoiZGUzZTZkNzUtMjc4Mi00ODg1LWJjNTgtNTQyYmZjMTM1Y2Q1IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoic2FtcGxlIHVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzYW1wbGUtdXNlciIsImdpdmVuX25hbWUiOiJzYW1wbGUiLCJmYW1pbHlfbmFtZSI6InVzZXIiLCJlbWFpbCI6InNhbXBsZXVzZXJAc2FtcGxlLmNvbSJ9.jH60V3ZkuiN6cuEmbRTspnxyOvQs_wNkgoBw9IEZ8E8yGzXDayouduxEd_O-DG6vjT4KPDxGC2lA0V4i-ke7KChkZhRYLkaSuqt2hTlKoLXotepJPq8GBlXhWjCmFMqaXEB8lMAlAEoCT7CWmg03eTBGzwynj0S4rjMuOj6TLf3HIIN0DP7bgtG9uIc0Ah_mTVJ4L6Y5yjv6LC9bMZ7YNpUIkFn-CZTudquxHkLYgxHgaRAfELBvmS5xn0pTrpIfZSdYQK7hGhjhm9fUg4J06Pg6QW-xZe1U7awyNl7pOeeGQ2lVTo1CWrAlOz9lAmzKzAwQakEOMXFxAjJeHsXTWg" + tokenExchangeJwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImE1NThkYzg0NzYzNDVjY2QyZWFhNjEzNjg4YmI2YTNkIn0.eyJleHAiOjE3MTU3OTA5MTAsImlhdCI6MTcxNTc5MDYxMCwianRpIjoiNjEyOTI2NzQtMDhmOS00ZmQ1LTk3Y2MtZDg3M2RhODRkZjllIiwiaXNzIjoiaHR0cHM6Ly9sb2NhbC1kc3AudmlydHJ1LmNvbTo4NDQzL2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4MDgwIiwiYWNjb3VudCIsIm9wZW50ZGYtc2RrIl0sInN1YiI6ImU2ZWI0YWU1LThjMDUtNDI3NC04ZmExLTFmMGY1ZmJjY2JkZiIsInR5cCI6IkJlYXJlciIsImF6cCI6Im9wZW50ZGYiLCJzZXNzaW9uX3N0YXRlIjoiZTQ0YzMxNWMtNjk5Yy00NGFkLTk2NDUtNmRkMmIyMjgzN2JlIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLXJlYWRvbmx5IiwiZGVmYXVsdC1yb2xlcy1vcGVudGRmIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJlNDRjMzE1Yy02OTljLTQ0YWQtOTY0NS02ZGQyYjIyODM3YmUiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6InNlcnZpY2UtYWNjb3VudC1vcGVudGRmLXNkayJ9.dmAulsUNfdPXVyWmVPsbGqaztshyHTD-m2hh1l2hmhwuNISJZjON0e1kXNxYXRLABr_PJzIpGYQCXz98yxOyiw" +) func testKeycloakConfig(server *httptest.Server) keycloak.KeycloakConfig { return keycloak.KeycloakConfig{ @@ -108,8 +114,10 @@ func testServerResp(t *testing.T, w http.ResponseWriter, r *http.Request, k stri t.Errorf("UnExpected Request, got: %s", r.URL.Path) } } + func testServer(t *testing.T, userSearchQueryAndResp map[string]string, groupSearchQueryAndResp map[string]string, - groupByIDAndResponse map[string]string, groupMemberQueryAndResponse map[string]string, clientsSearchQueryAndResp map[string]string) *httptest.Server { + groupByIDAndResponse map[string]string, groupMemberQueryAndResponse map[string]string, clientsSearchQueryAndResp map[string]string, +) *httptest.Server { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case r.URL.Path == "/realms/tdf/protocol/openid-connect/token": @@ -141,22 +149,22 @@ func Test_KCEntityResolutionByClientId(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}}) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody csqr := map[string]string{ "clientId=opentdf": byEmailBobResp, } server := testServer(t, nil, nil, nil, nil, csqr) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) _ = json.NewEncoder(os.Stdout).Encode(&resp) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 1) } @@ -172,24 +180,24 @@ func Test_KCEntityResolutionByEmail(t *testing.T) { validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_EmailAddress{EmailAddress: "bob@sample.org"}}) validBody = append(validBody, &authorization.Entity{Id: "1235", EntityType: &authorization.Entity_EmailAddress{EmailAddress: "alice@sample.org"}}) - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 2) assert.Equal(t, "1234", entityRepresentations[0].GetOriginalId()) assert.Len(t, entityRepresentations[0].GetAdditionalProps(), 1) - var propMap = entityRepresentations[0].GetAdditionalProps()[0].AsMap() + propMap := entityRepresentations[0].GetAdditionalProps()[0].AsMap() assert.Equal(t, "bobid", propMap["id"]) assert.Equal(t, "1235", entityRepresentations[1].GetOriginalId()) @@ -210,24 +218,24 @@ func Test_KCEntityResolutionByUsername(t *testing.T) { validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}}) validBody = append(validBody, &authorization.Entity{Id: "1235", EntityType: &authorization.Entity_UserName{UserName: "alice.smith"}}) - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 2) assert.Equal(t, "1234", entityRepresentations[0].GetOriginalId()) assert.Len(t, entityRepresentations[0].GetAdditionalProps(), 1) - var propMap = entityRepresentations[0].GetAdditionalProps()[0].AsMap() + propMap := entityRepresentations[0].GetAdditionalProps()[0].AsMap() assert.Equal(t, "bobid", propMap["id"]) assert.Equal(t, "1235", entityRepresentations[1].GetOriginalId()) @@ -252,24 +260,24 @@ func Test_KCEntityResolutionByGroupEmail(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "123456", EntityType: &authorization.Entity_EmailAddress{EmailAddress: "group1@sample.org"}}) - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 1) assert.Equal(t, "123456", entityRepresentations[0].GetOriginalId()) assert.Len(t, entityRepresentations[0].GetAdditionalProps(), 2) - var propMap = entityRepresentations[0].GetAdditionalProps()[0].AsMap() + propMap := entityRepresentations[0].GetAdditionalProps()[0].AsMap() assert.Equal(t, "bobid", propMap["id"]) propMap = entityRepresentations[0].GetAdditionalProps()[1].AsMap() assert.Equal(t, "aliceid", propMap["id"]) @@ -290,19 +298,19 @@ func Test_KCEntityResolutionNotFoundError(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_EmailAddress{EmailAddress: "random@sample.org"}}) - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.Error(t, reserr) assert.Equal(t, &entityresolution.ResolveEntitiesResponse{}, &resp) - var entityNotFound = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: keycloak.ErrTextGetRetrievalFailed, Entity: "random@sample.org"} - var expectedError = status.Error(codes.Code(entityNotFound.GetCode()), entityNotFound.GetMessage()) + entityNotFound := entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: keycloak.ErrGetRetrievalFailed.Error(), Entity: "random@sample.org"} + expectedError := connect.NewError(connect.Code(entityNotFound.GetCode()), keycloak.ErrGetRetrievalFailed) assert.Equal(t, expectedError, reserr) } @@ -313,13 +321,13 @@ func Test_JwtClientAndUsernameClientCredentials(t *testing.T) { server := testServer(t, nil, nil, nil, nil, csqr) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: clientCredentialsJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -335,13 +343,13 @@ func Test_JwtClientAndUsernamePasswordPub(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: passwordPubClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -357,13 +365,13 @@ func Test_JwtClientAndUsernamePasswordPriv(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: passwordPrivClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -379,13 +387,13 @@ func Test_JwtClientAndUsernameAuthPub(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: authPubClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -401,13 +409,13 @@ func Test_JwtClientAndUsernameAuthPriv(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: authPrivClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -423,13 +431,13 @@ func Test_JwtClientAndUsernameImplicitPub(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: implicitPubClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -445,13 +453,13 @@ func Test_JwtClientAndUsernameImplicitPriv(t *testing.T) { server := testServer(t, nil, nil, nil, nil, nil) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: implicitPrivClientJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -470,13 +478,13 @@ func Test_JwtClientAndClientTokenExchange(t *testing.T) { server := testServer(t, nil, nil, nil, nil, csqr) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: tokenExchangeJwt}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -495,13 +503,13 @@ func Test_JwtMultiple(t *testing.T) { server := testServer(t, nil, nil, nil, nil, csqr) defer server.Close() - var kcconfig = testKeycloakConfig(server) + kcconfig := testKeycloakConfig(server) - var ctxb = context.Background() + ctxb := context.Background() validBody := []*authorization.Token{{Jwt: tokenExchangeJwt, Id: "tok1"}, {Jwt: authPrivClientJwt, Id: "tok2"}} - var resp, reserr = keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.CreateEntityChainFromJwt(ctxb, &entityresolution.CreateEntityChainFromJwtRequest{Tokens: validBody}, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) @@ -534,24 +542,24 @@ func Test_KCEntityResolutionNotFoundInferEmail(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_EmailAddress{EmailAddress: "random@sample.org"}}) - var kcconfig = testKeycloakConfigInferID(server) + kcconfig := testKeycloakConfigInferID(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 1) assert.Equal(t, "1234", entityRepresentations[0].GetOriginalId()) assert.Len(t, entityRepresentations[0].GetAdditionalProps(), 1) - var propMap = entityRepresentations[0].GetAdditionalProps()[0].AsMap() + propMap := entityRepresentations[0].GetAdditionalProps()[0].AsMap() assert.Equal(t, "random@sample.org", propMap["emailAddress"]) assert.Equal(t, "1234", propMap["id"]) } @@ -566,24 +574,24 @@ func Test_KCEntityResolutionNotFoundInferClientId(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_ClientId{ClientId: "random"}}) - var kcconfig = testKeycloakConfigInferID(server) + kcconfig := testKeycloakConfigInferID(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.NoError(t, reserr) - var entityRepresentations = resp.GetEntityRepresentations() + entityRepresentations := resp.GetEntityRepresentations() assert.NotNil(t, entityRepresentations) assert.Len(t, entityRepresentations, 1) assert.Equal(t, "1234", entityRepresentations[0].GetOriginalId()) assert.Len(t, entityRepresentations[0].GetAdditionalProps(), 1) - var propMap = entityRepresentations[0].GetAdditionalProps()[0].AsMap() + propMap := entityRepresentations[0].GetAdditionalProps()[0].AsMap() assert.Equal(t, "random", propMap["clientId"]) assert.Equal(t, "1234", propMap["id"]) } @@ -597,18 +605,18 @@ func Test_KCEntityResolutionNotFoundNotInferUsername(t *testing.T) { var validBody []*authorization.Entity validBody = append(validBody, &authorization.Entity{Id: "1234", EntityType: &authorization.Entity_UserName{UserName: "randomuser"}}) - var kcconfig = testKeycloakConfigInferID(server) + kcconfig := testKeycloakConfigInferID(server) - var ctxb = context.Background() + ctxb := context.Background() - var req = entityresolution.ResolveEntitiesRequest{} + req := entityresolution.ResolveEntitiesRequest{} req.Entities = validBody - var resp, reserr = keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) + resp, reserr := keycloak.EntityResolution(ctxb, &req, kcconfig, logger.CreateTestLogger()) require.Error(t, reserr) assert.Equal(t, &entityresolution.ResolveEntitiesResponse{}, &resp) - var entityNotFound = entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: keycloak.ErrTextGetRetrievalFailed, Entity: "randomuser"} - var expectedError = status.Error(codes.Code(entityNotFound.GetCode()), entityNotFound.GetMessage()) + entityNotFound := entityresolution.EntityNotFoundError{Code: int32(codes.NotFound), Message: keycloak.ErrGetRetrievalFailed.Error(), Entity: "randomuser"} + expectedError := connect.NewError(connect.Code(entityNotFound.GetCode()), keycloak.ErrGetRetrievalFailed) assert.Equal(t, expectedError, reserr) } From c5de039c4b58b2283b9d77ba50f8ccc7475058d6 Mon Sep 17 00:00:00 2001 From: Sean Trantalis Date: Tue, 12 Nov 2024 18:38:07 -0500 Subject: [PATCH 37/37] update authorization svc error responses --- service/authorization/authorization.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go index eeaa9915bf..7112934443 100644 --- a/service/authorization/authorization.go +++ b/service/authorization/authorization.go @@ -9,8 +9,6 @@ import ( "strings" "connectrpc.com/connect" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "github.com/creasty/defaults" "github.com/go-playground/validator/v10" @@ -230,7 +228,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *connect.R attrDefs, err = populateAttrDefValueFqns(attrDefs) if err != nil { - return nil, err + return nil, connect.NewError(connect.CodeInternal, err) } // get the relevant resource attribute fqns @@ -449,12 +447,12 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connec attrsRes, err := as.sdk.Attributes.ListAttributes(ctx, &attr.ListAttributesRequest{}) if err != nil { as.logger.ErrorContext(ctx, "failed to list attributes", slog.String("error", err.Error())) - return nil, status.Error(codes.Internal, "failed to list attributes") + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to list attributes")) } subMapsRes, err := as.sdk.SubjectMapping.ListSubjectMappings(ctx, &subjectmapping.ListSubjectMappingsRequest{}) if err != nil { as.logger.ErrorContext(ctx, "failed to list subject mappings", slog.String("error", err.Error())) - return nil, status.Error(codes.Internal, "failed to list subject mappings") + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to list subject mappings")) } // create a lookup map of attribute value FQNs (based on request scope) scopeMap := makeScopeMap(req.Msg.GetScope()) @@ -470,7 +468,7 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connec // TODO: this could probably be moved to proto validation https://github.com/opentdf/platform/issues/1057 if req.Msg.Entities == nil { as.logger.ErrorContext(ctx, "requires entities") - return nil, status.Error(codes.InvalidArgument, "requires entities") + return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("requires entities")) } rsp := &authorization.GetEntitlementsResponse{ Entitlements: make([]*authorization.EntityEntitlements, len(req.Msg.GetEntities())), @@ -487,14 +485,14 @@ func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connec in, err := entitlements.OpaInput(subjectMappings, ersResp) if err != nil { as.logger.ErrorContext(ctx, "failed to build rego input", slog.String("error", err.Error())) - return nil, status.Error(codes.Internal, "failed to build rego input") + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to build rego input")) } results, err := as.eval.Eval(ctx, rego.EvalInput(in), ) if err != nil { - return nil, status.Error(codes.Internal, "failed to evaluate entitlements policy") + return nil, connect.NewError(connect.CodeInternal, errors.New("failed to evaluate entitlements policy")) } resp := connect.NewResponse(rsp)