diff --git a/app/cli/cmd/organization_apitoken_create.go b/app/cli/cmd/organization_apitoken_create.go index eb773111d..4f04aa2c5 100644 --- a/app/cli/cmd/organization_apitoken_create.go +++ b/app/cli/cmd/organization_apitoken_create.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,8 +27,8 @@ import ( func newAPITokenCreateCmd() *cobra.Command { var ( - description, name string - expiresIn time.Duration + description, name, projectName string + expiresIn time.Duration ) cmd := &cobra.Command{ @@ -40,7 +40,7 @@ func newAPITokenCreateCmd() *cobra.Command { duration = &expiresIn } - res, err := action.NewAPITokenCreate(actionOpts).Run(context.Background(), name, description, duration) + res, err := action.NewAPITokenCreate(actionOpts).Run(context.Background(), name, description, projectName, duration) if err != nil { return fmt.Errorf("creating API token: %w", err) } @@ -61,6 +61,7 @@ func newAPITokenCreateCmd() *cobra.Command { cmd.InheritedFlags().StringVarP(&flagOutputFormat, "output", "o", "table", "output format, valid options are table, json, token") err := cmd.MarkFlagRequired("name") cobra.CheckErr(err) + cmd.Flags().StringVar(&projectName, "project", "", "project name used to scope the token, if not set the token will be created at the organization level") return cmd } @@ -77,9 +78,9 @@ func apiTokenListTableOutput(tokens []*action.APITokenItem) error { t := newTableWriter() - t.AppendHeader(table.Row{"Name", "Description", "Created At", "Expires At", "Revoked At", "Last used at"}) + t.AppendHeader(table.Row{"ID", "Name", "Scope", "Description", "Created At", "Expires At", "Revoked At", "Last used at"}) for _, p := range tokens { - r := table.Row{p.Name, p.Description, p.CreatedAt.Format(time.RFC822)} + r := table.Row{p.ID, p.Name, p.ScopedEntity.String(), p.Description, p.CreatedAt.Format(time.RFC822)} if p.ExpiresAt != nil { r = append(r, p.ExpiresAt.Format(time.RFC822)) } else { diff --git a/app/cli/cmd/organization_apitoken_list.go b/app/cli/cmd/organization_apitoken_list.go index 9b6b7817b..46a79edce 100644 --- a/app/cli/cmd/organization_apitoken_list.go +++ b/app/cli/cmd/organization_apitoken_list.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,20 +18,37 @@ package cmd import ( "context" "fmt" + "slices" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) func newAPITokenListCmd() *cobra.Command { - var includeRevoked bool + var ( + includeRevoked bool + project string + scope string + ) + + var availableScopes = []string{ + "project", + "global", + } cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "List API tokens in this organization", + PreRunE: func(_ *cobra.Command, _ []string) error { + if scope != "" && !slices.Contains(availableScopes, scope) { + return fmt.Errorf("invalid scope %q, please chose one of: %v", scope, availableScopes) + } + + return nil + }, RunE: func(cmd *cobra.Command, args []string) error { - res, err := action.NewAPITokenList(actionOpts).Run(context.Background(), includeRevoked) + res, err := action.NewAPITokenList(actionOpts).Run(context.Background(), includeRevoked, project, scope) if err != nil { return fmt.Errorf("listing API tokens: %w", err) } @@ -41,5 +58,7 @@ func newAPITokenListCmd() *cobra.Command { } cmd.Flags().BoolVarP(&includeRevoked, "all", "a", false, "show all API tokens including revoked ones") + cmd.Flags().StringVarP(&project, "project", "p", "", "filter by project name") + cmd.Flags().StringVarP(&scope, "scope", "s", "", fmt.Sprintf("filter by scope, available scopes: %v", availableScopes)) return cmd } diff --git a/app/cli/cmd/organization_apitoken_revoke.go b/app/cli/cmd/organization_apitoken_revoke.go index b3df4af16..cb5d820c9 100644 --- a/app/cli/cmd/organization_apitoken_revoke.go +++ b/app/cli/cmd/organization_apitoken_revoke.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,13 +24,13 @@ import ( ) func newAPITokenRevokeCmd() *cobra.Command { - var name string + var id string cmd := &cobra.Command{ Use: "revoke", Short: "revoke API token", RunE: func(cmd *cobra.Command, args []string) error { - if err := action.NewAPITokenRevoke(actionOpts).Run(context.Background(), name); err != nil { + if err := action.NewAPITokenRevoke(actionOpts).Run(context.Background(), id); err != nil { return fmt.Errorf("revoking API token: %w", err) } @@ -39,8 +39,8 @@ func newAPITokenRevokeCmd() *cobra.Command { }, } - cmd.Flags().StringVar(&name, "name", "", "API token name") - err := cmd.MarkFlagRequired("name") + cmd.Flags().StringVar(&id, "id", "", "API token ID") + err := cmd.MarkFlagRequired("id") cobra.CheckErr(err) return cmd diff --git a/app/cli/cmd/workflow_contract_describe.go b/app/cli/cmd/workflow_contract_describe.go index 60aa56205..16251af4f 100644 --- a/app/cli/cmd/workflow_contract_describe.go +++ b/app/cli/cmd/workflow_contract_describe.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -86,6 +86,8 @@ func contractDescribeTableOutput(contractWithVersion *action.WorkflowContractWit t.SetTitle("Contract") t.AppendRow(table.Row{"Name", c.Name}) t.AppendSeparator() + t.AppendRow(table.Row{"Scope", c.ScopedEntity.String()}) + t.AppendSeparator() t.AppendRow(table.Row{"Description", c.Description}) t.AppendSeparator() t.AppendRow(table.Row{"Associated Workflows", stringifyAssociatedWorkflows(contractWithVersion)}) diff --git a/app/cli/cmd/workflow_contract_list.go b/app/cli/cmd/workflow_contract_list.go index 39bb40d6c..becf759dd 100644 --- a/app/cli/cmd/workflow_contract_list.go +++ b/app/cli/cmd/workflow_contract_list.go @@ -16,7 +16,6 @@ package cmd import ( - "fmt" "time" "github.com/chainloop-dev/chainloop/app/cli/internal/action" @@ -51,12 +50,7 @@ func contractListTableOutput(contracts []*action.WorkflowContractItem) error { t.AppendHeader(table.Row{"Name", "Latest Revision", "Created At", "Updated At", "# Workflows", "Scope"}) for _, p := range contracts { - scope := "org" - if p.ScopedEntity != nil { - scope = fmt.Sprintf("%s/%s", p.ScopedEntity.Type, p.ScopedEntity.Name) - } - - t.AppendRow(table.Row{p.Name, p.LatestRevision, p.CreatedAt.Format(time.RFC822), p.LatestRevisionCreatedAt.Format(time.RFC822), len(p.WorkflowRefs), scope}) + t.AppendRow(table.Row{p.Name, p.LatestRevision, p.CreatedAt.Format(time.RFC822), p.LatestRevisionCreatedAt.Format(time.RFC822), len(p.WorkflowRefs), p.ScopedEntity.String()}) } t.Render() diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index c9d05bb4d..7ef836da1 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -2044,6 +2044,7 @@ Options --expiration duration optional API token expiration, in hours i.e 1h, 24h, 178h (week), ... -h, --help help for create --name string token name +--project string project name used to scope the token, if not set the token will be created at the organization level ``` Options inherited from parent commands @@ -2108,8 +2109,10 @@ chainloop organization api-token list [flags] Options ``` --a, --all show all API tokens including revoked ones --h, --help help for list +-a, --all show all API tokens including revoked ones +-h, --help help for list +-p, --project string filter by project name +-s, --scope string filter by scope, available scopes: [project global] ``` Options inherited from parent commands @@ -2139,8 +2142,8 @@ chainloop organization api-token revoke [flags] Options ``` --h, --help help for revoke ---name string API token name +-h, --help help for revoke +--id string API token ID ``` Options inherited from parent commands diff --git a/app/cli/internal/action/apitoken_create.go b/app/cli/internal/action/apitoken_create.go index 21d2209ce..b19421b48 100644 --- a/app/cli/internal/action/apitoken_create.go +++ b/app/cli/internal/action/apitoken_create.go @@ -33,7 +33,7 @@ func NewAPITokenCreate(cfg *ActionsOpts) *APITokenCreate { return &APITokenCreate{cfg} } -func (action *APITokenCreate) Run(ctx context.Context, name, description string, expiresIn *time.Duration) (*APITokenItem, error) { +func (action *APITokenCreate) Run(ctx context.Context, name, description, projectName string, expiresIn *time.Duration) (*APITokenItem, error) { client := pb.NewAPITokenServiceClient(action.cfg.CPConnection) req := &pb.APITokenServiceCreateRequest{Name: name, Description: &description} @@ -41,6 +41,12 @@ func (action *APITokenCreate) Run(ctx context.Context, name, description string, req.ExpiresIn = durationpb.New(*expiresIn) } + if projectName != "" { + req.ProjectReference = &pb.IdentityReference{ + Name: &projectName, + } + } + resp, err := client.Create(ctx, req) if err != nil { return nil, fmt.Errorf("creating API token: %w", err) @@ -62,13 +68,12 @@ type APITokenItem struct { Name string `json:"name"` Description string `json:"description"` // JWT is returned only during the creation - JWT string `json:"jwt,omitempty"` - CreatedAt *time.Time `json:"createdAt"` - RevokedAt *time.Time `json:"revokedAt,omitempty"` - ExpiresAt *time.Time `json:"expiresAt,omitempty"` - LastUsedAt *time.Time `json:"lastUsedAt,omitempty"` - ProjectID string `json:"projectId,omitempty"` - ProjectName string `json:"projectName,omitempty"` + JWT string `json:"jwt,omitempty"` + CreatedAt *time.Time `json:"createdAt"` + RevokedAt *time.Time `json:"revokedAt,omitempty"` + ExpiresAt *time.Time `json:"expiresAt,omitempty"` + LastUsedAt *time.Time `json:"lastUsedAt,omitempty"` + ScopedEntity *ScopedEntity `json:"scopedEntity,omitempty"` } func pbAPITokenItemToAPITokenItem(p *pb.APITokenItem) *APITokenItem { @@ -95,12 +100,12 @@ func pbAPITokenItemToAPITokenItem(p *pb.APITokenItem) *APITokenItem { item.LastUsedAt = toTimePtr(p.LastUsedAt.AsTime()) } - if p.ProjectId != "" { - item.ProjectID = p.ProjectId - } - - if p.ProjectName != "" { - item.ProjectName = p.ProjectName + if p.ScopedEntity != nil { + item.ScopedEntity = &ScopedEntity{ + Type: p.ScopedEntity.Type, + ID: p.ScopedEntity.Id, + Name: p.ScopedEntity.Name, + } } return item diff --git a/app/cli/internal/action/apitoken_list.go b/app/cli/internal/action/apitoken_list.go index 486df4fe2..489d53245 100644 --- a/app/cli/internal/action/apitoken_list.go +++ b/app/cli/internal/action/apitoken_list.go @@ -1,5 +1,5 @@ // -// Copyright 2024 The Chainloop Authors. +// Copyright 2024-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -30,9 +30,19 @@ func NewAPITokenList(cfg *ActionsOpts) *APITokenList { return &APITokenList{cfg} } -func (action *APITokenList) Run(ctx context.Context, includeRevoked bool) ([]*APITokenItem, error) { +func (action *APITokenList) Run(ctx context.Context, includeRevoked bool, project string, scope string) ([]*APITokenItem, error) { client := pb.NewAPITokenServiceClient(action.cfg.CPConnection) - resp, err := client.List(ctx, &pb.APITokenServiceListRequest{IncludeRevoked: includeRevoked}) + + req := &pb.APITokenServiceListRequest{IncludeRevoked: includeRevoked} + if project != "" { + req.Project = &pb.IdentityReference{Name: &project} + } + + if scope != "" { + req.Scope = mapScope(scope) + } + + resp, err := client.List(ctx, req) if err != nil { return nil, fmt.Errorf("listing API tokens: %w", err) } @@ -44,3 +54,14 @@ func (action *APITokenList) Run(ctx context.Context, includeRevoked bool) ([]*AP return result, nil } + +func mapScope(scope string) pb.APITokenServiceListRequest_Scope { + switch scope { + case "project": + return pb.APITokenServiceListRequest_SCOPE_PROJECT + case "global": + return pb.APITokenServiceListRequest_SCOPE_GLOBAL + default: + return pb.APITokenServiceListRequest_SCOPE_UNSPECIFIED + } +} diff --git a/app/cli/internal/action/apitoken_revoke.go b/app/cli/internal/action/apitoken_revoke.go index b02a709bf..6c57fc9bc 100644 --- a/app/cli/internal/action/apitoken_revoke.go +++ b/app/cli/internal/action/apitoken_revoke.go @@ -30,9 +30,9 @@ func NewAPITokenRevoke(cfg *ActionsOpts) *APITokenRevoke { return &APITokenRevoke{cfg} } -func (action *APITokenRevoke) Run(ctx context.Context, name string) error { +func (action *APITokenRevoke) Run(ctx context.Context, id string) error { client := pb.NewAPITokenServiceClient(action.cfg.CPConnection) - if _, err := client.Revoke(ctx, &pb.APITokenServiceRevokeRequest{Name: name}); err != nil { + if _, err := client.Revoke(ctx, &pb.APITokenServiceRevokeRequest{Id: id}); err != nil { return fmt.Errorf("revoking API token: %w", err) } diff --git a/app/cli/internal/action/workflow_contract_list.go b/app/cli/internal/action/workflow_contract_list.go index fae0d7946..87989c9dd 100644 --- a/app/cli/internal/action/workflow_contract_list.go +++ b/app/cli/internal/action/workflow_contract_list.go @@ -17,6 +17,7 @@ package action import ( "context" + "fmt" "time" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" @@ -45,6 +46,14 @@ type ScopedEntity struct { Name string `json:"name"` } +func (s *ScopedEntity) String() string { + if s == nil { + return "global" + } + + return fmt.Sprintf("%s/%s", s.Type, s.Name) +} + type WorkflowRef struct { ID string `json:"id"` Name string `json:"name"` diff --git a/app/controlplane/api/controlplane/v1/api_token.pb.go b/app/controlplane/api/controlplane/v1/api_token.pb.go index d205bc5b9..bccee55dd 100644 --- a/app/controlplane/api/controlplane/v1/api_token.pb.go +++ b/app/controlplane/api/controlplane/v1/api_token.pb.go @@ -37,14 +37,65 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type APITokenServiceListRequest_Scope int32 + +const ( + APITokenServiceListRequest_SCOPE_UNSPECIFIED APITokenServiceListRequest_Scope = 0 + APITokenServiceListRequest_SCOPE_PROJECT APITokenServiceListRequest_Scope = 1 + APITokenServiceListRequest_SCOPE_GLOBAL APITokenServiceListRequest_Scope = 2 +) + +// Enum value maps for APITokenServiceListRequest_Scope. +var ( + APITokenServiceListRequest_Scope_name = map[int32]string{ + 0: "SCOPE_UNSPECIFIED", + 1: "SCOPE_PROJECT", + 2: "SCOPE_GLOBAL", + } + APITokenServiceListRequest_Scope_value = map[string]int32{ + "SCOPE_UNSPECIFIED": 0, + "SCOPE_PROJECT": 1, + "SCOPE_GLOBAL": 2, + } +) + +func (x APITokenServiceListRequest_Scope) Enum() *APITokenServiceListRequest_Scope { + p := new(APITokenServiceListRequest_Scope) + *p = x + return p +} + +func (x APITokenServiceListRequest_Scope) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (APITokenServiceListRequest_Scope) Descriptor() protoreflect.EnumDescriptor { + return file_controlplane_v1_api_token_proto_enumTypes[0].Descriptor() +} + +func (APITokenServiceListRequest_Scope) Type() protoreflect.EnumType { + return &file_controlplane_v1_api_token_proto_enumTypes[0] +} + +func (x APITokenServiceListRequest_Scope) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use APITokenServiceListRequest_Scope.Descriptor instead. +func (APITokenServiceListRequest_Scope) EnumDescriptor() ([]byte, []int) { + return file_controlplane_v1_api_token_proto_rawDescGZIP(), []int{4, 0} +} + type APITokenServiceCreateRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Description *string `protobuf:"bytes,1,opt,name=description,proto3,oneof" json:"description,omitempty"` - ExpiresIn *durationpb.Duration `protobuf:"bytes,2,opt,name=expires_in,json=expiresIn,proto3,oneof" json:"expires_in,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description *string `protobuf:"bytes,1,opt,name=description,proto3,oneof" json:"description,omitempty"` + // You might need to specify a project reference if you want/need to create a token scoped to a project + ProjectReference *IdentityReference `protobuf:"bytes,4,opt,name=project_reference,json=projectReference,proto3" json:"project_reference,omitempty"` + ExpiresIn *durationpb.Duration `protobuf:"bytes,2,opt,name=expires_in,json=expiresIn,proto3,oneof" json:"expires_in,omitempty"` } func (x *APITokenServiceCreateRequest) Reset() { @@ -93,6 +144,13 @@ func (x *APITokenServiceCreateRequest) GetDescription() string { return "" } +func (x *APITokenServiceCreateRequest) GetProjectReference() *IdentityReference { + if x != nil { + return x.ProjectReference + } + return nil +} + func (x *APITokenServiceCreateRequest) GetExpiresIn() *durationpb.Duration { if x != nil { return x.ExpiresIn @@ -152,7 +210,7 @@ type APITokenServiceRevokeRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` } func (x *APITokenServiceRevokeRequest) Reset() { @@ -187,9 +245,9 @@ func (*APITokenServiceRevokeRequest) Descriptor() ([]byte, []int) { return file_controlplane_v1_api_token_proto_rawDescGZIP(), []int{2} } -func (x *APITokenServiceRevokeRequest) GetName() string { +func (x *APITokenServiceRevokeRequest) GetId() string { if x != nil { - return x.Name + return x.Id } return "" } @@ -238,6 +296,10 @@ type APITokenServiceListRequest struct { unknownFields protoimpl.UnknownFields IncludeRevoked bool `protobuf:"varint,1,opt,name=include_revoked,json=includeRevoked,proto3" json:"include_revoked,omitempty"` + // optional project reference to filter by + Project *IdentityReference `protobuf:"bytes,4,opt,name=project,proto3" json:"project,omitempty"` + // filter by the scope of the token + Scope APITokenServiceListRequest_Scope `protobuf:"varint,2,opt,name=scope,proto3,enum=controlplane.v1.APITokenServiceListRequest_Scope" json:"scope,omitempty"` } func (x *APITokenServiceListRequest) Reset() { @@ -279,6 +341,20 @@ func (x *APITokenServiceListRequest) GetIncludeRevoked() bool { return false } +func (x *APITokenServiceListRequest) GetProject() *IdentityReference { + if x != nil { + return x.Project + } + return nil +} + +func (x *APITokenServiceListRequest) GetScope() APITokenServiceListRequest_Scope { + if x != nil { + return x.Scope + } + return APITokenServiceListRequest_SCOPE_UNSPECIFIED +} + type APITokenServiceListResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -391,83 +467,96 @@ var file_controlplane_v1_api_token_proto_rawDesc = []byte{ 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x01, 0x0a, 0x1c, 0x41, 0x50, 0x49, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x3d, 0x0a, - 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x09, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x49, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, - 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, 0x0b, - 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x22, 0xc9, 0x01, 0x0a, 0x1d, - 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x50, - 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x75, 0x6c, 0x6c, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x1a, 0x53, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x75, - 0x6c, 0x6c, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0xb8, 0x01, 0x0a, 0x1c, 0x41, 0x50, 0x49, 0x54, + 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, + 0x02, 0x0a, 0x1c, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x88, 0x01, 0x01, 0x12, 0x4f, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x49, 0x6e, + 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x69, 0x6e, 0x22, 0xc9, 0x01, 0x0a, 0x1d, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x75, 0x6c, + 0x6c, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x53, 0x0a, 0x0c, 0x41, 0x50, 0x49, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x75, 0x6c, 0x6c, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x74, 0x65, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, + 0x6a, 0x77, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x38, + 0x0a, 0x1c, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, - 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, - 0x3a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, - 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, - 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, - 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, - 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0x1f, 0x0a, 0x1d, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x45, 0x0a, 0x1a, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x22, 0x54, 0x0a, 0x1b, 0x41, 0x50, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x91, 0x02, 0x0a, 0x1a, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x32, 0xc6, 0x02, 0x0a, 0x0f, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x67, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x2d, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x64, 0x12, 0x3c, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, - 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x43, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x43, 0x4f, 0x50, + 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, + 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x10, 0x02, 0x22, 0x54, 0x0a, + 0x1b, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x32, 0xc6, 0x02, 0x0a, 0x0f, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x67, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x61, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x67, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, - 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x2d, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -482,34 +571,40 @@ func file_controlplane_v1_api_token_proto_rawDescGZIP() []byte { return file_controlplane_v1_api_token_proto_rawDescData } +var file_controlplane_v1_api_token_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_controlplane_v1_api_token_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_controlplane_v1_api_token_proto_goTypes = []interface{}{ - (*APITokenServiceCreateRequest)(nil), // 0: controlplane.v1.APITokenServiceCreateRequest - (*APITokenServiceCreateResponse)(nil), // 1: controlplane.v1.APITokenServiceCreateResponse - (*APITokenServiceRevokeRequest)(nil), // 2: controlplane.v1.APITokenServiceRevokeRequest - (*APITokenServiceRevokeResponse)(nil), // 3: controlplane.v1.APITokenServiceRevokeResponse - (*APITokenServiceListRequest)(nil), // 4: controlplane.v1.APITokenServiceListRequest - (*APITokenServiceListResponse)(nil), // 5: controlplane.v1.APITokenServiceListResponse - (*APITokenServiceCreateResponse_APITokenFull)(nil), // 6: controlplane.v1.APITokenServiceCreateResponse.APITokenFull - (*durationpb.Duration)(nil), // 7: google.protobuf.Duration - (*APITokenItem)(nil), // 8: controlplane.v1.APITokenItem + (APITokenServiceListRequest_Scope)(0), // 0: controlplane.v1.APITokenServiceListRequest.Scope + (*APITokenServiceCreateRequest)(nil), // 1: controlplane.v1.APITokenServiceCreateRequest + (*APITokenServiceCreateResponse)(nil), // 2: controlplane.v1.APITokenServiceCreateResponse + (*APITokenServiceRevokeRequest)(nil), // 3: controlplane.v1.APITokenServiceRevokeRequest + (*APITokenServiceRevokeResponse)(nil), // 4: controlplane.v1.APITokenServiceRevokeResponse + (*APITokenServiceListRequest)(nil), // 5: controlplane.v1.APITokenServiceListRequest + (*APITokenServiceListResponse)(nil), // 6: controlplane.v1.APITokenServiceListResponse + (*APITokenServiceCreateResponse_APITokenFull)(nil), // 7: controlplane.v1.APITokenServiceCreateResponse.APITokenFull + (*IdentityReference)(nil), // 8: controlplane.v1.IdentityReference + (*durationpb.Duration)(nil), // 9: google.protobuf.Duration + (*APITokenItem)(nil), // 10: controlplane.v1.APITokenItem } var file_controlplane_v1_api_token_proto_depIdxs = []int32{ - 7, // 0: controlplane.v1.APITokenServiceCreateRequest.expires_in:type_name -> google.protobuf.Duration - 6, // 1: controlplane.v1.APITokenServiceCreateResponse.result:type_name -> controlplane.v1.APITokenServiceCreateResponse.APITokenFull - 8, // 2: controlplane.v1.APITokenServiceListResponse.result:type_name -> controlplane.v1.APITokenItem - 8, // 3: controlplane.v1.APITokenServiceCreateResponse.APITokenFull.item:type_name -> controlplane.v1.APITokenItem - 0, // 4: controlplane.v1.APITokenService.Create:input_type -> controlplane.v1.APITokenServiceCreateRequest - 4, // 5: controlplane.v1.APITokenService.List:input_type -> controlplane.v1.APITokenServiceListRequest - 2, // 6: controlplane.v1.APITokenService.Revoke:input_type -> controlplane.v1.APITokenServiceRevokeRequest - 1, // 7: controlplane.v1.APITokenService.Create:output_type -> controlplane.v1.APITokenServiceCreateResponse - 5, // 8: controlplane.v1.APITokenService.List:output_type -> controlplane.v1.APITokenServiceListResponse - 3, // 9: controlplane.v1.APITokenService.Revoke:output_type -> controlplane.v1.APITokenServiceRevokeResponse - 7, // [7:10] is the sub-list for method output_type - 4, // [4:7] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 8, // 0: controlplane.v1.APITokenServiceCreateRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 9, // 1: controlplane.v1.APITokenServiceCreateRequest.expires_in:type_name -> google.protobuf.Duration + 7, // 2: controlplane.v1.APITokenServiceCreateResponse.result:type_name -> controlplane.v1.APITokenServiceCreateResponse.APITokenFull + 8, // 3: controlplane.v1.APITokenServiceListRequest.project:type_name -> controlplane.v1.IdentityReference + 0, // 4: controlplane.v1.APITokenServiceListRequest.scope:type_name -> controlplane.v1.APITokenServiceListRequest.Scope + 10, // 5: controlplane.v1.APITokenServiceListResponse.result:type_name -> controlplane.v1.APITokenItem + 10, // 6: controlplane.v1.APITokenServiceCreateResponse.APITokenFull.item:type_name -> controlplane.v1.APITokenItem + 1, // 7: controlplane.v1.APITokenService.Create:input_type -> controlplane.v1.APITokenServiceCreateRequest + 5, // 8: controlplane.v1.APITokenService.List:input_type -> controlplane.v1.APITokenServiceListRequest + 3, // 9: controlplane.v1.APITokenService.Revoke:input_type -> controlplane.v1.APITokenServiceRevokeRequest + 2, // 10: controlplane.v1.APITokenService.Create:output_type -> controlplane.v1.APITokenServiceCreateResponse + 6, // 11: controlplane.v1.APITokenService.List:output_type -> controlplane.v1.APITokenServiceListResponse + 4, // 12: controlplane.v1.APITokenService.Revoke:output_type -> controlplane.v1.APITokenServiceRevokeResponse + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_controlplane_v1_api_token_proto_init() } @@ -518,6 +613,7 @@ func file_controlplane_v1_api_token_proto_init() { return } file_controlplane_v1_response_messages_proto_init() + file_controlplane_v1_shared_message_proto_init() if !protoimpl.UnsafeEnabled { file_controlplane_v1_api_token_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*APITokenServiceCreateRequest); i { @@ -610,13 +706,14 @@ func file_controlplane_v1_api_token_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_api_token_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 7, NumExtensions: 0, NumServices: 1, }, GoTypes: file_controlplane_v1_api_token_proto_goTypes, DependencyIndexes: file_controlplane_v1_api_token_proto_depIdxs, + EnumInfos: file_controlplane_v1_api_token_proto_enumTypes, MessageInfos: file_controlplane_v1_api_token_proto_msgTypes, }.Build() File_controlplane_v1_api_token_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/api_token.proto b/app/controlplane/api/controlplane/v1/api_token.proto index b7f160a4e..609162da0 100644 --- a/app/controlplane/api/controlplane/v1/api_token.proto +++ b/app/controlplane/api/controlplane/v1/api_token.proto @@ -19,6 +19,7 @@ package controlplane.v1; import "buf/validate/validate.proto"; import "controlplane/v1/response_messages.proto"; +import "controlplane/v1/shared_message.proto"; import "google/protobuf/duration.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; @@ -33,6 +34,8 @@ message APITokenServiceCreateRequest { string name = 3 [(buf.validate.field).string.min_len = 1]; optional string description = 1; + // You might need to specify a project reference if you want/need to create a token scoped to a project + IdentityReference project_reference = 4; optional google.protobuf.Duration expires_in = 2; } @@ -46,20 +49,25 @@ message APITokenServiceCreateResponse { } message APITokenServiceRevokeRequest { - string name = 1 [(buf.validate.field) = { - // NOTE: validations can not be shared yet https://github.com/bufbuild/protovalidate/issues/51 - cel: { - message: "must contain only lowercase letters, numbers, and hyphens." - expression: "this.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')" - id: "name.dns-1123" - } - }]; + string id = 1 [(buf.validate.field).string.uuid = true]; } message APITokenServiceRevokeResponse {} message APITokenServiceListRequest { bool include_revoked = 1; + + // optional project reference to filter by + IdentityReference project = 4; + + enum Scope { + SCOPE_UNSPECIFIED = 0; + SCOPE_PROJECT = 1; + SCOPE_GLOBAL = 2; + } + + // filter by the scope of the token + Scope scope = 2; } message APITokenServiceListResponse { diff --git a/app/controlplane/api/controlplane/v1/project.pb.go b/app/controlplane/api/controlplane/v1/project.pb.go index 0deb0ed60..618dfc62c 100644 --- a/app/controlplane/api/controlplane/v1/project.pb.go +++ b/app/controlplane/api/controlplane/v1/project.pb.go @@ -25,7 +25,6 @@ import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" @@ -91,326 +90,6 @@ func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} } -type ProjectServiceAPITokenCreateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - ProjectName string `protobuf:"bytes,2,opt,name=project_name,json=projectName,proto3" json:"project_name,omitempty"` - Description *string `protobuf:"bytes,3,opt,name=description,proto3,oneof" json:"description,omitempty"` - ExpiresIn *durationpb.Duration `protobuf:"bytes,4,opt,name=expires_in,json=expiresIn,proto3,oneof" json:"expires_in,omitempty"` -} - -func (x *ProjectServiceAPITokenCreateRequest) Reset() { - *x = ProjectServiceAPITokenCreateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenCreateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenCreateRequest) ProtoMessage() {} - -func (x *ProjectServiceAPITokenCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenCreateRequest.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenCreateRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} -} - -func (x *ProjectServiceAPITokenCreateRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ProjectServiceAPITokenCreateRequest) GetProjectName() string { - if x != nil { - return x.ProjectName - } - return "" -} - -func (x *ProjectServiceAPITokenCreateRequest) GetDescription() string { - if x != nil && x.Description != nil { - return *x.Description - } - return "" -} - -func (x *ProjectServiceAPITokenCreateRequest) GetExpiresIn() *durationpb.Duration { - if x != nil { - return x.ExpiresIn - } - return nil -} - -type ProjectServiceAPITokenCreateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Result *ProjectServiceAPITokenCreateResponse_APITokenFull `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` -} - -func (x *ProjectServiceAPITokenCreateResponse) Reset() { - *x = ProjectServiceAPITokenCreateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenCreateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenCreateResponse) ProtoMessage() {} - -func (x *ProjectServiceAPITokenCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenCreateResponse.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenCreateResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{1} -} - -func (x *ProjectServiceAPITokenCreateResponse) GetResult() *ProjectServiceAPITokenCreateResponse_APITokenFull { - if x != nil { - return x.Result - } - return nil -} - -// ProjectServiceAPITokenRevokeRequest contains the information needed to revoke an API token for a project -type ProjectServiceAPITokenRevokeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The name of the API token to revoke - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // IdentityReference is used to specify the project by either its ID or name - ProjectReference *IdentityReference `protobuf:"bytes,2,opt,name=project_reference,json=projectReference,proto3" json:"project_reference,omitempty"` -} - -func (x *ProjectServiceAPITokenRevokeRequest) Reset() { - *x = ProjectServiceAPITokenRevokeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenRevokeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenRevokeRequest) ProtoMessage() {} - -func (x *ProjectServiceAPITokenRevokeRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenRevokeRequest.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenRevokeRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} -} - -func (x *ProjectServiceAPITokenRevokeRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ProjectServiceAPITokenRevokeRequest) GetProjectReference() *IdentityReference { - if x != nil { - return x.ProjectReference - } - return nil -} - -// ProjectServiceAPITokenRevokeResponse is returned upon successful revocation of an API token -type ProjectServiceAPITokenRevokeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ProjectServiceAPITokenRevokeResponse) Reset() { - *x = ProjectServiceAPITokenRevokeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenRevokeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenRevokeResponse) ProtoMessage() {} - -func (x *ProjectServiceAPITokenRevokeResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenRevokeResponse.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenRevokeResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} -} - -// ProjectServiceAPITokenListRequest contains the information needed to list API tokens for a project -type ProjectServiceAPITokenListRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // IdentityReference is used to specify the project by either its ID or name - ProjectReference *IdentityReference `protobuf:"bytes,1,opt,name=project_reference,json=projectReference,proto3" json:"project_reference,omitempty"` - // Flag to include revoked tokens in the list - IncludeRevoked bool `protobuf:"varint,2,opt,name=include_revoked,json=includeRevoked,proto3" json:"include_revoked,omitempty"` -} - -func (x *ProjectServiceAPITokenListRequest) Reset() { - *x = ProjectServiceAPITokenListRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenListRequest) ProtoMessage() {} - -func (x *ProjectServiceAPITokenListRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenListRequest.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenListRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} -} - -func (x *ProjectServiceAPITokenListRequest) GetProjectReference() *IdentityReference { - if x != nil { - return x.ProjectReference - } - return nil -} - -func (x *ProjectServiceAPITokenListRequest) GetIncludeRevoked() bool { - if x != nil { - return x.IncludeRevoked - } - return false -} - -type ProjectServiceAPITokenListResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Result []*APITokenItem `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"` -} - -func (x *ProjectServiceAPITokenListResponse) Reset() { - *x = ProjectServiceAPITokenListResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenListResponse) ProtoMessage() {} - -func (x *ProjectServiceAPITokenListResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenListResponse.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenListResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} -} - -func (x *ProjectServiceAPITokenListResponse) GetResult() []*APITokenItem { - if x != nil { - return x.Result - } - return nil -} - // ProjectServiceListMembersRequest contains the information needed to list members of a project type ProjectServiceListMembersRequest struct { state protoimpl.MessageState @@ -426,7 +105,7 @@ type ProjectServiceListMembersRequest struct { func (x *ProjectServiceListMembersRequest) Reset() { *x = ProjectServiceListMembersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -439,7 +118,7 @@ func (x *ProjectServiceListMembersRequest) String() string { func (*ProjectServiceListMembersRequest) ProtoMessage() {} func (x *ProjectServiceListMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -452,7 +131,7 @@ func (x *ProjectServiceListMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceListMembersRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceListMembersRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} } func (x *ProjectServiceListMembersRequest) GetProjectReference() *IdentityReference { @@ -484,7 +163,7 @@ type ProjectServiceListMembersResponse struct { func (x *ProjectServiceListMembersResponse) Reset() { *x = ProjectServiceListMembersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -497,7 +176,7 @@ func (x *ProjectServiceListMembersResponse) String() string { func (*ProjectServiceListMembersResponse) ProtoMessage() {} func (x *ProjectServiceListMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -510,7 +189,7 @@ func (x *ProjectServiceListMembersResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceListMembersResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceListMembersResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{1} } func (x *ProjectServiceListMembersResponse) GetMembers() []*ProjectMember { @@ -551,7 +230,7 @@ type ProjectMember struct { func (x *ProjectMember) Reset() { *x = ProjectMember{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -564,7 +243,7 @@ func (x *ProjectMember) String() string { func (*ProjectMember) ProtoMessage() {} func (x *ProjectMember) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -577,7 +256,7 @@ func (x *ProjectMember) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectMember.ProtoReflect.Descriptor instead. func (*ProjectMember) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} } func (m *ProjectMember) GetSubject() isProjectMember_Subject { @@ -657,7 +336,7 @@ type ProjectServiceAddMemberRequest struct { func (x *ProjectServiceAddMemberRequest) Reset() { *x = ProjectServiceAddMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -670,7 +349,7 @@ func (x *ProjectServiceAddMemberRequest) String() string { func (*ProjectServiceAddMemberRequest) ProtoMessage() {} func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -683,7 +362,7 @@ func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} } func (x *ProjectServiceAddMemberRequest) GetProjectReference() *IdentityReference { @@ -717,7 +396,7 @@ type ProjectServiceAddMemberResponse struct { func (x *ProjectServiceAddMemberResponse) Reset() { *x = ProjectServiceAddMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -730,7 +409,7 @@ func (x *ProjectServiceAddMemberResponse) String() string { func (*ProjectServiceAddMemberResponse) ProtoMessage() {} func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -743,7 +422,7 @@ func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} } type ProjectServiceRemoveMemberRequest struct { @@ -760,7 +439,7 @@ type ProjectServiceRemoveMemberRequest struct { func (x *ProjectServiceRemoveMemberRequest) Reset() { *x = ProjectServiceRemoveMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -773,7 +452,7 @@ func (x *ProjectServiceRemoveMemberRequest) String() string { func (*ProjectServiceRemoveMemberRequest) ProtoMessage() {} func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -786,7 +465,7 @@ func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} } func (x *ProjectServiceRemoveMemberRequest) GetProjectReference() *IdentityReference { @@ -813,7 +492,7 @@ type ProjectServiceRemoveMemberResponse struct { func (x *ProjectServiceRemoveMemberResponse) Reset() { *x = ProjectServiceRemoveMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[12] + mi := &file_controlplane_v1_project_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -826,7 +505,7 @@ func (x *ProjectServiceRemoveMemberResponse) String() string { func (*ProjectServiceRemoveMemberResponse) ProtoMessage() {} func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[12] + mi := &file_controlplane_v1_project_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -839,7 +518,7 @@ func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{12} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} } // ProjectMembershipReference is used to reference a user or group in the context of project membership @@ -860,7 +539,7 @@ type ProjectMembershipReference struct { func (x *ProjectMembershipReference) Reset() { *x = ProjectMembershipReference{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[13] + mi := &file_controlplane_v1_project_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -873,7 +552,7 @@ func (x *ProjectMembershipReference) String() string { func (*ProjectMembershipReference) ProtoMessage() {} func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[13] + mi := &file_controlplane_v1_project_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -886,7 +565,7 @@ func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectMembershipReference.ProtoReflect.Descriptor instead. func (*ProjectMembershipReference) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{13} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} } func (m *ProjectMembershipReference) GetMembershipReference() isProjectMembershipReference_MembershipReference { @@ -946,7 +625,7 @@ type ProjectServiceUpdateMemberRoleRequest struct { func (x *ProjectServiceUpdateMemberRoleRequest) Reset() { *x = ProjectServiceUpdateMemberRoleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[14] + mi := &file_controlplane_v1_project_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -959,7 +638,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) String() string { func (*ProjectServiceUpdateMemberRoleRequest) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[14] + mi := &file_controlplane_v1_project_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -972,7 +651,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use ProjectServiceUpdateMemberRoleRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{14} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} } func (x *ProjectServiceUpdateMemberRoleRequest) GetProjectReference() *IdentityReference { @@ -1006,7 +685,7 @@ type ProjectServiceUpdateMemberRoleResponse struct { func (x *ProjectServiceUpdateMemberRoleResponse) Reset() { *x = ProjectServiceUpdateMemberRoleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[15] + mi := &file_controlplane_v1_project_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1019,7 +698,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) String() string { func (*ProjectServiceUpdateMemberRoleResponse) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[15] + mi := &file_controlplane_v1_project_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1032,7 +711,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use ProjectServiceUpdateMemberRoleResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{15} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} } type ProjectServiceListPendingInvitationsRequest struct { @@ -1049,7 +728,7 @@ type ProjectServiceListPendingInvitationsRequest struct { func (x *ProjectServiceListPendingInvitationsRequest) Reset() { *x = ProjectServiceListPendingInvitationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[16] + mi := &file_controlplane_v1_project_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1062,7 +741,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) String() string { func (*ProjectServiceListPendingInvitationsRequest) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[16] + mi := &file_controlplane_v1_project_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1075,7 +754,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflec // Deprecated: Use ProjectServiceListPendingInvitationsRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{16} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} } func (x *ProjectServiceListPendingInvitationsRequest) GetProjectReference() *IdentityReference { @@ -1107,7 +786,7 @@ type ProjectServiceListPendingInvitationsResponse struct { func (x *ProjectServiceListPendingInvitationsResponse) Reset() { *x = ProjectServiceListPendingInvitationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[17] + mi := &file_controlplane_v1_project_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1120,7 +799,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) String() string { func (*ProjectServiceListPendingInvitationsResponse) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[17] + mi := &file_controlplane_v1_project_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1133,7 +812,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protorefle // Deprecated: Use ProjectServiceListPendingInvitationsResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{17} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} } func (x *ProjectServiceListPendingInvitationsResponse) GetInvitations() []*PendingProjectInvitation { @@ -1169,7 +848,7 @@ type PendingProjectInvitation struct { func (x *PendingProjectInvitation) Reset() { *x = PendingProjectInvitation{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[18] + mi := &file_controlplane_v1_project_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1182,7 +861,7 @@ func (x *PendingProjectInvitation) String() string { func (*PendingProjectInvitation) ProtoMessage() {} func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[18] + mi := &file_controlplane_v1_project_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1195,7 +874,7 @@ func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { // Deprecated: Use PendingProjectInvitation.ProtoReflect.Descriptor instead. func (*PendingProjectInvitation) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{18} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{12} } func (x *PendingProjectInvitation) GetUserEmail() string { @@ -1226,61 +905,6 @@ func (x *PendingProjectInvitation) GetInvitationId() string { return "" } -type ProjectServiceAPITokenCreateResponse_APITokenFull struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Item *APITokenItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` - Jwt string `protobuf:"bytes,2,opt,name=jwt,proto3" json:"jwt,omitempty"` -} - -func (x *ProjectServiceAPITokenCreateResponse_APITokenFull) Reset() { - *x = ProjectServiceAPITokenCreateResponse_APITokenFull{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectServiceAPITokenCreateResponse_APITokenFull) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectServiceAPITokenCreateResponse_APITokenFull) ProtoMessage() {} - -func (x *ProjectServiceAPITokenCreateResponse_APITokenFull) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectServiceAPITokenCreateResponse_APITokenFull.ProtoReflect.Descriptor instead. -func (*ProjectServiceAPITokenCreateResponse_APITokenFull) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{1, 0} -} - -func (x *ProjectServiceAPITokenCreateResponse_APITokenFull) GetItem() *APITokenItem { - if x != nil { - return x.Item - } - return nil -} - -func (x *ProjectServiceAPITokenCreateResponse_APITokenFull) GetJwt() string { - if x != nil { - return x.Jwt - } - return "" -} - var File_controlplane_v1_project_proto protoreflect.FileDescriptor var file_controlplane_v1_project_proto_rawDesc = []byte{ @@ -1297,298 +921,215 @@ var file_controlplane_v1_project_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x01, 0x0a, - 0x23, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x2a, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x88, 0x01, 0x01, 0x12, 0x3d, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, - 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x49, 0x6e, - 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, - 0x69, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x24, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x06, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x46, 0x75, 0x6c, 0x6c, 0x52, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x53, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x46, 0x75, 0x6c, 0x6c, 0x12, 0x31, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x9b, 0x01, 0x0a, - 0x23, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc5, 0x01, 0x0a, + 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x26, 0x0a, 0x24, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x22, 0x5b, 0x0a, 0x22, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x35, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xc5, 0x01, 0x0a, 0x20, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, - 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xa8, 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa5, 0x02, 0x0a, 0x0d, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x05, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, - 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, + 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa8, 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xa5, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, + 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, - 0x42, 0x0e, 0xba, 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, - 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x21, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, - 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, - 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xad, - 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, - 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, - 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x09, 0x0a, 0x07, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, + 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x0e, 0xba, 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, + 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, + 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, + 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, + 0x22, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, + 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, + 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xa7, - 0x02, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, - 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x45, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x07, 0x6e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, + 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, + 0x26, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, + 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xec, 0x01, 0x0a, 0x18, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x26, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, + 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, + 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, + 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, + 0x62, 0x79, 0x2a, 0x77, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, + 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, + 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, + 0x4f, 0x4c, 0x45, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, + 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, + 0x4c, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x32, 0x8f, 0x05, 0x0a, 0x0e, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xec, - 0x01, 0x0a, 0x18, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0a, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, - 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x2a, 0x77, 0x0a, - 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, - 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, - 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x56, 0x49, - 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x32, 0x86, 0x08, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x41, 0x50, 0x49, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x34, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x12, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x74, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, + 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, + 0x6c, 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x83, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, + 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, + 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, + 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -1604,90 +1145,69 @@ func file_controlplane_v1_project_proto_rawDescGZIP() []byte { } var file_controlplane_v1_project_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_controlplane_v1_project_proto_goTypes = []interface{}{ - (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole - (*ProjectServiceAPITokenCreateRequest)(nil), // 1: controlplane.v1.ProjectServiceAPITokenCreateRequest - (*ProjectServiceAPITokenCreateResponse)(nil), // 2: controlplane.v1.ProjectServiceAPITokenCreateResponse - (*ProjectServiceAPITokenRevokeRequest)(nil), // 3: controlplane.v1.ProjectServiceAPITokenRevokeRequest - (*ProjectServiceAPITokenRevokeResponse)(nil), // 4: controlplane.v1.ProjectServiceAPITokenRevokeResponse - (*ProjectServiceAPITokenListRequest)(nil), // 5: controlplane.v1.ProjectServiceAPITokenListRequest - (*ProjectServiceAPITokenListResponse)(nil), // 6: controlplane.v1.ProjectServiceAPITokenListResponse - (*ProjectServiceListMembersRequest)(nil), // 7: controlplane.v1.ProjectServiceListMembersRequest - (*ProjectServiceListMembersResponse)(nil), // 8: controlplane.v1.ProjectServiceListMembersResponse - (*ProjectMember)(nil), // 9: controlplane.v1.ProjectMember - (*ProjectServiceAddMemberRequest)(nil), // 10: controlplane.v1.ProjectServiceAddMemberRequest - (*ProjectServiceAddMemberResponse)(nil), // 11: controlplane.v1.ProjectServiceAddMemberResponse - (*ProjectServiceRemoveMemberRequest)(nil), // 12: controlplane.v1.ProjectServiceRemoveMemberRequest - (*ProjectServiceRemoveMemberResponse)(nil), // 13: controlplane.v1.ProjectServiceRemoveMemberResponse - (*ProjectMembershipReference)(nil), // 14: controlplane.v1.ProjectMembershipReference - (*ProjectServiceUpdateMemberRoleRequest)(nil), // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest - (*ProjectServiceUpdateMemberRoleResponse)(nil), // 16: controlplane.v1.ProjectServiceUpdateMemberRoleResponse - (*ProjectServiceListPendingInvitationsRequest)(nil), // 17: controlplane.v1.ProjectServiceListPendingInvitationsRequest - (*ProjectServiceListPendingInvitationsResponse)(nil), // 18: controlplane.v1.ProjectServiceListPendingInvitationsResponse - (*PendingProjectInvitation)(nil), // 19: controlplane.v1.PendingProjectInvitation - (*ProjectServiceAPITokenCreateResponse_APITokenFull)(nil), // 20: controlplane.v1.ProjectServiceAPITokenCreateResponse.APITokenFull - (*durationpb.Duration)(nil), // 21: google.protobuf.Duration - (*IdentityReference)(nil), // 22: controlplane.v1.IdentityReference - (*APITokenItem)(nil), // 23: controlplane.v1.APITokenItem - (*OffsetPaginationRequest)(nil), // 24: controlplane.v1.OffsetPaginationRequest - (*OffsetPaginationResponse)(nil), // 25: controlplane.v1.OffsetPaginationResponse - (*User)(nil), // 26: controlplane.v1.User - (*Group)(nil), // 27: controlplane.v1.Group - (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole + (*ProjectServiceListMembersRequest)(nil), // 1: controlplane.v1.ProjectServiceListMembersRequest + (*ProjectServiceListMembersResponse)(nil), // 2: controlplane.v1.ProjectServiceListMembersResponse + (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember + (*ProjectServiceAddMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceAddMemberRequest + (*ProjectServiceAddMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceAddMemberResponse + (*ProjectServiceRemoveMemberRequest)(nil), // 6: controlplane.v1.ProjectServiceRemoveMemberRequest + (*ProjectServiceRemoveMemberResponse)(nil), // 7: controlplane.v1.ProjectServiceRemoveMemberResponse + (*ProjectMembershipReference)(nil), // 8: controlplane.v1.ProjectMembershipReference + (*ProjectServiceUpdateMemberRoleRequest)(nil), // 9: controlplane.v1.ProjectServiceUpdateMemberRoleRequest + (*ProjectServiceUpdateMemberRoleResponse)(nil), // 10: controlplane.v1.ProjectServiceUpdateMemberRoleResponse + (*ProjectServiceListPendingInvitationsRequest)(nil), // 11: controlplane.v1.ProjectServiceListPendingInvitationsRequest + (*ProjectServiceListPendingInvitationsResponse)(nil), // 12: controlplane.v1.ProjectServiceListPendingInvitationsResponse + (*PendingProjectInvitation)(nil), // 13: controlplane.v1.PendingProjectInvitation + (*IdentityReference)(nil), // 14: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 15: controlplane.v1.OffsetPaginationRequest + (*OffsetPaginationResponse)(nil), // 16: controlplane.v1.OffsetPaginationResponse + (*User)(nil), // 17: controlplane.v1.User + (*Group)(nil), // 18: controlplane.v1.Group + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp } var file_controlplane_v1_project_proto_depIdxs = []int32{ - 21, // 0: controlplane.v1.ProjectServiceAPITokenCreateRequest.expires_in:type_name -> google.protobuf.Duration - 20, // 1: controlplane.v1.ProjectServiceAPITokenCreateResponse.result:type_name -> controlplane.v1.ProjectServiceAPITokenCreateResponse.APITokenFull - 22, // 2: controlplane.v1.ProjectServiceAPITokenRevokeRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 22, // 3: controlplane.v1.ProjectServiceAPITokenListRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 23, // 4: controlplane.v1.ProjectServiceAPITokenListResponse.result:type_name -> controlplane.v1.APITokenItem - 22, // 5: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 24, // 6: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 9, // 7: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember - 25, // 8: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 26, // 9: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User - 27, // 10: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group - 0, // 11: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole - 28, // 12: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp - 28, // 13: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp - 22, // 14: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 14, // 15: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 16: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole - 22, // 17: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 14, // 18: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 22, // 19: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference - 22, // 20: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 14, // 21: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 22: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole - 22, // 23: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 24, // 24: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 19, // 25: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation - 25, // 26: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 26, // 27: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User - 28, // 28: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp - 23, // 29: controlplane.v1.ProjectServiceAPITokenCreateResponse.APITokenFull.item:type_name -> controlplane.v1.APITokenItem - 1, // 30: controlplane.v1.ProjectService.APITokenCreate:input_type -> controlplane.v1.ProjectServiceAPITokenCreateRequest - 5, // 31: controlplane.v1.ProjectService.APITokenList:input_type -> controlplane.v1.ProjectServiceAPITokenListRequest - 3, // 32: controlplane.v1.ProjectService.APITokenRevoke:input_type -> controlplane.v1.ProjectServiceAPITokenRevokeRequest - 7, // 33: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest - 10, // 34: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest - 12, // 35: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest - 15, // 36: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest - 17, // 37: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest - 2, // 38: controlplane.v1.ProjectService.APITokenCreate:output_type -> controlplane.v1.ProjectServiceAPITokenCreateResponse - 6, // 39: controlplane.v1.ProjectService.APITokenList:output_type -> controlplane.v1.ProjectServiceAPITokenListResponse - 4, // 40: controlplane.v1.ProjectService.APITokenRevoke:output_type -> controlplane.v1.ProjectServiceAPITokenRevokeResponse - 8, // 41: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse - 11, // 42: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse - 13, // 43: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse - 16, // 44: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse - 18, // 45: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse - 38, // [38:46] is the sub-list for method output_type - 30, // [30:38] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 14, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 15, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 3, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember + 16, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 17, // 4: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User + 18, // 5: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group + 0, // 6: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole + 19, // 7: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp + 19, // 8: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp + 14, // 9: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 10: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 0, // 11: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole + 14, // 12: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 13: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 14, // 14: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference + 14, // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 16: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 0, // 17: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole + 14, // 18: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 15, // 19: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 13, // 20: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation + 16, // 21: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 17, // 22: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User + 19, // 23: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp + 1, // 24: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest + 4, // 25: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest + 6, // 26: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest + 9, // 27: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest + 11, // 28: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest + 2, // 29: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse + 5, // 30: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse + 7, // 31: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse + 10, // 32: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse + 12, // 33: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse + 29, // [29:34] is the sub-list for method output_type + 24, // [24:29] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_controlplane_v1_project_proto_init() } @@ -1701,78 +1221,6 @@ func file_controlplane_v1_project_proto_init() { file_controlplane_v1_shared_message_proto_init() if !protoimpl.UnsafeEnabled { file_controlplane_v1_project_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenCreateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenCreateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenRevokeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenRevokeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenListRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenListResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListMembersRequest); i { case 0: return &v.state @@ -1784,7 +1232,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListMembersResponse); i { case 0: return &v.state @@ -1796,7 +1244,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectMember); i { case 0: return &v.state @@ -1808,7 +1256,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceAddMemberRequest); i { case 0: return &v.state @@ -1820,7 +1268,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceAddMemberResponse); i { case 0: return &v.state @@ -1832,7 +1280,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceRemoveMemberRequest); i { case 0: return &v.state @@ -1844,7 +1292,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceRemoveMemberResponse); i { case 0: return &v.state @@ -1856,7 +1304,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectMembershipReference); i { case 0: return &v.state @@ -1868,7 +1316,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceUpdateMemberRoleRequest); i { case 0: return &v.state @@ -1880,7 +1328,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceUpdateMemberRoleResponse); i { case 0: return &v.state @@ -1892,7 +1340,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListPendingInvitationsRequest); i { case 0: return &v.state @@ -1904,7 +1352,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListPendingInvitationsResponse); i { case 0: return &v.state @@ -1916,7 +1364,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PendingProjectInvitation); i { case 0: return &v.state @@ -1928,36 +1376,23 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAPITokenCreateResponse_APITokenFull); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } - file_controlplane_v1_project_proto_msgTypes[0].OneofWrappers = []interface{}{} - file_controlplane_v1_project_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_controlplane_v1_project_proto_msgTypes[2].OneofWrappers = []interface{}{ (*ProjectMember_User)(nil), (*ProjectMember_Group)(nil), } - file_controlplane_v1_project_proto_msgTypes[13].OneofWrappers = []interface{}{ + file_controlplane_v1_project_proto_msgTypes[7].OneofWrappers = []interface{}{ (*ProjectMembershipReference_UserEmail)(nil), (*ProjectMembershipReference_GroupReference)(nil), } - file_controlplane_v1_project_proto_msgTypes[18].OneofWrappers = []interface{}{} + file_controlplane_v1_project_proto_msgTypes[12].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_project_proto_rawDesc, NumEnums: 1, - NumMessages: 20, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/app/controlplane/api/controlplane/v1/project.proto b/app/controlplane/api/controlplane/v1/project.proto index 2be530715..b4248d2d9 100644 --- a/app/controlplane/api/controlplane/v1/project.proto +++ b/app/controlplane/api/controlplane/v1/project.proto @@ -22,16 +22,11 @@ import "controlplane/v1/group.proto"; import "controlplane/v1/pagination.proto"; import "controlplane/v1/response_messages.proto"; import "controlplane/v1/shared_message.proto"; -import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; service ProjectService { - // Project level API tokens - rpc APITokenCreate(ProjectServiceAPITokenCreateRequest) returns (ProjectServiceAPITokenCreateResponse); - rpc APITokenList(ProjectServiceAPITokenListRequest) returns (ProjectServiceAPITokenListResponse); - rpc APITokenRevoke(ProjectServiceAPITokenRevokeRequest) returns (ProjectServiceAPITokenRevokeResponse); // Project membership management rpc ListMembers(ProjectServiceListMembersRequest) returns (ProjectServiceListMembersResponse); rpc AddMember(ProjectServiceAddMemberRequest) returns (ProjectServiceAddMemberResponse); @@ -40,45 +35,6 @@ service ProjectService { rpc ListPendingInvitations(ProjectServiceListPendingInvitationsRequest) returns (ProjectServiceListPendingInvitationsResponse) {} } -message ProjectServiceAPITokenCreateRequest { - string name = 1 [(buf.validate.field).string.min_len = 1]; - string project_name = 2 [(buf.validate.field).string.min_len = 1]; - optional string description = 3; - optional google.protobuf.Duration expires_in = 4; -} - -message ProjectServiceAPITokenCreateResponse { - APITokenFull result = 1; - - message APITokenFull { - APITokenItem item = 1; - string jwt = 2; - } -} - -// ProjectServiceAPITokenRevokeRequest contains the information needed to revoke an API token for a project -message ProjectServiceAPITokenRevokeRequest { - // The name of the API token to revoke - string name = 1 [(buf.validate.field).string.min_len = 1]; - // IdentityReference is used to specify the project by either its ID or name - IdentityReference project_reference = 2 [(buf.validate.field).required = true]; -} - -// ProjectServiceAPITokenRevokeResponse is returned upon successful revocation of an API token -message ProjectServiceAPITokenRevokeResponse {} - -// ProjectServiceAPITokenListRequest contains the information needed to list API tokens for a project -message ProjectServiceAPITokenListRequest { - // IdentityReference is used to specify the project by either its ID or name - IdentityReference project_reference = 1 [(buf.validate.field).required = true]; - // Flag to include revoked tokens in the list - bool include_revoked = 2; -} - -message ProjectServiceAPITokenListResponse { - repeated APITokenItem result = 1; -} - // ProjectServiceListMembersRequest contains the information needed to list members of a project message ProjectServiceListMembersRequest { // IdentityReference is used to specify the project by either its ID or name diff --git a/app/controlplane/api/controlplane/v1/project_grpc.pb.go b/app/controlplane/api/controlplane/v1/project_grpc.pb.go index 5849aff8b..06f0ecee5 100644 --- a/app/controlplane/api/controlplane/v1/project_grpc.pb.go +++ b/app/controlplane/api/controlplane/v1/project_grpc.pb.go @@ -34,9 +34,6 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - ProjectService_APITokenCreate_FullMethodName = "/controlplane.v1.ProjectService/APITokenCreate" - ProjectService_APITokenList_FullMethodName = "/controlplane.v1.ProjectService/APITokenList" - ProjectService_APITokenRevoke_FullMethodName = "/controlplane.v1.ProjectService/APITokenRevoke" ProjectService_ListMembers_FullMethodName = "/controlplane.v1.ProjectService/ListMembers" ProjectService_AddMember_FullMethodName = "/controlplane.v1.ProjectService/AddMember" ProjectService_RemoveMember_FullMethodName = "/controlplane.v1.ProjectService/RemoveMember" @@ -48,10 +45,6 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ProjectServiceClient interface { - // Project level API tokens - APITokenCreate(ctx context.Context, in *ProjectServiceAPITokenCreateRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenCreateResponse, error) - APITokenList(ctx context.Context, in *ProjectServiceAPITokenListRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenListResponse, error) - APITokenRevoke(ctx context.Context, in *ProjectServiceAPITokenRevokeRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenRevokeResponse, error) // Project membership management ListMembers(ctx context.Context, in *ProjectServiceListMembersRequest, opts ...grpc.CallOption) (*ProjectServiceListMembersResponse, error) AddMember(ctx context.Context, in *ProjectServiceAddMemberRequest, opts ...grpc.CallOption) (*ProjectServiceAddMemberResponse, error) @@ -68,33 +61,6 @@ func NewProjectServiceClient(cc grpc.ClientConnInterface) ProjectServiceClient { return &projectServiceClient{cc} } -func (c *projectServiceClient) APITokenCreate(ctx context.Context, in *ProjectServiceAPITokenCreateRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenCreateResponse, error) { - out := new(ProjectServiceAPITokenCreateResponse) - err := c.cc.Invoke(ctx, ProjectService_APITokenCreate_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *projectServiceClient) APITokenList(ctx context.Context, in *ProjectServiceAPITokenListRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenListResponse, error) { - out := new(ProjectServiceAPITokenListResponse) - err := c.cc.Invoke(ctx, ProjectService_APITokenList_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *projectServiceClient) APITokenRevoke(ctx context.Context, in *ProjectServiceAPITokenRevokeRequest, opts ...grpc.CallOption) (*ProjectServiceAPITokenRevokeResponse, error) { - out := new(ProjectServiceAPITokenRevokeResponse) - err := c.cc.Invoke(ctx, ProjectService_APITokenRevoke_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *projectServiceClient) ListMembers(ctx context.Context, in *ProjectServiceListMembersRequest, opts ...grpc.CallOption) (*ProjectServiceListMembersResponse, error) { out := new(ProjectServiceListMembersResponse) err := c.cc.Invoke(ctx, ProjectService_ListMembers_FullMethodName, in, out, opts...) @@ -144,10 +110,6 @@ func (c *projectServiceClient) ListPendingInvitations(ctx context.Context, in *P // All implementations must embed UnimplementedProjectServiceServer // for forward compatibility type ProjectServiceServer interface { - // Project level API tokens - APITokenCreate(context.Context, *ProjectServiceAPITokenCreateRequest) (*ProjectServiceAPITokenCreateResponse, error) - APITokenList(context.Context, *ProjectServiceAPITokenListRequest) (*ProjectServiceAPITokenListResponse, error) - APITokenRevoke(context.Context, *ProjectServiceAPITokenRevokeRequest) (*ProjectServiceAPITokenRevokeResponse, error) // Project membership management ListMembers(context.Context, *ProjectServiceListMembersRequest) (*ProjectServiceListMembersResponse, error) AddMember(context.Context, *ProjectServiceAddMemberRequest) (*ProjectServiceAddMemberResponse, error) @@ -161,15 +123,6 @@ type ProjectServiceServer interface { type UnimplementedProjectServiceServer struct { } -func (UnimplementedProjectServiceServer) APITokenCreate(context.Context, *ProjectServiceAPITokenCreateRequest) (*ProjectServiceAPITokenCreateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method APITokenCreate not implemented") -} -func (UnimplementedProjectServiceServer) APITokenList(context.Context, *ProjectServiceAPITokenListRequest) (*ProjectServiceAPITokenListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method APITokenList not implemented") -} -func (UnimplementedProjectServiceServer) APITokenRevoke(context.Context, *ProjectServiceAPITokenRevokeRequest) (*ProjectServiceAPITokenRevokeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method APITokenRevoke not implemented") -} func (UnimplementedProjectServiceServer) ListMembers(context.Context, *ProjectServiceListMembersRequest) (*ProjectServiceListMembersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListMembers not implemented") } @@ -198,60 +151,6 @@ func RegisterProjectServiceServer(s grpc.ServiceRegistrar, srv ProjectServiceSer s.RegisterService(&ProjectService_ServiceDesc, srv) } -func _ProjectService_APITokenCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ProjectServiceAPITokenCreateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProjectServiceServer).APITokenCreate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProjectService_APITokenCreate_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProjectServiceServer).APITokenCreate(ctx, req.(*ProjectServiceAPITokenCreateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProjectService_APITokenList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ProjectServiceAPITokenListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProjectServiceServer).APITokenList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProjectService_APITokenList_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProjectServiceServer).APITokenList(ctx, req.(*ProjectServiceAPITokenListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ProjectService_APITokenRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ProjectServiceAPITokenRevokeRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProjectServiceServer).APITokenRevoke(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: ProjectService_APITokenRevoke_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProjectServiceServer).APITokenRevoke(ctx, req.(*ProjectServiceAPITokenRevokeRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _ProjectService_ListMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ProjectServiceListMembersRequest) if err := dec(in); err != nil { @@ -349,18 +248,6 @@ var ProjectService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "controlplane.v1.ProjectService", HandlerType: (*ProjectServiceServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "APITokenCreate", - Handler: _ProjectService_APITokenCreate_Handler, - }, - { - MethodName: "APITokenList", - Handler: _ProjectService_APITokenList_Handler, - }, - { - MethodName: "APITokenRevoke", - Handler: _ProjectService_APITokenRevoke_Handler, - }, { MethodName: "ListMembers", Handler: _ProjectService_ListMembers_Handler, diff --git a/app/controlplane/api/controlplane/v1/response_messages.pb.go b/app/controlplane/api/controlplane/v1/response_messages.pb.go index e4349b10a..7fb519a63 100644 --- a/app/controlplane/api/controlplane/v1/response_messages.pb.go +++ b/app/controlplane/api/controlplane/v1/response_messages.pb.go @@ -2034,17 +2034,17 @@ type APITokenItem struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - OrganizationId string `protobuf:"bytes,3,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` - OrganizationName string `protobuf:"bytes,8,opt,name=organization_name,json=organizationName,proto3" json:"organization_name,omitempty"` - ProjectId string `protobuf:"bytes,9,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` - ProjectName string `protobuf:"bytes,10,opt,name=project_name,json=projectName,proto3" json:"project_name,omitempty"` - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - RevokedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=revoked_at,json=revokedAt,proto3" json:"revoked_at,omitempty"` - ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` - LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=last_used_at,json=lastUsedAt,proto3" json:"last_used_at,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + OrganizationId string `protobuf:"bytes,3,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` + OrganizationName string `protobuf:"bytes,8,opt,name=organization_name,json=organizationName,proto3" json:"organization_name,omitempty"` + // wether the token is scoped to an entity in the organization + ScopedEntity *ScopedEntity `protobuf:"bytes,10,opt,name=scoped_entity,json=scopedEntity,proto3" json:"scoped_entity,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + RevokedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=revoked_at,json=revokedAt,proto3" json:"revoked_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + LastUsedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=last_used_at,json=lastUsedAt,proto3" json:"last_used_at,omitempty"` } func (x *APITokenItem) Reset() { @@ -2114,18 +2114,11 @@ func (x *APITokenItem) GetOrganizationName() string { return "" } -func (x *APITokenItem) GetProjectId() string { +func (x *APITokenItem) GetScopedEntity() *ScopedEntity { if x != nil { - return x.ProjectId - } - return "" -} - -func (x *APITokenItem) GetProjectName() string { - if x != nil { - return x.ProjectName + return x.ScopedEntity } - return "" + return nil } func (x *APITokenItem) GetCreatedAt() *timestamppb.Timestamp { @@ -2934,7 +2927,7 @@ var file_controlplane_v1_response_messages_proto_rawDesc = []byte{ 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x22, 0xdb, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x22, 0xdd, 0x03, 0x0a, 0x0c, 0x41, 0x50, 0x49, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, @@ -2945,83 +2938,83 @@ var file_controlplane_v1_response_messages_proto_rawDesc = []byte{ 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x72, 0x67, 0x61, 0x6e, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, - 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x3c, - 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x2a, 0xa6, 0x01, 0x0a, - 0x09, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, - 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, - 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, - 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, - 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x18, 0x0a, 0x14, 0x52, - 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, - 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xaf, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x68, 0x69, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x4d, 0x42, - 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, - 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, - 0x5f, 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x73, + 0x63, 0x6f, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x0c, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, + 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, + 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, + 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, + 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x73, 0x65, 0x64, 0x41, 0x74, 0x2a, 0xa6, + 0x01, 0x0a, 0x09, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, + 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x55, 0x4e, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, + 0x45, 0x44, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x18, 0x0a, + 0x14, 0x52, 0x55, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, + 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x2a, 0xaf, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, + 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, + 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, + 0x52, 0x47, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x4d, + 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, + 0x52, 0x47, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, + 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, + 0x47, 0x5f, 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, - 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x45, 0x4d, 0x42, - 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, - 0x4f, 0x57, 0x4e, 0x45, 0x52, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x45, 0x4d, 0x42, 0x45, - 0x52, 0x53, 0x48, 0x49, 0x50, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x4d, - 0x45, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x04, 0x2a, 0x60, 0x0a, 0x0e, 0x41, 0x6c, 0x6c, 0x6f, 0x77, - 0x4c, 0x69, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x4c, 0x4c, - 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x1c, 0x41, + 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x04, 0x2a, 0x60, 0x0a, 0x0e, 0x41, 0x6c, 0x6c, + 0x6f, 0x77, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x1c, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x1a, 0x04, 0xa8, - 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x46, 0x65, 0x64, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x41, 0x75, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x24, 0x0a, 0x20, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x55, 0x54, - 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x21, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, - 0x45, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, - 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, - 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x84, 0x01, 0x0a, 0x19, 0x55, 0x73, 0x65, - 0x72, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x6f, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, - 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x29, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x57, - 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, - 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x32, 0x0a, 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x57, 0x49, - 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, 0x49, 0x50, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4f, 0x52, - 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, - 0x80, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x4f, 0x66, 0x4f, 0x72, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2c, 0x0a, 0x28, 0x55, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, + 0x1c, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x1a, + 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x41, 0x75, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x24, 0x0a, 0x20, 0x46, 0x45, 0x44, 0x45, 0x52, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, + 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2b, 0x0a, 0x21, 0x46, 0x45, 0x44, 0x45, 0x52, + 0x41, 0x54, 0x45, 0x44, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x04, + 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x2a, 0x84, 0x01, 0x0a, 0x19, 0x55, + 0x73, 0x65, 0x72, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x6f, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x68, 0x69, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x29, 0x55, 0x53, 0x45, 0x52, + 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, + 0x48, 0x49, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x32, 0x0a, 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, + 0x57, 0x49, 0x54, 0x48, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x48, + 0x49, 0x50, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x5f, + 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, + 0x03, 0x2a, 0x80, 0x01, 0x0a, 0x17, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x4f, 0x66, 0x4f, 0x72, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2c, 0x0a, + 0x28, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, + 0x5f, 0x4f, 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x31, 0x0a, 0x27, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x4f, - 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x31, 0x0a, 0x27, 0x55, 0x53, 0x45, - 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x4f, 0x46, 0x5f, - 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, - 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, 0xa0, 0x45, - 0xf4, 0x03, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x46, 0x5f, 0x4f, 0x52, 0x47, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x49, 0x4e, 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45, 0x93, 0x03, 0x1a, 0x04, + 0xa0, 0x45, 0xf4, 0x03, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, + 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3123,18 +3116,19 @@ var file_controlplane_v1_response_messages_proto_depIdxs = []int32{ 37, // 39: controlplane.v1.CASBackendItem.validated_at:type_name -> google.protobuf.Timestamp 8, // 40: controlplane.v1.CASBackendItem.validation_status:type_name -> controlplane.v1.CASBackendItem.ValidationStatus 36, // 41: controlplane.v1.CASBackendItem.limits:type_name -> controlplane.v1.CASBackendItem.Limits - 37, // 42: controlplane.v1.APITokenItem.created_at:type_name -> google.protobuf.Timestamp - 37, // 43: controlplane.v1.APITokenItem.revoked_at:type_name -> google.protobuf.Timestamp - 37, // 44: controlplane.v1.APITokenItem.expires_at:type_name -> google.protobuf.Timestamp - 37, // 45: controlplane.v1.APITokenItem.last_used_at:type_name -> google.protobuf.Timestamp - 13, // 46: controlplane.v1.AttestationItem.PolicyEvaluationsEntry.value:type_name -> controlplane.v1.PolicyEvaluations - 31, // 47: controlplane.v1.AttestationItem.Material.annotations:type_name -> controlplane.v1.AttestationItem.Material.AnnotationsEntry - 6, // 48: controlplane.v1.WorkflowContractVersionItem.RawBody.format:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody.Format - 49, // [49:49] is the sub-list for method output_type - 49, // [49:49] is the sub-list for method input_type - 49, // [49:49] is the sub-list for extension type_name - 49, // [49:49] is the sub-list for extension extendee - 0, // [0:49] is the sub-list for field type_name + 18, // 42: controlplane.v1.APITokenItem.scoped_entity:type_name -> controlplane.v1.ScopedEntity + 37, // 43: controlplane.v1.APITokenItem.created_at:type_name -> google.protobuf.Timestamp + 37, // 44: controlplane.v1.APITokenItem.revoked_at:type_name -> google.protobuf.Timestamp + 37, // 45: controlplane.v1.APITokenItem.expires_at:type_name -> google.protobuf.Timestamp + 37, // 46: controlplane.v1.APITokenItem.last_used_at:type_name -> google.protobuf.Timestamp + 13, // 47: controlplane.v1.AttestationItem.PolicyEvaluationsEntry.value:type_name -> controlplane.v1.PolicyEvaluations + 31, // 48: controlplane.v1.AttestationItem.Material.annotations:type_name -> controlplane.v1.AttestationItem.Material.AnnotationsEntry + 6, // 49: controlplane.v1.WorkflowContractVersionItem.RawBody.format:type_name -> controlplane.v1.WorkflowContractVersionItem.RawBody.Format + 50, // [50:50] is the sub-list for method output_type + 50, // [50:50] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name } func init() { file_controlplane_v1_response_messages_proto_init() } diff --git a/app/controlplane/api/controlplane/v1/response_messages.proto b/app/controlplane/api/controlplane/v1/response_messages.proto index 80cc8f1d7..a6cdba957 100644 --- a/app/controlplane/api/controlplane/v1/response_messages.proto +++ b/app/controlplane/api/controlplane/v1/response_messages.proto @@ -330,8 +330,8 @@ message APITokenItem { string description = 2; string organization_id = 3; string organization_name = 8; - string project_id = 9; - string project_name = 10; + // wether the token is scoped to an entity in the organization + ScopedEntity scoped_entity = 10; google.protobuf.Timestamp created_at = 4; google.protobuf.Timestamp revoked_at = 5; google.protobuf.Timestamp expires_at = 6; diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/api_token.ts b/app/controlplane/api/gen/frontend/controlplane/v1/api_token.ts index 6fd14efee..0fdbca493 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/api_token.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/api_token.ts @@ -4,12 +4,17 @@ import { BrowserHeaders } from "browser-headers"; import _m0 from "protobufjs/minimal"; import { Duration } from "../../google/protobuf/duration"; import { APITokenItem } from "./response_messages"; +import { IdentityReference } from "./shared_message"; export const protobufPackage = "controlplane.v1"; export interface APITokenServiceCreateRequest { name: string; - description?: string | undefined; + description?: + | string + | undefined; + /** You might need to specify a project reference if you want/need to create a token scoped to a project */ + projectReference?: IdentityReference; expiresIn?: Duration | undefined; } @@ -23,7 +28,7 @@ export interface APITokenServiceCreateResponse_APITokenFull { } export interface APITokenServiceRevokeRequest { - name: string; + id: string; } export interface APITokenServiceRevokeResponse { @@ -31,6 +36,49 @@ export interface APITokenServiceRevokeResponse { export interface APITokenServiceListRequest { includeRevoked: boolean; + /** optional project reference to filter by */ + project?: IdentityReference; + /** filter by the scope of the token */ + scope: APITokenServiceListRequest_Scope; +} + +export enum APITokenServiceListRequest_Scope { + SCOPE_UNSPECIFIED = 0, + SCOPE_PROJECT = 1, + SCOPE_GLOBAL = 2, + UNRECOGNIZED = -1, +} + +export function aPITokenServiceListRequest_ScopeFromJSON(object: any): APITokenServiceListRequest_Scope { + switch (object) { + case 0: + case "SCOPE_UNSPECIFIED": + return APITokenServiceListRequest_Scope.SCOPE_UNSPECIFIED; + case 1: + case "SCOPE_PROJECT": + return APITokenServiceListRequest_Scope.SCOPE_PROJECT; + case 2: + case "SCOPE_GLOBAL": + return APITokenServiceListRequest_Scope.SCOPE_GLOBAL; + case -1: + case "UNRECOGNIZED": + default: + return APITokenServiceListRequest_Scope.UNRECOGNIZED; + } +} + +export function aPITokenServiceListRequest_ScopeToJSON(object: APITokenServiceListRequest_Scope): string { + switch (object) { + case APITokenServiceListRequest_Scope.SCOPE_UNSPECIFIED: + return "SCOPE_UNSPECIFIED"; + case APITokenServiceListRequest_Scope.SCOPE_PROJECT: + return "SCOPE_PROJECT"; + case APITokenServiceListRequest_Scope.SCOPE_GLOBAL: + return "SCOPE_GLOBAL"; + case APITokenServiceListRequest_Scope.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } } export interface APITokenServiceListResponse { @@ -38,7 +86,7 @@ export interface APITokenServiceListResponse { } function createBaseAPITokenServiceCreateRequest(): APITokenServiceCreateRequest { - return { name: "", description: undefined, expiresIn: undefined }; + return { name: "", description: undefined, projectReference: undefined, expiresIn: undefined }; } export const APITokenServiceCreateRequest = { @@ -49,6 +97,9 @@ export const APITokenServiceCreateRequest = { if (message.description !== undefined) { writer.uint32(10).string(message.description); } + if (message.projectReference !== undefined) { + IdentityReference.encode(message.projectReference, writer.uint32(34).fork()).ldelim(); + } if (message.expiresIn !== undefined) { Duration.encode(message.expiresIn, writer.uint32(18).fork()).ldelim(); } @@ -76,6 +127,13 @@ export const APITokenServiceCreateRequest = { message.description = reader.string(); continue; + case 4: + if (tag !== 34) { + break; + } + + message.projectReference = IdentityReference.decode(reader, reader.uint32()); + continue; case 2: if (tag !== 18) { break; @@ -96,6 +154,9 @@ export const APITokenServiceCreateRequest = { return { name: isSet(object.name) ? String(object.name) : "", description: isSet(object.description) ? String(object.description) : undefined, + projectReference: isSet(object.projectReference) + ? IdentityReference.fromJSON(object.projectReference) + : undefined, expiresIn: isSet(object.expiresIn) ? Duration.fromJSON(object.expiresIn) : undefined, }; }, @@ -104,6 +165,10 @@ export const APITokenServiceCreateRequest = { const obj: any = {}; message.name !== undefined && (obj.name = message.name); message.description !== undefined && (obj.description = message.description); + message.projectReference !== undefined && + (obj.projectReference = message.projectReference + ? IdentityReference.toJSON(message.projectReference) + : undefined); message.expiresIn !== undefined && (obj.expiresIn = message.expiresIn ? Duration.toJSON(message.expiresIn) : undefined); return obj; @@ -117,6 +182,9 @@ export const APITokenServiceCreateRequest = { const message = createBaseAPITokenServiceCreateRequest(); message.name = object.name ?? ""; message.description = object.description ?? undefined; + message.projectReference = (object.projectReference !== undefined && object.projectReference !== null) + ? IdentityReference.fromPartial(object.projectReference) + : undefined; message.expiresIn = (object.expiresIn !== undefined && object.expiresIn !== null) ? Duration.fromPartial(object.expiresIn) : undefined; @@ -265,13 +333,13 @@ export const APITokenServiceCreateResponse_APITokenFull = { }; function createBaseAPITokenServiceRevokeRequest(): APITokenServiceRevokeRequest { - return { name: "" }; + return { id: "" }; } export const APITokenServiceRevokeRequest = { encode(message: APITokenServiceRevokeRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); + if (message.id !== "") { + writer.uint32(10).string(message.id); } return writer; }, @@ -288,7 +356,7 @@ export const APITokenServiceRevokeRequest = { break; } - message.name = reader.string(); + message.id = reader.string(); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -300,12 +368,12 @@ export const APITokenServiceRevokeRequest = { }, fromJSON(object: any): APITokenServiceRevokeRequest { - return { name: isSet(object.name) ? String(object.name) : "" }; + return { id: isSet(object.id) ? String(object.id) : "" }; }, toJSON(message: APITokenServiceRevokeRequest): unknown { const obj: any = {}; - message.name !== undefined && (obj.name = message.name); + message.id !== undefined && (obj.id = message.id); return obj; }, @@ -315,7 +383,7 @@ export const APITokenServiceRevokeRequest = { fromPartial, I>>(object: I): APITokenServiceRevokeRequest { const message = createBaseAPITokenServiceRevokeRequest(); - message.name = object.name ?? ""; + message.id = object.id ?? ""; return message; }, }; @@ -365,7 +433,7 @@ export const APITokenServiceRevokeResponse = { }; function createBaseAPITokenServiceListRequest(): APITokenServiceListRequest { - return { includeRevoked: false }; + return { includeRevoked: false, project: undefined, scope: 0 }; } export const APITokenServiceListRequest = { @@ -373,6 +441,12 @@ export const APITokenServiceListRequest = { if (message.includeRevoked === true) { writer.uint32(8).bool(message.includeRevoked); } + if (message.project !== undefined) { + IdentityReference.encode(message.project, writer.uint32(34).fork()).ldelim(); + } + if (message.scope !== 0) { + writer.uint32(16).int32(message.scope); + } return writer; }, @@ -390,6 +464,20 @@ export const APITokenServiceListRequest = { message.includeRevoked = reader.bool(); continue; + case 4: + if (tag !== 34) { + break; + } + + message.project = IdentityReference.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 16) { + break; + } + + message.scope = reader.int32() as any; + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -400,12 +488,19 @@ export const APITokenServiceListRequest = { }, fromJSON(object: any): APITokenServiceListRequest { - return { includeRevoked: isSet(object.includeRevoked) ? Boolean(object.includeRevoked) : false }; + return { + includeRevoked: isSet(object.includeRevoked) ? Boolean(object.includeRevoked) : false, + project: isSet(object.project) ? IdentityReference.fromJSON(object.project) : undefined, + scope: isSet(object.scope) ? aPITokenServiceListRequest_ScopeFromJSON(object.scope) : 0, + }; }, toJSON(message: APITokenServiceListRequest): unknown { const obj: any = {}; message.includeRevoked !== undefined && (obj.includeRevoked = message.includeRevoked); + message.project !== undefined && + (obj.project = message.project ? IdentityReference.toJSON(message.project) : undefined); + message.scope !== undefined && (obj.scope = aPITokenServiceListRequest_ScopeToJSON(message.scope)); return obj; }, @@ -416,6 +511,10 @@ export const APITokenServiceListRequest = { fromPartial, I>>(object: I): APITokenServiceListRequest { const message = createBaseAPITokenServiceListRequest(); message.includeRevoked = object.includeRevoked ?? false; + message.project = (object.project !== undefined && object.project !== null) + ? IdentityReference.fromPartial(object.project) + : undefined; + message.scope = object.scope ?? 0; return message; }, }; diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts index 7aa351392..2e4341abb 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts @@ -2,11 +2,10 @@ import { grpc } from "@improbable-eng/grpc-web"; import { BrowserHeaders } from "browser-headers"; import _m0 from "protobufjs/minimal"; -import { Duration } from "../../google/protobuf/duration"; import { Timestamp } from "../../google/protobuf/timestamp"; import { Group } from "./group"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; -import { APITokenItem, User } from "./response_messages"; +import { User } from "./response_messages"; import { IdentityReference } from "./shared_message"; export const protobufPackage = "controlplane.v1"; @@ -54,46 +53,6 @@ export function projectMemberRoleToJSON(object: ProjectMemberRole): string { } } -export interface ProjectServiceAPITokenCreateRequest { - name: string; - projectName: string; - description?: string | undefined; - expiresIn?: Duration | undefined; -} - -export interface ProjectServiceAPITokenCreateResponse { - result?: ProjectServiceAPITokenCreateResponse_APITokenFull; -} - -export interface ProjectServiceAPITokenCreateResponse_APITokenFull { - item?: APITokenItem; - jwt: string; -} - -/** ProjectServiceAPITokenRevokeRequest contains the information needed to revoke an API token for a project */ -export interface ProjectServiceAPITokenRevokeRequest { - /** The name of the API token to revoke */ - name: string; - /** IdentityReference is used to specify the project by either its ID or name */ - projectReference?: IdentityReference; -} - -/** ProjectServiceAPITokenRevokeResponse is returned upon successful revocation of an API token */ -export interface ProjectServiceAPITokenRevokeResponse { -} - -/** ProjectServiceAPITokenListRequest contains the information needed to list API tokens for a project */ -export interface ProjectServiceAPITokenListRequest { - /** IdentityReference is used to specify the project by either its ID or name */ - projectReference?: IdentityReference; - /** Flag to include revoked tokens in the list */ - includeRevoked: boolean; -} - -export interface ProjectServiceAPITokenListResponse { - result: APITokenItem[]; -} - /** ProjectServiceListMembersRequest contains the information needed to list members of a project */ export interface ProjectServiceListMembersRequest { /** IdentityReference is used to specify the project by either its ID or name */ @@ -206,534 +165,6 @@ export interface PendingProjectInvitation { invitationId: string; } -function createBaseProjectServiceAPITokenCreateRequest(): ProjectServiceAPITokenCreateRequest { - return { name: "", projectName: "", description: undefined, expiresIn: undefined }; -} - -export const ProjectServiceAPITokenCreateRequest = { - encode(message: ProjectServiceAPITokenCreateRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.projectName !== "") { - writer.uint32(18).string(message.projectName); - } - if (message.description !== undefined) { - writer.uint32(26).string(message.description); - } - if (message.expiresIn !== undefined) { - Duration.encode(message.expiresIn, writer.uint32(34).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenCreateRequest { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenCreateRequest(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.name = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.projectName = reader.string(); - continue; - case 3: - if (tag !== 26) { - break; - } - - message.description = reader.string(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.expiresIn = Duration.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenCreateRequest { - return { - name: isSet(object.name) ? String(object.name) : "", - projectName: isSet(object.projectName) ? String(object.projectName) : "", - description: isSet(object.description) ? String(object.description) : undefined, - expiresIn: isSet(object.expiresIn) ? Duration.fromJSON(object.expiresIn) : undefined, - }; - }, - - toJSON(message: ProjectServiceAPITokenCreateRequest): unknown { - const obj: any = {}; - message.name !== undefined && (obj.name = message.name); - message.projectName !== undefined && (obj.projectName = message.projectName); - message.description !== undefined && (obj.description = message.description); - message.expiresIn !== undefined && - (obj.expiresIn = message.expiresIn ? Duration.toJSON(message.expiresIn) : undefined); - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenCreateRequest { - return ProjectServiceAPITokenCreateRequest.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenCreateRequest { - const message = createBaseProjectServiceAPITokenCreateRequest(); - message.name = object.name ?? ""; - message.projectName = object.projectName ?? ""; - message.description = object.description ?? undefined; - message.expiresIn = (object.expiresIn !== undefined && object.expiresIn !== null) - ? Duration.fromPartial(object.expiresIn) - : undefined; - return message; - }, -}; - -function createBaseProjectServiceAPITokenCreateResponse(): ProjectServiceAPITokenCreateResponse { - return { result: undefined }; -} - -export const ProjectServiceAPITokenCreateResponse = { - encode(message: ProjectServiceAPITokenCreateResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.result !== undefined) { - ProjectServiceAPITokenCreateResponse_APITokenFull.encode(message.result, writer.uint32(10).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenCreateResponse { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenCreateResponse(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.result = ProjectServiceAPITokenCreateResponse_APITokenFull.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenCreateResponse { - return { - result: isSet(object.result) - ? ProjectServiceAPITokenCreateResponse_APITokenFull.fromJSON(object.result) - : undefined, - }; - }, - - toJSON(message: ProjectServiceAPITokenCreateResponse): unknown { - const obj: any = {}; - message.result !== undefined && (obj.result = message.result - ? ProjectServiceAPITokenCreateResponse_APITokenFull.toJSON(message.result) - : undefined); - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenCreateResponse { - return ProjectServiceAPITokenCreateResponse.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenCreateResponse { - const message = createBaseProjectServiceAPITokenCreateResponse(); - message.result = (object.result !== undefined && object.result !== null) - ? ProjectServiceAPITokenCreateResponse_APITokenFull.fromPartial(object.result) - : undefined; - return message; - }, -}; - -function createBaseProjectServiceAPITokenCreateResponse_APITokenFull(): ProjectServiceAPITokenCreateResponse_APITokenFull { - return { item: undefined, jwt: "" }; -} - -export const ProjectServiceAPITokenCreateResponse_APITokenFull = { - encode( - message: ProjectServiceAPITokenCreateResponse_APITokenFull, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.item !== undefined) { - APITokenItem.encode(message.item, writer.uint32(10).fork()).ldelim(); - } - if (message.jwt !== "") { - writer.uint32(18).string(message.jwt); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenCreateResponse_APITokenFull { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenCreateResponse_APITokenFull(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.item = APITokenItem.decode(reader, reader.uint32()); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.jwt = reader.string(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenCreateResponse_APITokenFull { - return { - item: isSet(object.item) ? APITokenItem.fromJSON(object.item) : undefined, - jwt: isSet(object.jwt) ? String(object.jwt) : "", - }; - }, - - toJSON(message: ProjectServiceAPITokenCreateResponse_APITokenFull): unknown { - const obj: any = {}; - message.item !== undefined && (obj.item = message.item ? APITokenItem.toJSON(message.item) : undefined); - message.jwt !== undefined && (obj.jwt = message.jwt); - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenCreateResponse_APITokenFull { - return ProjectServiceAPITokenCreateResponse_APITokenFull.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenCreateResponse_APITokenFull { - const message = createBaseProjectServiceAPITokenCreateResponse_APITokenFull(); - message.item = (object.item !== undefined && object.item !== null) - ? APITokenItem.fromPartial(object.item) - : undefined; - message.jwt = object.jwt ?? ""; - return message; - }, -}; - -function createBaseProjectServiceAPITokenRevokeRequest(): ProjectServiceAPITokenRevokeRequest { - return { name: "", projectReference: undefined }; -} - -export const ProjectServiceAPITokenRevokeRequest = { - encode(message: ProjectServiceAPITokenRevokeRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.name !== "") { - writer.uint32(10).string(message.name); - } - if (message.projectReference !== undefined) { - IdentityReference.encode(message.projectReference, writer.uint32(18).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenRevokeRequest { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenRevokeRequest(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.name = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.projectReference = IdentityReference.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenRevokeRequest { - return { - name: isSet(object.name) ? String(object.name) : "", - projectReference: isSet(object.projectReference) - ? IdentityReference.fromJSON(object.projectReference) - : undefined, - }; - }, - - toJSON(message: ProjectServiceAPITokenRevokeRequest): unknown { - const obj: any = {}; - message.name !== undefined && (obj.name = message.name); - message.projectReference !== undefined && - (obj.projectReference = message.projectReference - ? IdentityReference.toJSON(message.projectReference) - : undefined); - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenRevokeRequest { - return ProjectServiceAPITokenRevokeRequest.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenRevokeRequest { - const message = createBaseProjectServiceAPITokenRevokeRequest(); - message.name = object.name ?? ""; - message.projectReference = (object.projectReference !== undefined && object.projectReference !== null) - ? IdentityReference.fromPartial(object.projectReference) - : undefined; - return message; - }, -}; - -function createBaseProjectServiceAPITokenRevokeResponse(): ProjectServiceAPITokenRevokeResponse { - return {}; -} - -export const ProjectServiceAPITokenRevokeResponse = { - encode(_: ProjectServiceAPITokenRevokeResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenRevokeResponse { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenRevokeResponse(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(_: any): ProjectServiceAPITokenRevokeResponse { - return {}; - }, - - toJSON(_: ProjectServiceAPITokenRevokeResponse): unknown { - const obj: any = {}; - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenRevokeResponse { - return ProjectServiceAPITokenRevokeResponse.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - _: I, - ): ProjectServiceAPITokenRevokeResponse { - const message = createBaseProjectServiceAPITokenRevokeResponse(); - return message; - }, -}; - -function createBaseProjectServiceAPITokenListRequest(): ProjectServiceAPITokenListRequest { - return { projectReference: undefined, includeRevoked: false }; -} - -export const ProjectServiceAPITokenListRequest = { - encode(message: ProjectServiceAPITokenListRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.projectReference !== undefined) { - IdentityReference.encode(message.projectReference, writer.uint32(10).fork()).ldelim(); - } - if (message.includeRevoked === true) { - writer.uint32(16).bool(message.includeRevoked); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenListRequest { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenListRequest(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.projectReference = IdentityReference.decode(reader, reader.uint32()); - continue; - case 2: - if (tag !== 16) { - break; - } - - message.includeRevoked = reader.bool(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenListRequest { - return { - projectReference: isSet(object.projectReference) - ? IdentityReference.fromJSON(object.projectReference) - : undefined, - includeRevoked: isSet(object.includeRevoked) ? Boolean(object.includeRevoked) : false, - }; - }, - - toJSON(message: ProjectServiceAPITokenListRequest): unknown { - const obj: any = {}; - message.projectReference !== undefined && - (obj.projectReference = message.projectReference - ? IdentityReference.toJSON(message.projectReference) - : undefined); - message.includeRevoked !== undefined && (obj.includeRevoked = message.includeRevoked); - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenListRequest { - return ProjectServiceAPITokenListRequest.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenListRequest { - const message = createBaseProjectServiceAPITokenListRequest(); - message.projectReference = (object.projectReference !== undefined && object.projectReference !== null) - ? IdentityReference.fromPartial(object.projectReference) - : undefined; - message.includeRevoked = object.includeRevoked ?? false; - return message; - }, -}; - -function createBaseProjectServiceAPITokenListResponse(): ProjectServiceAPITokenListResponse { - return { result: [] }; -} - -export const ProjectServiceAPITokenListResponse = { - encode(message: ProjectServiceAPITokenListResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - for (const v of message.result) { - APITokenItem.encode(v!, writer.uint32(10).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectServiceAPITokenListResponse { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectServiceAPITokenListResponse(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.result.push(APITokenItem.decode(reader, reader.uint32())); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectServiceAPITokenListResponse { - return { result: Array.isArray(object?.result) ? object.result.map((e: any) => APITokenItem.fromJSON(e)) : [] }; - }, - - toJSON(message: ProjectServiceAPITokenListResponse): unknown { - const obj: any = {}; - if (message.result) { - obj.result = message.result.map((e) => e ? APITokenItem.toJSON(e) : undefined); - } else { - obj.result = []; - } - return obj; - }, - - create, I>>( - base?: I, - ): ProjectServiceAPITokenListResponse { - return ProjectServiceAPITokenListResponse.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): ProjectServiceAPITokenListResponse { - const message = createBaseProjectServiceAPITokenListResponse(); - message.result = object.result?.map((e) => APITokenItem.fromPartial(e)) || []; - return message; - }, -}; - function createBaseProjectServiceListMembersRequest(): ProjectServiceListMembersRequest { return { projectReference: undefined, pagination: undefined }; } @@ -1782,19 +1213,6 @@ export const PendingProjectInvitation = { }; export interface ProjectService { - /** Project level API tokens */ - APITokenCreate( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise; - APITokenList( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise; - APITokenRevoke( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise; /** Project membership management */ ListMembers( request: DeepPartial, @@ -1823,9 +1241,6 @@ export class ProjectServiceClientImpl implements ProjectService { constructor(rpc: Rpc) { this.rpc = rpc; - this.APITokenCreate = this.APITokenCreate.bind(this); - this.APITokenList = this.APITokenList.bind(this); - this.APITokenRevoke = this.APITokenRevoke.bind(this); this.ListMembers = this.ListMembers.bind(this); this.AddMember = this.AddMember.bind(this); this.RemoveMember = this.RemoveMember.bind(this); @@ -1833,39 +1248,6 @@ export class ProjectServiceClientImpl implements ProjectService { this.ListPendingInvitations = this.ListPendingInvitations.bind(this); } - APITokenCreate( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise { - return this.rpc.unary( - ProjectServiceAPITokenCreateDesc, - ProjectServiceAPITokenCreateRequest.fromPartial(request), - metadata, - ); - } - - APITokenList( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise { - return this.rpc.unary( - ProjectServiceAPITokenListDesc, - ProjectServiceAPITokenListRequest.fromPartial(request), - metadata, - ); - } - - APITokenRevoke( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise { - return this.rpc.unary( - ProjectServiceAPITokenRevokeDesc, - ProjectServiceAPITokenRevokeRequest.fromPartial(request), - metadata, - ); - } - ListMembers( request: DeepPartial, metadata?: grpc.Metadata, @@ -1920,75 +1302,6 @@ export class ProjectServiceClientImpl implements ProjectService { export const ProjectServiceDesc = { serviceName: "controlplane.v1.ProjectService" }; -export const ProjectServiceAPITokenCreateDesc: UnaryMethodDefinitionish = { - methodName: "APITokenCreate", - service: ProjectServiceDesc, - requestStream: false, - responseStream: false, - requestType: { - serializeBinary() { - return ProjectServiceAPITokenCreateRequest.encode(this).finish(); - }, - } as any, - responseType: { - deserializeBinary(data: Uint8Array) { - const value = ProjectServiceAPITokenCreateResponse.decode(data); - return { - ...value, - toObject() { - return value; - }, - }; - }, - } as any, -}; - -export const ProjectServiceAPITokenListDesc: UnaryMethodDefinitionish = { - methodName: "APITokenList", - service: ProjectServiceDesc, - requestStream: false, - responseStream: false, - requestType: { - serializeBinary() { - return ProjectServiceAPITokenListRequest.encode(this).finish(); - }, - } as any, - responseType: { - deserializeBinary(data: Uint8Array) { - const value = ProjectServiceAPITokenListResponse.decode(data); - return { - ...value, - toObject() { - return value; - }, - }; - }, - } as any, -}; - -export const ProjectServiceAPITokenRevokeDesc: UnaryMethodDefinitionish = { - methodName: "APITokenRevoke", - service: ProjectServiceDesc, - requestStream: false, - responseStream: false, - requestType: { - serializeBinary() { - return ProjectServiceAPITokenRevokeRequest.encode(this).finish(); - }, - } as any, - responseType: { - deserializeBinary(data: Uint8Array) { - const value = ProjectServiceAPITokenRevokeResponse.decode(data); - return { - ...value, - toObject() { - return value; - }, - }; - }, - } as any, -}; - export const ProjectServiceListMembersDesc: UnaryMethodDefinitionish = { methodName: "ListMembers", service: ProjectServiceDesc, diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts b/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts index e69eedfe2..5c579c249 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/response_messages.ts @@ -661,8 +661,8 @@ export interface APITokenItem { description: string; organizationId: string; organizationName: string; - projectId: string; - projectName: string; + /** wether the token is scoped to an entity in the organization */ + scopedEntity?: ScopedEntity; createdAt?: Date; revokedAt?: Date; expiresAt?: Date; @@ -3993,8 +3993,7 @@ function createBaseAPITokenItem(): APITokenItem { description: "", organizationId: "", organizationName: "", - projectId: "", - projectName: "", + scopedEntity: undefined, createdAt: undefined, revokedAt: undefined, expiresAt: undefined, @@ -4019,11 +4018,8 @@ export const APITokenItem = { if (message.organizationName !== "") { writer.uint32(66).string(message.organizationName); } - if (message.projectId !== "") { - writer.uint32(74).string(message.projectId); - } - if (message.projectName !== "") { - writer.uint32(82).string(message.projectName); + if (message.scopedEntity !== undefined) { + ScopedEntity.encode(message.scopedEntity, writer.uint32(82).fork()).ldelim(); } if (message.createdAt !== undefined) { Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).ldelim(); @@ -4082,19 +4078,12 @@ export const APITokenItem = { message.organizationName = reader.string(); continue; - case 9: - if (tag !== 74) { - break; - } - - message.projectId = reader.string(); - continue; case 10: if (tag !== 82) { break; } - message.projectName = reader.string(); + message.scopedEntity = ScopedEntity.decode(reader, reader.uint32()); continue; case 4: if (tag !== 34) { @@ -4140,8 +4129,7 @@ export const APITokenItem = { description: isSet(object.description) ? String(object.description) : "", organizationId: isSet(object.organizationId) ? String(object.organizationId) : "", organizationName: isSet(object.organizationName) ? String(object.organizationName) : "", - projectId: isSet(object.projectId) ? String(object.projectId) : "", - projectName: isSet(object.projectName) ? String(object.projectName) : "", + scopedEntity: isSet(object.scopedEntity) ? ScopedEntity.fromJSON(object.scopedEntity) : undefined, createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, revokedAt: isSet(object.revokedAt) ? fromJsonTimestamp(object.revokedAt) : undefined, expiresAt: isSet(object.expiresAt) ? fromJsonTimestamp(object.expiresAt) : undefined, @@ -4156,8 +4144,8 @@ export const APITokenItem = { message.description !== undefined && (obj.description = message.description); message.organizationId !== undefined && (obj.organizationId = message.organizationId); message.organizationName !== undefined && (obj.organizationName = message.organizationName); - message.projectId !== undefined && (obj.projectId = message.projectId); - message.projectName !== undefined && (obj.projectName = message.projectName); + message.scopedEntity !== undefined && + (obj.scopedEntity = message.scopedEntity ? ScopedEntity.toJSON(message.scopedEntity) : undefined); message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); message.revokedAt !== undefined && (obj.revokedAt = message.revokedAt.toISOString()); message.expiresAt !== undefined && (obj.expiresAt = message.expiresAt.toISOString()); @@ -4176,8 +4164,9 @@ export const APITokenItem = { message.description = object.description ?? ""; message.organizationId = object.organizationId ?? ""; message.organizationName = object.organizationName ?? ""; - message.projectId = object.projectId ?? ""; - message.projectName = object.projectName ?? ""; + message.scopedEntity = (object.scopedEntity !== undefined && object.scopedEntity !== null) + ? ScopedEntity.fromPartial(object.scopedEntity) + : undefined; message.createdAt = object.createdAt ?? undefined; message.revokedAt = object.revokedAt ?? undefined; message.expiresAt = object.expiresAt ?? undefined; diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.jsonschema.json index 40641b6e2..c1e730ef0 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.jsonschema.json @@ -18,14 +18,12 @@ "^(organization_name)$": { "type": "string" }, - "^(project_id)$": { - "type": "string" - }, - "^(project_name)$": { - "type": "string" - }, "^(revoked_at)$": { "$ref": "google.protobuf.Timestamp.jsonschema.json" + }, + "^(scoped_entity)$": { + "$ref": "controlplane.v1.ScopedEntity.jsonschema.json", + "description": "wether the token is scoped to an entity in the organization" } }, "properties": { @@ -53,14 +51,12 @@ "organizationName": { "type": "string" }, - "projectId": { - "type": "string" - }, - "projectName": { - "type": "string" - }, "revokedAt": { "$ref": "google.protobuf.Timestamp.jsonschema.json" + }, + "scopedEntity": { + "$ref": "controlplane.v1.ScopedEntity.jsonschema.json", + "description": "wether the token is scoped to an entity in the organization" } }, "title": "API Token Item", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.schema.json index a80f39e1d..78f54ddc0 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenItem.schema.json @@ -18,14 +18,12 @@ "^(organizationName)$": { "type": "string" }, - "^(projectId)$": { - "type": "string" - }, - "^(projectName)$": { - "type": "string" - }, "^(revokedAt)$": { "$ref": "google.protobuf.Timestamp.schema.json" + }, + "^(scopedEntity)$": { + "$ref": "controlplane.v1.ScopedEntity.schema.json", + "description": "wether the token is scoped to an entity in the organization" } }, "properties": { @@ -53,14 +51,12 @@ "organization_name": { "type": "string" }, - "project_id": { - "type": "string" - }, - "project_name": { - "type": "string" - }, "revoked_at": { "$ref": "google.protobuf.Timestamp.schema.json" + }, + "scoped_entity": { + "$ref": "controlplane.v1.ScopedEntity.schema.json", + "description": "wether the token is scoped to an entity in the organization" } }, "title": "API Token Item", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.jsonschema.json index d8f48fce5..fb74fd2fa 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.jsonschema.json @@ -5,6 +5,10 @@ "patternProperties": { "^(expires_in)$": { "$ref": "google.protobuf.Duration.jsonschema.json" + }, + "^(project_reference)$": { + "$ref": "controlplane.v1.IdentityReference.jsonschema.json", + "description": "You might need to specify a project reference if you want/need to create a token scoped to a project" } }, "properties": { @@ -17,6 +21,10 @@ "name": { "minLength": 1, "type": "string" + }, + "projectReference": { + "$ref": "controlplane.v1.IdentityReference.jsonschema.json", + "description": "You might need to specify a project reference if you want/need to create a token scoped to a project" } }, "title": "API Token Service Create Request", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.schema.json index 0fcaba7ca..43ca1809c 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceCreateRequest.schema.json @@ -5,6 +5,10 @@ "patternProperties": { "^(expiresIn)$": { "$ref": "google.protobuf.Duration.schema.json" + }, + "^(projectReference)$": { + "$ref": "controlplane.v1.IdentityReference.schema.json", + "description": "You might need to specify a project reference if you want/need to create a token scoped to a project" } }, "properties": { @@ -17,6 +21,10 @@ "name": { "minLength": 1, "type": "string" + }, + "project_reference": { + "$ref": "controlplane.v1.IdentityReference.schema.json", + "description": "You might need to specify a project reference if you want/need to create a token scoped to a project" } }, "title": "API Token Service Create Request", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.jsonschema.json index 205bc414f..984e5cd4b 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.jsonschema.json @@ -10,6 +10,29 @@ "properties": { "includeRevoked": { "type": "boolean" + }, + "project": { + "$ref": "controlplane.v1.IdentityReference.jsonschema.json", + "description": "optional project reference to filter by" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "SCOPE_UNSPECIFIED", + "SCOPE_PROJECT", + "SCOPE_GLOBAL" + ], + "title": "Scope", + "type": "string" + }, + { + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + } + ], + "description": "filter by the scope of the token" } }, "title": "API Token Service List Request", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.schema.json index 1747f0268..d6bfc4712 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceListRequest.schema.json @@ -10,6 +10,29 @@ "properties": { "include_revoked": { "type": "boolean" + }, + "project": { + "$ref": "controlplane.v1.IdentityReference.schema.json", + "description": "optional project reference to filter by" + }, + "scope": { + "anyOf": [ + { + "enum": [ + "SCOPE_UNSPECIFIED", + "SCOPE_PROJECT", + "SCOPE_GLOBAL" + ], + "title": "Scope", + "type": "string" + }, + { + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + } + ], + "description": "filter by the scope of the token" } }, "title": "API Token Service List Request", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.jsonschema.json index 862e7ead7..21307c1e9 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.jsonschema.json @@ -3,7 +3,8 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { - "name": { + "id": { + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", "type": "string" } }, diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.schema.json index a4451b008..1c91a21f9 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.APITokenServiceRevokeRequest.schema.json @@ -3,7 +3,8 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { - "name": { + "id": { + "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", "type": "string" } }, diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 9f9ff8a1d..c6d007b20 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -231,7 +231,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l signingService := service.NewSigningService(signingUseCase, v5...) prometheusService := service.NewPrometheusService(organizationUseCase, prometheusUseCase, v5...) groupService := service.NewGroupService(groupUseCase, v5...) - projectService := service.NewProjectService(apiTokenUseCase, v5...) + projectService := service.NewProjectService(v5...) federatedAuthentication := bootstrap.FederatedAuthentication validator, err := newProtoValidator() if err != nil { diff --git a/app/controlplane/internal/service/apitoken.go b/app/controlplane/internal/service/apitoken.go index d724dbc58..d7f98ecf4 100644 --- a/app/controlplane/internal/service/apitoken.go +++ b/app/controlplane/internal/service/apitoken.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,7 +20,10 @@ import ( "time" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" + errors "github.com/go-kratos/kratos/v2/errors" + "github.com/google/uuid" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -44,13 +47,29 @@ func (s *APITokenService) Create(ctx context.Context, req *pb.APITokenServiceCre return nil, err } + // Authorization checks + // Force setting a project scope if RBAC is enabled + if rbacEnabled(ctx) && !req.ProjectReference.IsSet() { + return nil, errors.BadRequest("invalid", "project is required") + } + + // if the project is provided we make sure it exists and the user has permission to it + var project *biz.Project + if req.ProjectReference.IsSet() { + // Make sure the provided project exists and the user has permission to create tokens in it + project, err = s.userHasPermissionOnProject(ctx, currentOrg.ID, req.GetProjectReference(), authz.PolicyAPITokenCreate) + if err != nil { + return nil, err + } + } + var expiresIn *time.Duration if req.ExpiresIn != nil { expiresIn = new(time.Duration) *expiresIn = req.ExpiresIn.AsDuration() } - token, err := s.APITokenUseCase.Create(ctx, req.Name, req.Description, expiresIn, currentOrg.ID) + token, err := s.APITokenUseCase.Create(ctx, req.Name, req.Description, expiresIn, currentOrg.ID, biz.APITokenWithProject(project)) if err != nil { return nil, handleUseCaseErr(err, s.log) } @@ -69,8 +88,20 @@ func (s *APITokenService) List(ctx context.Context, req *pb.APITokenServiceListR return nil, err } + // default to visible projects for the user + defaultProjectFilter := s.visibleProjects(ctx) + // or the user has provided a project filter + if req.Project.IsSet() { + project, err := s.userHasPermissionOnProject(ctx, currentOrg.ID, req.GetProject(), authz.PolicyAPITokenList) + if err != nil { + return nil, err + } + + defaultProjectFilter = []uuid.UUID{project.ID} + } + // Only expose system tokens - tokens, err := s.APITokenUseCase.List(ctx, currentOrg.ID, req.IncludeRevoked, biz.APITokenShowOnlySystemTokens(true)) + tokens, err := s.APITokenUseCase.List(ctx, currentOrg.ID, biz.WithAPITokenRevoked(req.IncludeRevoked), biz.WithAPITokenProjectFilter(defaultProjectFilter), biz.WithAPITokenScope(mapTokenScope(req.Scope))) if err != nil { return nil, handleUseCaseErr(err, s.log) } @@ -83,17 +114,40 @@ func (s *APITokenService) List(ctx context.Context, req *pb.APITokenServiceListR return &pb.APITokenServiceListResponse{Result: result}, nil } +func mapTokenScope(scope pb.APITokenServiceListRequest_Scope) biz.APITokenScope { + switch scope { + case pb.APITokenServiceListRequest_SCOPE_PROJECT: + return biz.APITokenScopeProject + case pb.APITokenServiceListRequest_SCOPE_GLOBAL: + return biz.APITokenScopeGlobal + } + + return "" +} + func (s *APITokenService) Revoke(ctx context.Context, req *pb.APITokenServiceRevokeRequest) (*pb.APITokenServiceRevokeResponse, error) { currentOrg, err := requireCurrentOrg(ctx) if err != nil { return nil, err } - t, err := s.APITokenUseCase.FindByNameInOrg(ctx, currentOrg.ID, req.Name) + t, err := s.APITokenUseCase.FindByIDInOrg(ctx, currentOrg.ID, req.GetId()) if err != nil { return nil, handleUseCaseErr(err, s.log) } + // 1 - Only admins can manage global contracts + if t.ProjectID == nil && rbacEnabled(ctx) { + return nil, errors.BadRequest("invalid", "you can not manage a global API token") + } + + // Make sure the user has permission to revoke the token in the project + if t.ProjectID != nil { + if err := s.authorizeResource(ctx, authz.PolicyAPITokenRevoke, authz.ResourceTypeProject, *t.ProjectID); err != nil { + return nil, err + } + } + if err := s.APITokenUseCase.Revoke(ctx, currentOrg.ID, t.ID.String()); err != nil { return nil, handleUseCaseErr(err, s.log) } @@ -124,11 +178,11 @@ func apiTokenBizToPb(in *biz.APIToken) *pb.APITokenItem { } if in.ProjectID != nil { - res.ProjectId = in.ProjectID.String() - } - - if in.ProjectName != nil { - res.ProjectName = *in.ProjectName + res.ScopedEntity = &pb.ScopedEntity{ + Type: string(biz.ContractScopeProject), + Id: in.ProjectID.String(), + Name: *in.ProjectName, + } } return res diff --git a/app/controlplane/internal/service/project.go b/app/controlplane/internal/service/project.go index a5f535193..0ac18fd78 100644 --- a/app/controlplane/internal/service/project.go +++ b/app/controlplane/internal/service/project.go @@ -18,7 +18,6 @@ package service import ( "context" "fmt" - "time" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/authz" @@ -32,96 +31,12 @@ import ( type ProjectService struct { pb.UnimplementedProjectServiceServer *service - - // Use Cases - apiTokenUseCase *biz.APITokenUseCase } -func NewProjectService(apiTokenUseCase *biz.APITokenUseCase, opts ...NewOpt) *ProjectService { +func NewProjectService(opts ...NewOpt) *ProjectService { return &ProjectService{ - service: newService(opts...), - apiTokenUseCase: apiTokenUseCase, - } -} - -func (s *ProjectService) APITokenCreate(ctx context.Context, req *pb.ProjectServiceAPITokenCreateRequest) (*pb.ProjectServiceAPITokenCreateResponse, error) { - currentOrg, err := requireCurrentOrg(ctx) - if err != nil { - return nil, err - } - - // Make sure the provided project exists and the user has permission to create tokens in it - project, err := s.userHasPermissionOnProject(ctx, currentOrg.ID, &pb.IdentityReference{Name: &req.ProjectName}, authz.PolicyProjectAPITokenCreate) - if err != nil { - return nil, err - } - - var expiresIn *time.Duration - if req.ExpiresIn != nil { - expiresIn = new(time.Duration) - *expiresIn = req.ExpiresIn.AsDuration() - } - - token, err := s.apiTokenUseCase.Create(ctx, req.Name, req.Description, expiresIn, currentOrg.ID, biz.APITokenWithProject(project)) - if err != nil { - return nil, handleUseCaseErr(err, s.log) - } - - return &pb.ProjectServiceAPITokenCreateResponse{ - Result: &pb.ProjectServiceAPITokenCreateResponse_APITokenFull{ - Item: apiTokenBizToPb(token), - Jwt: token.JWT, - }, - }, nil -} - -func (s *ProjectService) APITokenList(ctx context.Context, req *pb.ProjectServiceAPITokenListRequest) (*pb.ProjectServiceAPITokenListResponse, error) { - currentOrg, err := requireCurrentOrg(ctx) - if err != nil { - return nil, err - } - - // Make sure the provided project exists and the user has permission to create tokens in it - project, err := s.userHasPermissionOnProject(ctx, currentOrg.ID, req.GetProjectReference(), authz.PolicyProjectAPITokenList) - if err != nil { - return nil, err - } - - tokens, err := s.apiTokenUseCase.List(ctx, currentOrg.ID, req.IncludeRevoked, biz.APITokenWithProject(project)) - if err != nil { - return nil, handleUseCaseErr(err, s.log) - } - - result := make([]*pb.APITokenItem, 0, len(tokens)) - for _, p := range tokens { - result = append(result, apiTokenBizToPb(p)) + service: newService(opts...), } - - return &pb.ProjectServiceAPITokenListResponse{Result: result}, nil -} - -func (s *ProjectService) APITokenRevoke(ctx context.Context, req *pb.ProjectServiceAPITokenRevokeRequest) (*pb.ProjectServiceAPITokenRevokeResponse, error) { - currentOrg, err := requireCurrentOrg(ctx) - if err != nil { - return nil, err - } - - // Make sure the provided project exists and the user has permission to create tokens in it - project, err := s.userHasPermissionOnProject(ctx, currentOrg.ID, req.GetProjectReference(), authz.PolicyProjectAPITokenRevoke) - if err != nil { - return nil, err - } - - t, err := s.apiTokenUseCase.FindByNameInOrg(ctx, currentOrg.ID, req.Name, biz.APITokenWithProject(project)) - if err != nil { - return nil, handleUseCaseErr(err, s.log) - } - - if err := s.apiTokenUseCase.Revoke(ctx, currentOrg.ID, t.ID.String()); err != nil { - return nil, handleUseCaseErr(err, s.log) - } - - return &pb.ProjectServiceAPITokenRevokeResponse{}, nil } // ListMembers lists the members of a project. diff --git a/app/controlplane/internal/usercontext/apitoken_middleware_test.go b/app/controlplane/internal/usercontext/apitoken_middleware_test.go index 0c7e2120b..8b8699bb8 100644 --- a/app/controlplane/internal/usercontext/apitoken_middleware_test.go +++ b/app/controlplane/internal/usercontext/apitoken_middleware_test.go @@ -97,7 +97,7 @@ func TestWithCurrentAPITokenAndOrgMiddleware(t *testing.T) { wantToken := &biz.APIToken{ID: uuid.New(), OrganizationID: wantOrgID} t.Run(tc.name, func(t *testing.T) { - apiTokenRepo := bizMocks.NewMockAPITokenRepo(t) + apiTokenRepo := bizMocks.NewAPITokenRepo(t) orgRepo := bizMocks.NewOrganizationRepo(t) apiTokenUC, err := biz.NewAPITokenUseCase(apiTokenRepo, &biz.APITokenJWTConfig{SymmetricHmacKey: "test"}, nil, nil, nil, nil) require.NoError(t, err) diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index 1eb64343e..7c5b04b0b 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -50,7 +50,7 @@ const ( OrganizationMemberships = "organization_memberships" ResourceGroup = "group" ResourceGroupMembership = "group_membership" - ResourceProjectAPIToken = "project_api_token" + ResourceAPIToken = "api_token" ResourceProjectMembership = "project_membership" ResourceOrganizationInvitations = "organization_invitations" @@ -96,7 +96,7 @@ var ManagedResources = []string{ OrganizationMemberships, ResourceGroup, ResourceGroupMembership, - ResourceProjectAPIToken, + ResourceAPIToken, ResourceProjectMembership, ResourceOrganizationInvitations, } @@ -154,10 +154,10 @@ var ( PolicyGroupAddMemberships = &Policy{ResourceGroupMembership, ActionCreate} PolicyGroupRemoveMemberships = &Policy{ResourceGroupMembership, ActionDelete} PolicyGroupUpdateMemberships = &Policy{ResourceGroupMembership, ActionUpdate} - // Project API Token - PolicyProjectAPITokenList = &Policy{ResourceProjectAPIToken, ActionList} - PolicyProjectAPITokenCreate = &Policy{ResourceProjectAPIToken, ActionCreate} - PolicyProjectAPITokenRevoke = &Policy{ResourceProjectAPIToken, ActionDelete} + // API Token + PolicyAPITokenList = &Policy{ResourceAPIToken, ActionList} + PolicyAPITokenCreate = &Policy{ResourceAPIToken, ActionCreate} + PolicyAPITokenRevoke = &Policy{ResourceAPIToken, ActionDelete} // Project Memberships PolicyProjectListMemberships = &Policy{ResourceProjectMembership, ActionList} PolicyProjectAddMemberships = &Policy{ResourceProjectMembership, ActionCreate} @@ -257,10 +257,10 @@ var RolesMap = map[Role][]*Policy{ // Group Memberships PolicyGroupListMemberships, - // Project API Token - PolicyProjectAPITokenList, - PolicyProjectAPITokenCreate, - PolicyProjectAPITokenRevoke, + // Additional check for API tokens is done at the service level + PolicyAPITokenList, + PolicyAPITokenCreate, + PolicyAPITokenRevoke, // Project Memberships PolicyProjectListMemberships, @@ -278,6 +278,8 @@ var RolesMap = map[Role][]*Policy{ // workflow contracts PolicyWorkflowContractList, PolicyWorkflowContractRead, + // Project API Token + PolicyAPITokenList, }, // RoleProjectAdmin: represents a project administrator. It's the higher role in project resources, // and it's only considered when the org-level role is `RoleOrgMember` @@ -307,9 +309,9 @@ var RolesMap = map[Role][]*Policy{ PolicyAttachedIntegrationDetach, // Project API Token - PolicyProjectAPITokenList, - PolicyProjectAPITokenCreate, - PolicyProjectAPITokenRevoke, + PolicyAPITokenList, + PolicyAPITokenCreate, + PolicyAPITokenRevoke, // Project Memberships PolicyProjectListMemberships, @@ -411,6 +413,11 @@ var ServerOperationsMap = map[string][]*Policy{ "/controlplane.v1.ProjectService/RemoveMember": {}, "/controlplane.v1.ProjectService/UpdateMemberRole": {}, "/controlplane.v1.ProjectService/ListPendingInvitations": {}, + + // API tokens RBAC are handled at the service level + "/controlplane.v1.APITokenService/List": {}, + "/controlplane.v1.APITokenService/Create": {}, + "/controlplane.v1.APITokenService/Revoke": {}, } // Implements https://pkg.go.dev/entgo.io/ent/schema/field#EnumValues diff --git a/app/controlplane/pkg/biz/apitoken.go b/app/controlplane/pkg/biz/apitoken.go index a66a6a87e..2a7d8cb8a 100644 --- a/app/controlplane/pkg/biz/apitoken.go +++ b/app/controlplane/pkg/biz/apitoken.go @@ -18,6 +18,7 @@ package biz import ( "context" "fmt" + "slices" "time" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/auditor/events" @@ -57,13 +58,12 @@ type APIToken struct { type APITokenRepo interface { Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*APIToken, error) - // List all the tokens optionally filtering it by organization and including revoked tokens - List(ctx context.Context, orgID *uuid.UUID, projectID *uuid.UUID, includeRevoked bool, showOnlySystemTokens bool) ([]*APIToken, error) + List(ctx context.Context, orgID *uuid.UUID, filters *APITokenListFilters) ([]*APIToken, error) Revoke(ctx context.Context, orgID, ID uuid.UUID) error UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error FindByID(ctx context.Context, ID uuid.UUID) (*APIToken, error) - FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string, projectID *uuid.UUID) (*APIToken, error) + FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*APIToken, error) } type APITokenUseCase struct { @@ -134,22 +134,16 @@ type apiTokenOptions struct { showOnlySystemTokens bool } -type APITokenUseCaseOpt func(*apiTokenOptions) +type APITokenCreateOpt func(*apiTokenOptions) -func APITokenWithProject(project *Project) APITokenUseCaseOpt { +func APITokenWithProject(project *Project) APITokenCreateOpt { return func(o *apiTokenOptions) { o.project = project } } -func APITokenShowOnlySystemTokens(show bool) APITokenUseCaseOpt { - return func(o *apiTokenOptions) { - o.showOnlySystemTokens = show - } -} - // expires in is a string that can be parsed by time.ParseDuration -func (uc *APITokenUseCase) Create(ctx context.Context, name string, description *string, expiresIn *time.Duration, orgID string, opts ...APITokenUseCaseOpt) (*APIToken, error) { +func (uc *APITokenUseCase) Create(ctx context.Context, name string, description *string, expiresIn *time.Duration, orgID string, opts ...APITokenCreateOpt) (*APIToken, error) { options := &apiTokenOptions{} for _, opt := range opts { opt(options) @@ -277,10 +271,56 @@ func (uc *APITokenUseCase) RegenerateJWT(ctx context.Context, tokenID uuid.UUID, return token, nil } -func (uc *APITokenUseCase) List(ctx context.Context, orgID string, includeRevoked bool, opts ...APITokenUseCaseOpt) ([]*APIToken, error) { - options := &apiTokenOptions{} +type APITokenListOpt func(*APITokenListFilters) + +func WithAPITokenProjectFilter(projectIDs []uuid.UUID) APITokenListOpt { + return func(opts *APITokenListFilters) { + opts.FilterByProjects = projectIDs + } +} + +func WithAPITokenRevoked(includeRevoked bool) APITokenListOpt { + return func(opts *APITokenListFilters) { + opts.IncludeRevoked = includeRevoked + } +} + +func WithAPITokenScope(scope APITokenScope) APITokenListOpt { + return func(opts *APITokenListFilters) { + opts.FilterByScope = scope + } +} + +type APITokenScope string + +const ( + APITokenScopeProject APITokenScope = "project" + APITokenScopeGlobal APITokenScope = "global" +) + +var availableAPITokenScopes = []APITokenScope{ + APITokenScopeProject, + APITokenScopeGlobal, +} + +type APITokenListFilters struct { + // FilterByProjects is used to filter the result by a project list + // If it's empty, no filter will be applied + FilterByProjects []uuid.UUID + // IncludeRevoked is used to include revoked tokens in the result + IncludeRevoked bool + // FilterByScope is used to filter the result by the scope of the token + FilterByScope APITokenScope +} + +func (uc *APITokenUseCase) List(ctx context.Context, orgID string, opts ...APITokenListOpt) ([]*APIToken, error) { + filters := &APITokenListFilters{} for _, opt := range opts { - opt(options) + opt(filters) + } + + if filters.FilterByScope != "" && !slices.Contains(availableAPITokenScopes, filters.FilterByScope) { + return nil, NewErrValidationStr(fmt.Sprintf("invalid scope %q, please chose one of: %v", filters.FilterByScope, availableAPITokenScopes)) } orgUUID, err := uuid.Parse(orgID) @@ -288,12 +328,7 @@ func (uc *APITokenUseCase) List(ctx context.Context, orgID string, includeRevoke return nil, NewErrInvalidUUID(err) } - var projectID *uuid.UUID - if options.project != nil { - projectID = ToPtr(options.project.ID) - } - - return uc.apiTokenRepo.List(ctx, &orgUUID, projectID, includeRevoked, options.showOnlySystemTokens) + return uc.apiTokenRepo.List(ctx, &orgUUID, filters) } func (uc *APITokenUseCase) Revoke(ctx context.Context, orgID, id string) error { @@ -332,23 +367,18 @@ func (uc *APITokenUseCase) Revoke(ctx context.Context, orgID, id string) error { return nil } -func (uc *APITokenUseCase) FindByNameInOrg(ctx context.Context, orgID, name string, opts ...APITokenUseCaseOpt) (*APIToken, error) { - options := &apiTokenOptions{} - for _, opt := range opts { - opt(options) - } - +func (uc *APITokenUseCase) FindByIDInOrg(ctx context.Context, orgID, id string) (*APIToken, error) { orgUUID, err := uuid.Parse(orgID) if err != nil { return nil, NewErrInvalidUUID(err) } - var projectID *uuid.UUID - if options.project != nil { - projectID = ToPtr(options.project.ID) + tokenUUID, err := uuid.Parse(id) + if err != nil { + return nil, NewErrInvalidUUID(err) } - t, err := uc.apiTokenRepo.FindByNameInOrg(ctx, orgUUID, name, projectID) + t, err := uc.apiTokenRepo.FindByIDInOrg(ctx, orgUUID, tokenUUID) if err != nil { return nil, fmt.Errorf("finding token: %w", err) } @@ -384,7 +414,7 @@ func (suc *APITokenSyncerUseCase) SyncPolicies() error { suc.base.logger.Info("syncing policies for all the API tokens") // List all the non-revoked tokens from all the orgs - tokens, err := suc.base.apiTokenRepo.List(context.Background(), nil, nil, false, false) + tokens, err := suc.base.apiTokenRepo.List(context.Background(), nil, nil) if err != nil { return fmt.Errorf("listing tokens: %w", err) } @@ -396,6 +426,8 @@ func (suc *APITokenSyncerUseCase) SyncPolicies() error { } } + suc.base.logger.Info("policies synced") + return nil } diff --git a/app/controlplane/pkg/biz/apitoken_integration_test.go b/app/controlplane/pkg/biz/apitoken_integration_test.go index 169e8f606..0591bc6c2 100644 --- a/app/controlplane/pkg/biz/apitoken_integration_test.go +++ b/app/controlplane/pkg/biz/apitoken_integration_test.go @@ -124,7 +124,7 @@ func (s *apiTokenTestSuite) TestCreate() { for _, tc := range testCases { s.Run(tc.name, func() { - var opts []biz.APITokenUseCaseOpt + var opts []biz.APITokenCreateOpt if tc.project != nil { opts = append(opts, biz.APITokenWithProject(tc.project)) } @@ -201,7 +201,7 @@ func (s *apiTokenTestSuite) TestRevoke() { s.Run("token can be revoked once", func() { err := s.APIToken.Revoke(ctx, s.org.ID, s.t1.ID.String()) s.NoError(err) - tokens, err := s.APIToken.List(ctx, s.org.ID, true) + tokens, err := s.APIToken.List(ctx, s.org.ID, biz.WithAPITokenRevoked(true)) s.NoError(err) s.Equal(s.t1.ID, tokens[0].ID) // It's revoked @@ -240,7 +240,7 @@ func (s *apiTokenTestSuite) TestFindByID() { func (s *apiTokenTestSuite) TestList() { ctx := context.Background() s.Run("invalid org ID", func() { - tokens, err := s.APIToken.List(ctx, "deadbeef", false) + tokens, err := s.APIToken.List(ctx, "deadbeef") s.Error(err) s.True(biz.IsErrInvalidUUID(err)) s.Nil(tokens) @@ -249,61 +249,70 @@ func (s *apiTokenTestSuite) TestList() { s.Run("returns empty list", func() { emptyOrg, err := s.Organization.CreateWithRandomName(ctx) require.NoError(s.T(), err) - tokens, err := s.APIToken.List(ctx, emptyOrg.ID, false) + tokens, err := s.APIToken.List(ctx, emptyOrg.ID) s.NoError(err) s.Len(tokens, 0) }) s.Run("returns all tokens for that org both system and project scoped", func() { - var err error - tokens, err := s.APIToken.List(ctx, s.org.ID, false) + tokens, err := s.APIToken.List(ctx, s.org.ID) s.NoError(err) - require.Len(s.T(), tokens, 4) + require.Len(s.T(), tokens, 5) s.Equal(s.t1.ID, tokens[0].ID) s.Equal(s.t2.ID, tokens[1].ID) // It has a name set s.NotEmpty(tokens[1].Name) - s.Equal(s.t2.Name, tokens[1].Name) - tokens, err = s.APIToken.List(ctx, s.org2.ID, false) + tokens, err = s.APIToken.List(ctx, s.org2.ID) s.NoError(err) require.Len(s.T(), tokens, 1) s.Equal(s.t3.ID, tokens[0].ID) }) s.Run("can return only for a specific project", func() { - var err error - tokens, err := s.APIToken.List(ctx, s.org.ID, false, biz.APITokenWithProject(s.p1)) + tokens, err := s.APIToken.List(ctx, s.org.ID, biz.WithAPITokenProjectFilter([]uuid.UUID{s.p1.ID})) s.NoError(err) require.Len(s.T(), tokens, 2) s.Equal(s.t4.ID, tokens[0].ID) s.Equal(s.t5.ID, tokens[1].ID) }) - s.Run("or just the system tokens", func() { - var err error - tokens, err := s.APIToken.List(ctx, s.org.ID, false, biz.APITokenShowOnlySystemTokens(true)) + s.Run("can return scoped to a project", func() { + tokens, err := s.APIToken.List(ctx, s.org.ID, biz.WithAPITokenScope(biz.APITokenScopeProject)) s.NoError(err) - require.Len(s.T(), tokens, 2) - s.Equal(s.t1.ID, tokens[0].ID) - s.Equal(s.t2.ID, tokens[1].ID) + require.Len(s.T(), tokens, 3) + }) + + s.Run("can return scoped to a global", func() { + tokens, err := s.APIToken.List(ctx, s.org.ID, biz.WithAPITokenScope(biz.APITokenScopeGlobal)) + s.NoError(err) + s.Len(tokens, 2) + }) + + s.Run("they are org scoped", func() { + tokens, err := s.APIToken.List(ctx, s.org.ID) + s.NoError(err) + s.Len(tokens, 5) + + tokens, err = s.APIToken.List(ctx, s.org2.ID) + s.NoError(err) + s.Len(tokens, 1) }) s.Run("doesn't return revoked by default", func() { // revoke one token err := s.APIToken.Revoke(ctx, s.org.ID, s.t1.ID.String()) require.NoError(s.T(), err) - tokens, err := s.APIToken.List(ctx, s.org.ID, false) + tokens, err := s.APIToken.List(ctx, s.org.ID) s.NoError(err) - require.Len(s.T(), tokens, 3) + require.Len(s.T(), tokens, 4) s.Equal(s.t2.ID, tokens[0].ID) }) s.Run("doesn't return revoked unless requested", func() { - // revoke one token - tokens, err := s.APIToken.List(ctx, s.org.ID, true) + tokens, err := s.APIToken.List(ctx, s.org.ID, biz.WithAPITokenRevoked(true)) s.NoError(err) - require.Len(s.T(), tokens, 4) + require.Len(s.T(), tokens, 5) s.Equal(s.t1.ID, tokens[0].ID) s.Equal(s.t2.ID, tokens[1].ID) }) @@ -336,9 +345,9 @@ func TestAPITokenUseCase(t *testing.T) { // Utility struct to hold the test suite type apiTokenTestSuite struct { testhelpers.UseCasesEachTestSuite - org, org2 *biz.Organization - t1, t2, t3, t4, t5 *biz.APIToken - p1, p2 *biz.Project + org, org2 *biz.Organization + t1, t2, t3, t4, t5, t6 *biz.APIToken + p1, p2 *biz.Project } func (s *apiTokenTestSuite) SetupTest() { @@ -373,6 +382,10 @@ func (s *apiTokenTestSuite) SetupTest() { require.NoError(s.T(), err) s.t5, err = s.APIToken.Create(ctx, randomName(), nil, nil, s.org.ID, biz.APITokenWithProject(s.p1)) require.NoError(s.T(), err) + + // Create 1 token for project 2 + s.t6, err = s.APIToken.Create(ctx, randomName(), nil, nil, s.org.ID, biz.APITokenWithProject(s.p2)) + require.NoError(s.T(), err) } func (s *apiTokenTestSuite) TestUpdateLastUsedAt() { diff --git a/app/controlplane/pkg/biz/mocks/APITokenRepo.go b/app/controlplane/pkg/biz/mocks/APITokenRepo.go index 29c84e754..9803d4411 100644 --- a/app/controlplane/pkg/biz/mocks/APITokenRepo.go +++ b/app/controlplane/pkg/biz/mocks/APITokenRepo.go @@ -1,48 +1,27 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify +// Code generated by mockery v2.53.4. DO NOT EDIT. package mocks import ( - "context" - "time" + context "context" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" - "github.com/google/uuid" - mock "github.com/stretchr/testify/mock" -) + biz "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" -// NewMockAPITokenRepo creates a new instance of MockAPITokenRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockAPITokenRepo(t interface { - mock.TestingT - Cleanup(func()) -}) *MockAPITokenRepo { - mock := &MockAPITokenRepo{} - mock.Mock.Test(t) + mock "github.com/stretchr/testify/mock" - t.Cleanup(func() { mock.AssertExpectations(t) }) + time "time" - return mock -} + uuid "github.com/google/uuid" +) -// MockAPITokenRepo is an autogenerated mock type for the APITokenRepo type -type MockAPITokenRepo struct { +// APITokenRepo is an autogenerated mock type for the APITokenRepo type +type APITokenRepo struct { mock.Mock } -type MockAPITokenRepo_Expecter struct { - mock *mock.Mock -} - -func (_m *MockAPITokenRepo) EXPECT() *MockAPITokenRepo_Expecter { - return &MockAPITokenRepo_Expecter{mock: &_m.Mock} -} - -// Create provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*biz.APIToken, error) { - ret := _mock.Called(ctx, name, description, expiresAt, organizationID, projectID) +// Create provides a mock function with given fields: ctx, name, description, expiresAt, organizationID, projectID +func (_m *APITokenRepo) Create(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*biz.APIToken, error) { + ret := _m.Called(ctx, name, description, expiresAt, organizationID, projectID) if len(ret) == 0 { panic("no return value specified for Create") @@ -50,91 +29,29 @@ func (_mock *MockAPITokenRepo) Create(ctx context.Context, name string, descript var r0 *biz.APIToken var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) (*biz.APIToken, error)); ok { - return returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + if rf, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) (*biz.APIToken, error)); ok { + return rf(ctx, name, description, expiresAt, organizationID, projectID) } - if returnFunc, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) *biz.APIToken); ok { - r0 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + if rf, ok := ret.Get(0).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) *biz.APIToken); ok { + r0 = rf(ctx, name, description, expiresAt, organizationID, projectID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) error); ok { - r1 = returnFunc(ctx, name, description, expiresAt, organizationID, projectID) + + if rf, ok := ret.Get(1).(func(context.Context, string, *string, *time.Time, uuid.UUID, *uuid.UUID) error); ok { + r1 = rf(ctx, name, description, expiresAt, organizationID, projectID) } else { r1 = ret.Error(1) } - return r0, r1 -} - -// MockAPITokenRepo_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' -type MockAPITokenRepo_Create_Call struct { - *mock.Call -} - -// Create is a helper method to define mock.On call -// - ctx context.Context -// - name string -// - description *string -// - expiresAt *time.Time -// - organizationID uuid.UUID -// - projectID *uuid.UUID -func (_e *MockAPITokenRepo_Expecter) Create(ctx interface{}, name interface{}, description interface{}, expiresAt interface{}, organizationID interface{}, projectID interface{}) *MockAPITokenRepo_Create_Call { - return &MockAPITokenRepo_Create_Call{Call: _e.mock.On("Create", ctx, name, description, expiresAt, organizationID, projectID)} -} - -func (_c *MockAPITokenRepo_Create_Call) Run(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID)) *MockAPITokenRepo_Create_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *string - if args[2] != nil { - arg2 = args[2].(*string) - } - var arg3 *time.Time - if args[3] != nil { - arg3 = args[3].(*time.Time) - } - var arg4 uuid.UUID - if args[4] != nil { - arg4 = args[4].(uuid.UUID) - } - var arg5 *uuid.UUID - if args[5] != nil { - arg5 = args[5].(*uuid.UUID) - } - run( - arg0, - arg1, - arg2, - arg3, - arg4, - arg5, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_Create_Call) Return(aPIToken *biz.APIToken, err error) *MockAPITokenRepo_Create_Call { - _c.Call.Return(aPIToken, err) - return _c -} -func (_c *MockAPITokenRepo_Create_Call) RunAndReturn(run func(ctx context.Context, name string, description *string, expiresAt *time.Time, organizationID uuid.UUID, projectID *uuid.UUID) (*biz.APIToken, error)) *MockAPITokenRepo_Create_Call { - _c.Call.Return(run) - return _c + return r0, r1 } -// FindByID provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error) { - ret := _mock.Called(ctx, ID) +// FindByID provides a mock function with given fields: ctx, ID +func (_m *APITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error) { + ret := _m.Called(ctx, ID) if len(ret) == 0 { panic("no return value specified for FindByID") @@ -142,147 +59,59 @@ func (_mock *MockAPITokenRepo) FindByID(ctx context.Context, ID uuid.UUID) (*biz var r0 *biz.APIToken var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.APIToken, error)); ok { - return returnFunc(ctx, ID) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) (*biz.APIToken, error)); ok { + return rf(ctx, ID) } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.APIToken); ok { - r0 = returnFunc(ctx, ID) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID) *biz.APIToken); ok { + r0 = rf(ctx, ID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { - r1 = returnFunc(ctx, ID) + + if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID) error); ok { + r1 = rf(ctx, ID) } else { r1 = ret.Error(1) } - return r0, r1 -} - -// MockAPITokenRepo_FindByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByID' -type MockAPITokenRepo_FindByID_Call struct { - *mock.Call -} - -// FindByID is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -func (_e *MockAPITokenRepo_Expecter) FindByID(ctx interface{}, ID interface{}) *MockAPITokenRepo_FindByID_Call { - return &MockAPITokenRepo_FindByID_Call{Call: _e.mock.On("FindByID", ctx, ID)} -} - -func (_c *MockAPITokenRepo_FindByID_Call) Run(run func(ctx context.Context, ID uuid.UUID)) *MockAPITokenRepo_FindByID_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_FindByID_Call) Return(aPIToken *biz.APIToken, err error) *MockAPITokenRepo_FindByID_Call { - _c.Call.Return(aPIToken, err) - return _c -} -func (_c *MockAPITokenRepo_FindByID_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID) (*biz.APIToken, error)) *MockAPITokenRepo_FindByID_Call { - _c.Call.Return(run) - return _c + return r0, r1 } -// FindByNameInOrg provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string, projectID *uuid.UUID) (*biz.APIToken, error) { - ret := _mock.Called(ctx, orgID, name, projectID) +// FindByIDInOrg provides a mock function with given fields: ctx, orgID, id +func (_m *APITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*biz.APIToken, error) { + ret := _m.Called(ctx, orgID, id) if len(ret) == 0 { - panic("no return value specified for FindByNameInOrg") + panic("no return value specified for FindByIDInOrg") } var r0 *biz.APIToken var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string, *uuid.UUID) (*biz.APIToken, error)); ok { - return returnFunc(ctx, orgID, name, projectID) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) (*biz.APIToken, error)); ok { + return rf(ctx, orgID, id) } - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, string, *uuid.UUID) *biz.APIToken); ok { - r0 = returnFunc(ctx, orgID, name, projectID) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) *biz.APIToken); ok { + r0 = rf(ctx, orgID, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*biz.APIToken) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, uuid.UUID, string, *uuid.UUID) error); ok { - r1 = returnFunc(ctx, orgID, name, projectID) + + if rf, ok := ret.Get(1).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { + r1 = rf(ctx, orgID, id) } else { r1 = ret.Error(1) } - return r0, r1 -} - -// MockAPITokenRepo_FindByNameInOrg_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByNameInOrg' -type MockAPITokenRepo_FindByNameInOrg_Call struct { - *mock.Call -} - -// FindByNameInOrg is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -// - name string -// - projectID *uuid.UUID -func (_e *MockAPITokenRepo_Expecter) FindByNameInOrg(ctx interface{}, orgID interface{}, name interface{}, projectID interface{}) *MockAPITokenRepo_FindByNameInOrg_Call { - return &MockAPITokenRepo_FindByNameInOrg_Call{Call: _e.mock.On("FindByNameInOrg", ctx, orgID, name, projectID)} -} - -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) Run(run func(ctx context.Context, orgID uuid.UUID, name string, projectID *uuid.UUID)) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 string - if args[2] != nil { - arg2 = args[2].(string) - } - var arg3 *uuid.UUID - if args[3] != nil { - arg3 = args[3].(*uuid.UUID) - } - run( - arg0, - arg1, - arg2, - arg3, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) Return(aPIToken *biz.APIToken, err error) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Return(aPIToken, err) - return _c -} -func (_c *MockAPITokenRepo_FindByNameInOrg_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, name string, projectID *uuid.UUID) (*biz.APIToken, error)) *MockAPITokenRepo_FindByNameInOrg_Call { - _c.Call.Return(run) - return _c + return r0, r1 } -// List provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) List(ctx context.Context, orgID *uuid.UUID, projectID *uuid.UUID, includeRevoked bool, showOnlySystemTokens bool) ([]*biz.APIToken, error) { - ret := _mock.Called(ctx, orgID, projectID, includeRevoked, showOnlySystemTokens) +// List provides a mock function with given fields: ctx, orgID, filters +func (_m *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters) ([]*biz.APIToken, error) { + ret := _m.Called(ctx, orgID, filters) if len(ret) == 0 { panic("no return value specified for List") @@ -290,267 +119,90 @@ func (_mock *MockAPITokenRepo) List(ctx context.Context, orgID *uuid.UUID, proje var r0 []*biz.APIToken var r1 error - if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *uuid.UUID, bool, bool) ([]*biz.APIToken, error)); ok { - return returnFunc(ctx, orgID, projectID, includeRevoked, showOnlySystemTokens) + if rf, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) ([]*biz.APIToken, error)); ok { + return rf(ctx, orgID, filters) } - if returnFunc, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *uuid.UUID, bool, bool) []*biz.APIToken); ok { - r0 = returnFunc(ctx, orgID, projectID, includeRevoked, showOnlySystemTokens) + if rf, ok := ret.Get(0).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) []*biz.APIToken); ok { + r0 = rf(ctx, orgID, filters) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*biz.APIToken) } } - if returnFunc, ok := ret.Get(1).(func(context.Context, *uuid.UUID, *uuid.UUID, bool, bool) error); ok { - r1 = returnFunc(ctx, orgID, projectID, includeRevoked, showOnlySystemTokens) + + if rf, ok := ret.Get(1).(func(context.Context, *uuid.UUID, *biz.APITokenListFilters) error); ok { + r1 = rf(ctx, orgID, filters) } else { r1 = ret.Error(1) } - return r0, r1 -} - -// MockAPITokenRepo_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type MockAPITokenRepo_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - ctx context.Context -// - orgID *uuid.UUID -// - projectID *uuid.UUID -// - includeRevoked bool -// - showOnlySystemTokens bool -func (_e *MockAPITokenRepo_Expecter) List(ctx interface{}, orgID interface{}, projectID interface{}, includeRevoked interface{}, showOnlySystemTokens interface{}) *MockAPITokenRepo_List_Call { - return &MockAPITokenRepo_List_Call{Call: _e.mock.On("List", ctx, orgID, projectID, includeRevoked, showOnlySystemTokens)} -} -func (_c *MockAPITokenRepo_List_Call) Run(run func(ctx context.Context, orgID *uuid.UUID, projectID *uuid.UUID, includeRevoked bool, showOnlySystemTokens bool)) *MockAPITokenRepo_List_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 *uuid.UUID - if args[1] != nil { - arg1 = args[1].(*uuid.UUID) - } - var arg2 *uuid.UUID - if args[2] != nil { - arg2 = args[2].(*uuid.UUID) - } - var arg3 bool - if args[3] != nil { - arg3 = args[3].(bool) - } - var arg4 bool - if args[4] != nil { - arg4 = args[4].(bool) - } - run( - arg0, - arg1, - arg2, - arg3, - arg4, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_List_Call) Return(aPITokens []*biz.APIToken, err error) *MockAPITokenRepo_List_Call { - _c.Call.Return(aPITokens, err) - return _c -} - -func (_c *MockAPITokenRepo_List_Call) RunAndReturn(run func(ctx context.Context, orgID *uuid.UUID, projectID *uuid.UUID, includeRevoked bool, showOnlySystemTokens bool) ([]*biz.APIToken, error)) *MockAPITokenRepo_List_Call { - _c.Call.Return(run) - return _c + return r0, r1 } -// Revoke provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) Revoke(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error { - ret := _mock.Called(ctx, orgID, ID) +// Revoke provides a mock function with given fields: ctx, orgID, ID +func (_m *APITokenRepo) Revoke(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error { + ret := _m.Called(ctx, orgID, ID) if len(ret) == 0 { panic("no return value specified for Revoke") } var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { - r0 = returnFunc(ctx, orgID, ID) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, uuid.UUID) error); ok { + r0 = rf(ctx, orgID, ID) } else { r0 = ret.Error(0) } - return r0 -} - -// MockAPITokenRepo_Revoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Revoke' -type MockAPITokenRepo_Revoke_Call struct { - *mock.Call -} - -// Revoke is a helper method to define mock.On call -// - ctx context.Context -// - orgID uuid.UUID -// - ID uuid.UUID -func (_e *MockAPITokenRepo_Expecter) Revoke(ctx interface{}, orgID interface{}, ID interface{}) *MockAPITokenRepo_Revoke_Call { - return &MockAPITokenRepo_Revoke_Call{Call: _e.mock.On("Revoke", ctx, orgID, ID)} -} - -func (_c *MockAPITokenRepo_Revoke_Call) Run(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID)) *MockAPITokenRepo_Revoke_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 uuid.UUID - if args[2] != nil { - arg2 = args[2].(uuid.UUID) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockAPITokenRepo_Revoke_Call) Return(err error) *MockAPITokenRepo_Revoke_Call { - _c.Call.Return(err) - return _c -} -func (_c *MockAPITokenRepo_Revoke_Call) RunAndReturn(run func(ctx context.Context, orgID uuid.UUID, ID uuid.UUID) error) *MockAPITokenRepo_Revoke_Call { - _c.Call.Return(run) - return _c + return r0 } -// UpdateExpiration provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error { - ret := _mock.Called(ctx, ID, expiresAt) +// UpdateExpiration provides a mock function with given fields: ctx, ID, expiresAt +func (_m *APITokenRepo) UpdateExpiration(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error { + ret := _m.Called(ctx, ID, expiresAt) if len(ret) == 0 { panic("no return value specified for UpdateExpiration") } var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = returnFunc(ctx, ID, expiresAt) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { + r0 = rf(ctx, ID, expiresAt) } else { r0 = ret.Error(0) } - return r0 -} - -// MockAPITokenRepo_UpdateExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateExpiration' -type MockAPITokenRepo_UpdateExpiration_Call struct { - *mock.Call -} - -// UpdateExpiration is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -// - expiresAt time.Time -func (_e *MockAPITokenRepo_Expecter) UpdateExpiration(ctx interface{}, ID interface{}, expiresAt interface{}) *MockAPITokenRepo_UpdateExpiration_Call { - return &MockAPITokenRepo_UpdateExpiration_Call{Call: _e.mock.On("UpdateExpiration", ctx, ID, expiresAt)} -} - -func (_c *MockAPITokenRepo_UpdateExpiration_Call) Run(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time)) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 time.Time - if args[2] != nil { - arg2 = args[2].(time.Time) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} -func (_c *MockAPITokenRepo_UpdateExpiration_Call) Return(err error) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockAPITokenRepo_UpdateExpiration_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, expiresAt time.Time) error) *MockAPITokenRepo_UpdateExpiration_Call { - _c.Call.Return(run) - return _c + return r0 } -// UpdateLastUsedAt provides a mock function for the type MockAPITokenRepo -func (_mock *MockAPITokenRepo) UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error { - ret := _mock.Called(ctx, ID, lastUsedAt) +// UpdateLastUsedAt provides a mock function with given fields: ctx, ID, lastUsedAt +func (_m *APITokenRepo) UpdateLastUsedAt(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error { + ret := _m.Called(ctx, ID, lastUsedAt) if len(ret) == 0 { panic("no return value specified for UpdateLastUsedAt") } var r0 error - if returnFunc, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { - r0 = returnFunc(ctx, ID, lastUsedAt) + if rf, ok := ret.Get(0).(func(context.Context, uuid.UUID, time.Time) error); ok { + r0 = rf(ctx, ID, lastUsedAt) } else { r0 = ret.Error(0) } - return r0 -} - -// MockAPITokenRepo_UpdateLastUsedAt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLastUsedAt' -type MockAPITokenRepo_UpdateLastUsedAt_Call struct { - *mock.Call -} -// UpdateLastUsedAt is a helper method to define mock.On call -// - ctx context.Context -// - ID uuid.UUID -// - lastUsedAt time.Time -func (_e *MockAPITokenRepo_Expecter) UpdateLastUsedAt(ctx interface{}, ID interface{}, lastUsedAt interface{}) *MockAPITokenRepo_UpdateLastUsedAt_Call { - return &MockAPITokenRepo_UpdateLastUsedAt_Call{Call: _e.mock.On("UpdateLastUsedAt", ctx, ID, lastUsedAt)} + return r0 } -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) Run(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time)) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 context.Context - if args[0] != nil { - arg0 = args[0].(context.Context) - } - var arg1 uuid.UUID - if args[1] != nil { - arg1 = args[1].(uuid.UUID) - } - var arg2 time.Time - if args[2] != nil { - arg2 = args[2].(time.Time) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} +// NewAPITokenRepo creates a new instance of APITokenRepo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAPITokenRepo(t interface { + mock.TestingT + Cleanup(func()) +}) *APITokenRepo { + mock := &APITokenRepo{} + mock.Mock.Test(t) -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) Return(err error) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Return(err) - return _c -} + t.Cleanup(func() { mock.AssertExpectations(t) }) -func (_c *MockAPITokenRepo_UpdateLastUsedAt_Call) RunAndReturn(run func(ctx context.Context, ID uuid.UUID, lastUsedAt time.Time) error) *MockAPITokenRepo_UpdateLastUsedAt_Call { - _c.Call.Return(run) - return _c + return mock } diff --git a/app/controlplane/pkg/data/apitoken.go b/app/controlplane/pkg/data/apitoken.go index 88c909550..57f060fa3 100644 --- a/app/controlplane/pkg/data/apitoken.go +++ b/app/controlplane/pkg/data/apitoken.go @@ -71,16 +71,8 @@ func (r *APITokenRepo) FindByID(ctx context.Context, id uuid.UUID) (*biz.APIToke return entAPITokenToBiz(token), nil } -func (r *APITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, name string, projectID *uuid.UUID) (*biz.APIToken, error) { - query := r.data.DB.APIToken.Query().Where(apitoken.NameEQ(name), apitoken.HasOrganizationWith(organization.ID(orgID)), apitoken.RevokedAtIsNil()) - - if projectID != nil { - query = query.Where(apitoken.ProjectIDEQ(*projectID)) - } else { - query = query.Where(apitoken.ProjectIDIsNil()) - } - - token, err := query.Only(ctx) +func (r *APITokenRepo) FindByIDInOrg(ctx context.Context, orgID uuid.UUID, id uuid.UUID) (*biz.APIToken, error) { + token, err := r.data.DB.APIToken.Query().Where(apitoken.ID(id), apitoken.HasOrganizationWith(organization.ID(orgID)), apitoken.RevokedAtIsNil()).WithProject().Only(ctx) if err != nil { if ent.IsNotFound(err) { return nil, biz.NewErrNotFound("API token") @@ -92,28 +84,29 @@ func (r *APITokenRepo) FindByNameInOrg(ctx context.Context, orgID uuid.UUID, nam return entAPITokenToBiz(token), nil } -func (r *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, projectID *uuid.UUID, includeRevoked bool, showOnlySystemTokens bool) ([]*biz.APIToken, error) { +func (r *APITokenRepo) List(ctx context.Context, orgID *uuid.UUID, filters *biz.APITokenListFilters) ([]*biz.APIToken, error) { query := r.data.DB.APIToken.Query().WithProject().WithOrganization() + if filters == nil { + filters = &biz.APITokenListFilters{} + } + if orgID != nil { query = query.Where(apitoken.OrganizationIDEQ(*orgID)) } - if showOnlySystemTokens && projectID != nil { - return nil, fmt.Errorf("projectID cannot be provided when skipProjectScopedTokens is true") + if len(filters.FilterByProjects) > 0 { + query = query.Where(apitoken.ProjectIDIn(filters.FilterByProjects...)) } - if showOnlySystemTokens { + switch filters.FilterByScope { + case biz.APITokenScopeProject: + query = query.Where(apitoken.ProjectIDNotNil()) + case biz.APITokenScopeGlobal: query = query.Where(apitoken.ProjectIDIsNil()) - } else if projectID != nil { - query = query.Where(apitoken.ProjectIDEQ(*projectID)) - } - - if projectID != nil { - query = query.Where(apitoken.ProjectIDEQ(*projectID)) } - if !includeRevoked { + if !filters.IncludeRevoked { query = query.Where(apitoken.RevokedAtIsNil()) }