From 6e9aa6a771e986ea01bcf45a2c4831a3b4d23ffc Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 10 Dec 2024 18:46:43 -0800 Subject: [PATCH] clients/v1: define user metadata RPCs (#78) Part of https://linear.app/sourcegraph/issue/CORE-545/confirm-absence-of-api-for-writing-sams-user-metadata - see issue description ## Test plan CI --------- Co-authored-by: Joe Chen --- auth/clientcredentials/connectrpc.go | 3 - auth/clientcredentials/connectrpc_test.go | 46 +- clients/v1/clients.pb.go | 948 +++++++++++++----- clients/v1/clients.proto | 66 ++ .../v1/clientsv1connect/clients.connect.go | 82 +- scopes/metadata.go | 25 + scopes/metadata_test.go | 29 + scopes/scopes.go | 8 + scopes/scopes_test.go | 6 + 9 files changed, 931 insertions(+), 282 deletions(-) create mode 100644 scopes/metadata.go create mode 100644 scopes/metadata_test.go diff --git a/auth/clientcredentials/connectrpc.go b/auth/clientcredentials/connectrpc.go index 7e39b2f..7d559a8 100644 --- a/auth/clientcredentials/connectrpc.go +++ b/auth/clientcredentials/connectrpc.go @@ -170,9 +170,6 @@ func extractSchemaRequiredScopes(spec connect.Spec, extension *protoimpl.Extensi return nil, errors.Newf("extension field %s not valid", extension.TypeDescriptor().FullName()) } list := value.List() - if list.Len() == 0 { - return nil, errors.Newf("extension field %s cannot be empty", extension.TypeDescriptor().FullName()) - } requiredScopes := make(scopes.Scopes, list.Len()) for i := 0; i < list.Len(); i++ { diff --git a/auth/clientcredentials/connectrpc_test.go b/auth/clientcredentials/connectrpc_test.go index cc47e59..5348963 100644 --- a/auth/clientcredentials/connectrpc_test.go +++ b/auth/clientcredentials/connectrpc_test.go @@ -20,10 +20,14 @@ import ( ) func TestInterceptor(t *testing.T) { - // All tests based on UsersService.GetUser() + // All tests based on UsersService for _, tc := range []struct { - name string - token *sams.IntrospectTokenResponse + name string + token *sams.IntrospectTokenResponse + + // doRPC, if nil, tests against UsersService.GetUser() + doRPC func(svc clientsv1connect.UsersServiceClient) error + wantError autogold.Value wantLogs autogold.Value }{{ @@ -56,6 +60,34 @@ func TestInterceptor(t *testing.T) { }, wantError: autogold.Expect("permission_denied: insufficient scopes: got scopes [not-a-scope], required: [profile]"), wantLogs: autogold.Expect([]string{}), + }, { + name: "no scopes required, active session", + token: &sams.IntrospectTokenResponse{ + Active: true, + Scopes: scopes.Scopes{}, + }, + doRPC: func(svc clientsv1connect.UsersServiceClient) error { + // GetUserMetadata has no sams_required_scopes extension + _, err := svc.GetUserMetadata(context.Background(), connect.NewRequest(&clientsv1.GetUserMetadataRequest{})) + return err + }, + wantError: autogold.Expect(nil), // should not error! + wantLogs: autogold.Expect([]string{}), + }, { + name: "no scopes required, inactive session", + token: &sams.IntrospectTokenResponse{ + Active: false, + Scopes: scopes.Scopes{}, + }, + doRPC: func(svc clientsv1connect.UsersServiceClient) error { + // GetUserMetadata has no sams_required_scopes extension + _, err := svc.GetUserMetadata(context.Background(), connect.NewRequest(&clientsv1.GetUserMetadataRequest{})) + return err + }, + // should error - no required scopes still requires an active and valid + // client credentials token + wantError: autogold.Expect("permission_denied: permission denied"), + wantLogs: autogold.Expect([]string{}), }} { t.Run(tc.name, func(t *testing.T) { logger, exportLogs := logtest.Captured(t) @@ -83,7 +115,13 @@ func TestInterceptor(t *testing.T) { }), ), srv.URL) - _, err := c.GetUser(context.Background(), connect.NewRequest(&clientsv1.GetUserRequest{})) + + var err error + if tc.doRPC == nil { + _, err = c.GetUser(context.Background(), connect.NewRequest(&clientsv1.GetUserRequest{})) + } else { + err = tc.doRPC(c) + } // Success cases are connect.CodeUnimplemented require.Error(t, err) diff --git a/clients/v1/clients.pb.go b/clients/v1/clients.pb.go index 5bf203a..4e1261c 100644 --- a/clients/v1/clients.pb.go +++ b/clients/v1/clients.pb.go @@ -10,6 +10,7 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" descriptorpb "google.golang.org/protobuf/types/descriptorpb" + structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" @@ -513,6 +514,291 @@ func (x *Role) GetResourceType() string { return "" } +type GetUserMetadataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The user's external ID. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // The list of namespace to filter the metadata. "*" can be used to return + // metadata for all namespaces. + // + // Requires the scope for the requested namespace(s); for example: + // - namespaces: ['*'] requires 'sams::user.metadata::read' + // - namespaces: ['dotcom'] requires 'sams::user.metadata.dotcom::read'. + Namespaces []string `protobuf:"bytes,2,rep,name=namespaces,proto3" json:"namespaces,omitempty"` +} + +func (x *GetUserMetadataRequest) Reset() { + *x = GetUserMetadataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clients_v1_clients_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserMetadataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserMetadataRequest) ProtoMessage() {} + +func (x *GetUserMetadataRequest) ProtoReflect() protoreflect.Message { + mi := &file_clients_v1_clients_proto_msgTypes[8] + 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 GetUserMetadataRequest.ProtoReflect.Descriptor instead. +func (*GetUserMetadataRequest) Descriptor() ([]byte, []int) { + return file_clients_v1_clients_proto_rawDescGZIP(), []int{8} +} + +func (x *GetUserMetadataRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetUserMetadataRequest) GetNamespaces() []string { + if x != nil { + return x.Namespaces + } + return nil +} + +// The metadata associated with a user for a specific namespace. +type UserServiceMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The user's external ID. + // + // Behaviour: IDENTIFIER + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + // The metadata namespace. + // + // Behaviour: IDENTIFIER + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` + // Metadata associated with this user for the specified namespace. + Metadata *structpb.Struct `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *UserServiceMetadata) Reset() { + *x = UserServiceMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_clients_v1_clients_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserServiceMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserServiceMetadata) ProtoMessage() {} + +func (x *UserServiceMetadata) ProtoReflect() protoreflect.Message { + mi := &file_clients_v1_clients_proto_msgTypes[9] + 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 UserServiceMetadata.ProtoReflect.Descriptor instead. +func (*UserServiceMetadata) Descriptor() ([]byte, []int) { + return file_clients_v1_clients_proto_rawDescGZIP(), []int{9} +} + +func (x *UserServiceMetadata) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *UserServiceMetadata) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *UserServiceMetadata) GetMetadata() *structpb.Struct { + if x != nil { + return x.Metadata + } + return nil +} + +type GetUserMetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The requested metadata for the user. + Metadata []*UserServiceMetadata `protobuf:"bytes,1,rep,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *GetUserMetadataResponse) Reset() { + *x = GetUserMetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clients_v1_clients_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserMetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserMetadataResponse) ProtoMessage() {} + +func (x *GetUserMetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_clients_v1_clients_proto_msgTypes[10] + 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 GetUserMetadataResponse.ProtoReflect.Descriptor instead. +func (*GetUserMetadataResponse) Descriptor() ([]byte, []int) { + return file_clients_v1_clients_proto_rawDescGZIP(), []int{10} +} + +func (x *GetUserMetadataResponse) GetMetadata() []*UserServiceMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +type UpdateUserMetadataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The following fields are used to identify the workspace to update: + // - user_id + // - namespace + // Both user_id and namespace are required to apply an update. + // + // An update requires the scope for the requested namespace(s); for example + // namespaces: ['dotcom'] requires 'sams::user.metadata.dotcom::write' or the wildcard 'sams::user.metadata::write'. + // + // The wildcard '*' namespace is not allowed in an update. + Metadata *UserServiceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *UpdateUserMetadataRequest) Reset() { + *x = UpdateUserMetadataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_clients_v1_clients_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserMetadataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserMetadataRequest) ProtoMessage() {} + +func (x *UpdateUserMetadataRequest) ProtoReflect() protoreflect.Message { + mi := &file_clients_v1_clients_proto_msgTypes[11] + 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 UpdateUserMetadataRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserMetadataRequest) Descriptor() ([]byte, []int) { + return file_clients_v1_clients_proto_rawDescGZIP(), []int{11} +} + +func (x *UpdateUserMetadataRequest) GetMetadata() *UserServiceMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +type UpdateUserMetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The updated user metadata. + Metadata *UserServiceMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *UpdateUserMetadataResponse) Reset() { + *x = UpdateUserMetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_clients_v1_clients_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserMetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserMetadataResponse) ProtoMessage() {} + +func (x *UpdateUserMetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_clients_v1_clients_proto_msgTypes[12] + 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 UpdateUserMetadataResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserMetadataResponse) Descriptor() ([]byte, []int) { + return file_clients_v1_clients_proto_rawDescGZIP(), []int{12} +} + +func (x *UpdateUserMetadataResponse) GetMetadata() *UserServiceMetadata { + if x != nil { + return x.Metadata + } + return nil +} + type GetSessionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -525,7 +811,7 @@ type GetSessionRequest struct { func (x *GetSessionRequest) Reset() { *x = GetSessionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[8] + mi := &file_clients_v1_clients_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -538,7 +824,7 @@ func (x *GetSessionRequest) String() string { func (*GetSessionRequest) ProtoMessage() {} func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[8] + mi := &file_clients_v1_clients_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -551,7 +837,7 @@ func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSessionRequest.ProtoReflect.Descriptor instead. func (*GetSessionRequest) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{8} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{13} } func (x *GetSessionRequest) GetId() string { @@ -575,7 +861,7 @@ type Session struct { func (x *Session) Reset() { *x = Session{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[9] + mi := &file_clients_v1_clients_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -588,7 +874,7 @@ func (x *Session) String() string { func (*Session) ProtoMessage() {} func (x *Session) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[9] + mi := &file_clients_v1_clients_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -601,7 +887,7 @@ func (x *Session) ProtoReflect() protoreflect.Message { // Deprecated: Use Session.ProtoReflect.Descriptor instead. func (*Session) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{9} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{14} } func (x *Session) GetId() string { @@ -629,7 +915,7 @@ type GetSessionResponse struct { func (x *GetSessionResponse) Reset() { *x = GetSessionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[10] + mi := &file_clients_v1_clients_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -642,7 +928,7 @@ func (x *GetSessionResponse) String() string { func (*GetSessionResponse) ProtoMessage() {} func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[10] + mi := &file_clients_v1_clients_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -655,7 +941,7 @@ func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSessionResponse.ProtoReflect.Descriptor instead. func (*GetSessionResponse) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{10} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{15} } func (x *GetSessionResponse) GetSession() *Session { @@ -679,7 +965,7 @@ type SignOutSessionRequest struct { func (x *SignOutSessionRequest) Reset() { *x = SignOutSessionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[11] + mi := &file_clients_v1_clients_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -692,7 +978,7 @@ func (x *SignOutSessionRequest) String() string { func (*SignOutSessionRequest) ProtoMessage() {} func (x *SignOutSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[11] + mi := &file_clients_v1_clients_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -705,7 +991,7 @@ func (x *SignOutSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignOutSessionRequest.ProtoReflect.Descriptor instead. func (*SignOutSessionRequest) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{11} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{16} } func (x *SignOutSessionRequest) GetId() string { @@ -731,7 +1017,7 @@ type SignOutSessionResponse struct { func (x *SignOutSessionResponse) Reset() { *x = SignOutSessionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[12] + mi := &file_clients_v1_clients_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -744,7 +1030,7 @@ func (x *SignOutSessionResponse) String() string { func (*SignOutSessionResponse) ProtoMessage() {} func (x *SignOutSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[12] + mi := &file_clients_v1_clients_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -757,7 +1043,7 @@ func (x *SignOutSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignOutSessionResponse.ProtoReflect.Descriptor instead. func (*SignOutSessionResponse) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{12} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{17} } // ErrorRecordMismatch is returned in the error details when the record does not match the expected record, @@ -771,7 +1057,7 @@ type ErrorRecordMismatch struct { func (x *ErrorRecordMismatch) Reset() { *x = ErrorRecordMismatch{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[13] + mi := &file_clients_v1_clients_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -784,7 +1070,7 @@ func (x *ErrorRecordMismatch) String() string { func (*ErrorRecordMismatch) ProtoMessage() {} func (x *ErrorRecordMismatch) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[13] + mi := &file_clients_v1_clients_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -797,7 +1083,7 @@ func (x *ErrorRecordMismatch) ProtoReflect() protoreflect.Message { // Deprecated: Use ErrorRecordMismatch.ProtoReflect.Descriptor instead. func (*ErrorRecordMismatch) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{13} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{18} } type IntrospectTokenRequest struct { @@ -812,7 +1098,7 @@ type IntrospectTokenRequest struct { func (x *IntrospectTokenRequest) Reset() { *x = IntrospectTokenRequest{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[14] + mi := &file_clients_v1_clients_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -825,7 +1111,7 @@ func (x *IntrospectTokenRequest) String() string { func (*IntrospectTokenRequest) ProtoMessage() {} func (x *IntrospectTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[14] + mi := &file_clients_v1_clients_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -838,7 +1124,7 @@ func (x *IntrospectTokenRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IntrospectTokenRequest.ProtoReflect.Descriptor instead. func (*IntrospectTokenRequest) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{14} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{19} } func (x *IntrospectTokenRequest) GetToken() string { @@ -868,7 +1154,7 @@ type IntrospectTokenResponse struct { func (x *IntrospectTokenResponse) Reset() { *x = IntrospectTokenResponse{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[15] + mi := &file_clients_v1_clients_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -881,7 +1167,7 @@ func (x *IntrospectTokenResponse) String() string { func (*IntrospectTokenResponse) ProtoMessage() {} func (x *IntrospectTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[15] + mi := &file_clients_v1_clients_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -894,7 +1180,7 @@ func (x *IntrospectTokenResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IntrospectTokenResponse.ProtoReflect.Descriptor instead. func (*IntrospectTokenResponse) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{15} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{20} } func (x *IntrospectTokenResponse) GetActive() bool { @@ -942,7 +1228,7 @@ type RegisterRoleResourcesRequestMetadata struct { func (x *RegisterRoleResourcesRequestMetadata) Reset() { *x = RegisterRoleResourcesRequestMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[16] + mi := &file_clients_v1_clients_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -955,7 +1241,7 @@ func (x *RegisterRoleResourcesRequestMetadata) String() string { func (*RegisterRoleResourcesRequestMetadata) ProtoMessage() {} func (x *RegisterRoleResourcesRequestMetadata) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[16] + mi := &file_clients_v1_clients_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -968,7 +1254,7 @@ func (x *RegisterRoleResourcesRequestMetadata) ProtoReflect() protoreflect.Messa // Deprecated: Use RegisterRoleResourcesRequestMetadata.ProtoReflect.Descriptor instead. func (*RegisterRoleResourcesRequestMetadata) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{16} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{21} } func (x *RegisterRoleResourcesRequestMetadata) GetRevision() string { @@ -1000,7 +1286,7 @@ type RegisterRoleResourcesRequest struct { func (x *RegisterRoleResourcesRequest) Reset() { *x = RegisterRoleResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[17] + mi := &file_clients_v1_clients_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1013,7 +1299,7 @@ func (x *RegisterRoleResourcesRequest) String() string { func (*RegisterRoleResourcesRequest) ProtoMessage() {} func (x *RegisterRoleResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[17] + mi := &file_clients_v1_clients_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1026,7 +1312,7 @@ func (x *RegisterRoleResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterRoleResourcesRequest.ProtoReflect.Descriptor instead. func (*RegisterRoleResourcesRequest) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{17} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{22} } func (m *RegisterRoleResourcesRequest) GetPayload() isRegisterRoleResourcesRequest_Payload { @@ -1082,7 +1368,7 @@ type RegisterRoleResourcesResponse struct { func (x *RegisterRoleResourcesResponse) Reset() { *x = RegisterRoleResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[18] + mi := &file_clients_v1_clients_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1095,7 +1381,7 @@ func (x *RegisterRoleResourcesResponse) String() string { func (*RegisterRoleResourcesResponse) ProtoMessage() {} func (x *RegisterRoleResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[18] + mi := &file_clients_v1_clients_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1108,7 +1394,7 @@ func (x *RegisterRoleResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterRoleResourcesResponse.ProtoReflect.Descriptor instead. func (*RegisterRoleResourcesResponse) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{18} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{23} } func (x *RegisterRoleResourcesResponse) GetResourceCount() uint64 { @@ -1132,7 +1418,7 @@ type RoleResource struct { func (x *RoleResource) Reset() { *x = RoleResource{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[19] + mi := &file_clients_v1_clients_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1145,7 +1431,7 @@ func (x *RoleResource) String() string { func (*RoleResource) ProtoMessage() {} func (x *RoleResource) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[19] + mi := &file_clients_v1_clients_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1158,7 +1444,7 @@ func (x *RoleResource) ProtoReflect() protoreflect.Message { // Deprecated: Use RoleResource.ProtoReflect.Descriptor instead. func (*RoleResource) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{19} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{24} } func (x *RoleResource) GetResourceId() string { @@ -1186,7 +1472,7 @@ type RegisterRoleResourcesRequest_Resources struct { func (x *RegisterRoleResourcesRequest_Resources) Reset() { *x = RegisterRoleResourcesRequest_Resources{} if protoimpl.UnsafeEnabled { - mi := &file_clients_v1_clients_proto_msgTypes[20] + mi := &file_clients_v1_clients_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1199,7 +1485,7 @@ func (x *RegisterRoleResourcesRequest_Resources) String() string { func (*RegisterRoleResourcesRequest_Resources) ProtoMessage() {} func (x *RegisterRoleResourcesRequest_Resources) ProtoReflect() protoreflect.Message { - mi := &file_clients_v1_clients_proto_msgTypes[20] + mi := &file_clients_v1_clients_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1212,7 +1498,7 @@ func (x *RegisterRoleResourcesRequest_Resources) ProtoReflect() protoreflect.Mes // Deprecated: Use RegisterRoleResourcesRequest_Resources.ProtoReflect.Descriptor instead. func (*RegisterRoleResourcesRequest_Resources) Descriptor() ([]byte, []int) { - return file_clients_v1_clients_proto_rawDescGZIP(), []int{17, 0} + return file_clients_v1_clients_proto_rawDescGZIP(), []int{22, 0} } func (x *RegisterRoleResourcesRequest_Resources) GetResources() []*RoleResource { @@ -1253,183 +1539,227 @@ var file_clients_v1_clients_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x0e, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 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, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, - 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, + 0xfc, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 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, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 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, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x07, 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, 0x22, 0x37, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x23, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x3f, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x61, 0x0a, 0x14, 0x47, 0x65, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xab, 0x01, 0x0a, + 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x28, + 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x48, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x13, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x17, 0x0a, 0x07, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, + 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x56, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x58, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x59, 0x0a, 0x1a, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x07, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x22, 0x43, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2d, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, + 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x22, 0x18, 0x0a, 0x16, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x4d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x22, 0x2e, 0x0a, 0x16, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xa1, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x73, 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, 0x07, 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, - 0x22, 0x37, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x23, 0x0a, 0x0f, 0x47, 0x65, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x3a, - 0x0a, 0x10, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x3f, 0x0a, 0x13, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x61, 0x0a, 0x14, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, - 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x6f, 0x6c, 0x65, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x22, 0xab, - 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0b, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, - 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x23, 0x0a, 0x11, - 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x22, 0x4d, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x29, 0x0a, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, - 0x22, 0x43, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, - 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x53, 0x69, 0x67, 0x6e, 0x4f, - 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x15, 0x0a, 0x13, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x4d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x16, 0x49, 0x6e, 0x74, 0x72, - 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xa1, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x74, - 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, - 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, - 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 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, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x67, 0x0a, 0x24, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x67, 0x0a, 0x24, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x92, + 0x02, 0x0a, 0x1c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x52, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x92, 0x02, 0x0a, 0x1c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x52, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, - 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x43, 0x0a, 0x09, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, - 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x46, 0x0a, 0x1d, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0xa2, 0x02, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, - 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b, 0x8a, 0xb5, 0x18, - 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x52, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1c, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x0b, 0x8a, 0xb5, 0x18, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x6d, 0x0a, 0x0c, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x1a, 0x43, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x36, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0x46, 0x0a, 0x1d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x0c, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x32, + 0xe7, 0x03, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b, 0x8a, 0xb5, 0x18, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x52, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1a, 0x8a, 0xb5, 0x18, 0x16, 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2e, - 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x3a, 0x72, 0x65, 0x61, 0x64, 0x32, 0xea, 0x01, 0x0a, 0x0f, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x64, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x8a, 0xb5, - 0x18, 0x13, 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, - 0x3a, 0x72, 0x65, 0x61, 0x64, 0x12, 0x71, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, - 0x8a, 0xb5, 0x18, 0x14, 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x32, 0x6b, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5a, 0x0a, 0x0f, 0x49, 0x6e, 0x74, - 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, - 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, - 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa1, 0x01, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x90, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x28, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x8a, 0xb5, 0x18, 0x1c, 0x73, 0x61, 0x6d, 0x73, 0x3a, - 0x3a, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x3a, 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x01, 0x3a, 0x52, 0x0a, 0x14, 0x73, 0x61, 0x6d, - 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, - 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0xd1, 0x86, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x73, 0x61, 0x6d, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, 0x49, 0x5a, - 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, - 0x61, 0x70, 0x68, 0x2d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2d, 0x73, 0x64, 0x6b, - 0x2d, 0x67, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0b, 0x8a, 0xb5, 0x18, 0x07, 0x70, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x6d, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x8a, 0xb5, 0x18, 0x16, 0x73, 0x61, + 0x6d, 0x73, 0x3a, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x3a, 0x3a, + 0x72, 0x65, 0x61, 0x64, 0x12, 0x5c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x22, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x65, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x32, 0xea, 0x01, 0x0a, 0x0f, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x8a, 0xb5, 0x18, 0x13, + 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x72, + 0x65, 0x61, 0x64, 0x12, 0x71, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x8a, 0xb5, + 0x18, 0x14, 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x3a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x32, 0x6b, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5a, 0x0a, 0x0f, 0x49, 0x6e, 0x74, 0x72, 0x6f, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x74, 0x72, + 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x32, 0xa1, 0x01, 0x0a, 0x0c, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x90, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x28, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x20, 0x8a, 0xb5, 0x18, 0x1c, 0x73, 0x61, 0x6d, 0x73, 0x3a, 0x3a, 0x72, + 0x6f, 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x3a, 0x3a, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x01, 0x3a, 0x52, 0x0a, 0x14, 0x73, 0x61, 0x6d, 0x73, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, + 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xd1, 0x86, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x73, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, 0x49, 0x5a, 0x47, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, + 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1444,7 +1774,7 @@ func file_clients_v1_clients_proto_rawDescGZIP() []byte { return file_clients_v1_clients_proto_rawDescData } -var file_clients_v1_clients_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_clients_v1_clients_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_clients_v1_clients_proto_goTypes = []interface{}{ (*GetUserRequest)(nil), // 0: clients.v1.GetUserRequest (*User)(nil), // 1: clients.v1.User @@ -1454,54 +1784,68 @@ var file_clients_v1_clients_proto_goTypes = []interface{}{ (*GetUserRolesRequest)(nil), // 5: clients.v1.GetUserRolesRequest (*GetUserRolesResponse)(nil), // 6: clients.v1.GetUserRolesResponse (*Role)(nil), // 7: clients.v1.Role - (*GetSessionRequest)(nil), // 8: clients.v1.GetSessionRequest - (*Session)(nil), // 9: clients.v1.Session - (*GetSessionResponse)(nil), // 10: clients.v1.GetSessionResponse - (*SignOutSessionRequest)(nil), // 11: clients.v1.SignOutSessionRequest - (*SignOutSessionResponse)(nil), // 12: clients.v1.SignOutSessionResponse - (*ErrorRecordMismatch)(nil), // 13: clients.v1.ErrorRecordMismatch - (*IntrospectTokenRequest)(nil), // 14: clients.v1.IntrospectTokenRequest - (*IntrospectTokenResponse)(nil), // 15: clients.v1.IntrospectTokenResponse - (*RegisterRoleResourcesRequestMetadata)(nil), // 16: clients.v1.RegisterRoleResourcesRequestMetadata - (*RegisterRoleResourcesRequest)(nil), // 17: clients.v1.RegisterRoleResourcesRequest - (*RegisterRoleResourcesResponse)(nil), // 18: clients.v1.RegisterRoleResourcesResponse - (*RoleResource)(nil), // 19: clients.v1.RoleResource - (*RegisterRoleResourcesRequest_Resources)(nil), // 20: clients.v1.RegisterRoleResourcesRequest.Resources - (*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp - (*descriptorpb.MethodOptions)(nil), // 22: google.protobuf.MethodOptions + (*GetUserMetadataRequest)(nil), // 8: clients.v1.GetUserMetadataRequest + (*UserServiceMetadata)(nil), // 9: clients.v1.UserServiceMetadata + (*GetUserMetadataResponse)(nil), // 10: clients.v1.GetUserMetadataResponse + (*UpdateUserMetadataRequest)(nil), // 11: clients.v1.UpdateUserMetadataRequest + (*UpdateUserMetadataResponse)(nil), // 12: clients.v1.UpdateUserMetadataResponse + (*GetSessionRequest)(nil), // 13: clients.v1.GetSessionRequest + (*Session)(nil), // 14: clients.v1.Session + (*GetSessionResponse)(nil), // 15: clients.v1.GetSessionResponse + (*SignOutSessionRequest)(nil), // 16: clients.v1.SignOutSessionRequest + (*SignOutSessionResponse)(nil), // 17: clients.v1.SignOutSessionResponse + (*ErrorRecordMismatch)(nil), // 18: clients.v1.ErrorRecordMismatch + (*IntrospectTokenRequest)(nil), // 19: clients.v1.IntrospectTokenRequest + (*IntrospectTokenResponse)(nil), // 20: clients.v1.IntrospectTokenResponse + (*RegisterRoleResourcesRequestMetadata)(nil), // 21: clients.v1.RegisterRoleResourcesRequestMetadata + (*RegisterRoleResourcesRequest)(nil), // 22: clients.v1.RegisterRoleResourcesRequest + (*RegisterRoleResourcesResponse)(nil), // 23: clients.v1.RegisterRoleResourcesResponse + (*RoleResource)(nil), // 24: clients.v1.RoleResource + (*RegisterRoleResourcesRequest_Resources)(nil), // 25: clients.v1.RegisterRoleResourcesRequest.Resources + (*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 27: google.protobuf.Struct + (*descriptorpb.MethodOptions)(nil), // 28: google.protobuf.MethodOptions } var file_clients_v1_clients_proto_depIdxs = []int32{ - 21, // 0: clients.v1.User.created_at:type_name -> google.protobuf.Timestamp - 21, // 1: clients.v1.User.updated_at:type_name -> google.protobuf.Timestamp + 26, // 0: clients.v1.User.created_at:type_name -> google.protobuf.Timestamp + 26, // 1: clients.v1.User.updated_at:type_name -> google.protobuf.Timestamp 1, // 2: clients.v1.GetUserResponse.user:type_name -> clients.v1.User 1, // 3: clients.v1.GetUsersResponse.users:type_name -> clients.v1.User 7, // 4: clients.v1.GetUserRolesResponse.user_roles:type_name -> clients.v1.Role - 1, // 5: clients.v1.Session.user:type_name -> clients.v1.User - 9, // 6: clients.v1.GetSessionResponse.session:type_name -> clients.v1.Session - 21, // 7: clients.v1.IntrospectTokenResponse.expires_at:type_name -> google.protobuf.Timestamp - 16, // 8: clients.v1.RegisterRoleResourcesRequest.metadata:type_name -> clients.v1.RegisterRoleResourcesRequestMetadata - 20, // 9: clients.v1.RegisterRoleResourcesRequest.resources:type_name -> clients.v1.RegisterRoleResourcesRequest.Resources - 19, // 10: clients.v1.RegisterRoleResourcesRequest.Resources.resources:type_name -> clients.v1.RoleResource - 22, // 11: clients.v1.sams_required_scopes:extendee -> google.protobuf.MethodOptions - 0, // 12: clients.v1.UsersService.GetUser:input_type -> clients.v1.GetUserRequest - 3, // 13: clients.v1.UsersService.GetUsers:input_type -> clients.v1.GetUsersRequest - 5, // 14: clients.v1.UsersService.GetUserRoles:input_type -> clients.v1.GetUserRolesRequest - 8, // 15: clients.v1.SessionsService.GetSession:input_type -> clients.v1.GetSessionRequest - 11, // 16: clients.v1.SessionsService.SignOutSession:input_type -> clients.v1.SignOutSessionRequest - 14, // 17: clients.v1.TokensService.IntrospectToken:input_type -> clients.v1.IntrospectTokenRequest - 17, // 18: clients.v1.RolesService.RegisterRoleResources:input_type -> clients.v1.RegisterRoleResourcesRequest - 2, // 19: clients.v1.UsersService.GetUser:output_type -> clients.v1.GetUserResponse - 4, // 20: clients.v1.UsersService.GetUsers:output_type -> clients.v1.GetUsersResponse - 6, // 21: clients.v1.UsersService.GetUserRoles:output_type -> clients.v1.GetUserRolesResponse - 10, // 22: clients.v1.SessionsService.GetSession:output_type -> clients.v1.GetSessionResponse - 12, // 23: clients.v1.SessionsService.SignOutSession:output_type -> clients.v1.SignOutSessionResponse - 15, // 24: clients.v1.TokensService.IntrospectToken:output_type -> clients.v1.IntrospectTokenResponse - 18, // 25: clients.v1.RolesService.RegisterRoleResources:output_type -> clients.v1.RegisterRoleResourcesResponse - 19, // [19:26] is the sub-list for method output_type - 12, // [12:19] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 11, // [11:12] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 27, // 5: clients.v1.UserServiceMetadata.metadata:type_name -> google.protobuf.Struct + 9, // 6: clients.v1.GetUserMetadataResponse.metadata:type_name -> clients.v1.UserServiceMetadata + 9, // 7: clients.v1.UpdateUserMetadataRequest.metadata:type_name -> clients.v1.UserServiceMetadata + 9, // 8: clients.v1.UpdateUserMetadataResponse.metadata:type_name -> clients.v1.UserServiceMetadata + 1, // 9: clients.v1.Session.user:type_name -> clients.v1.User + 14, // 10: clients.v1.GetSessionResponse.session:type_name -> clients.v1.Session + 26, // 11: clients.v1.IntrospectTokenResponse.expires_at:type_name -> google.protobuf.Timestamp + 21, // 12: clients.v1.RegisterRoleResourcesRequest.metadata:type_name -> clients.v1.RegisterRoleResourcesRequestMetadata + 25, // 13: clients.v1.RegisterRoleResourcesRequest.resources:type_name -> clients.v1.RegisterRoleResourcesRequest.Resources + 24, // 14: clients.v1.RegisterRoleResourcesRequest.Resources.resources:type_name -> clients.v1.RoleResource + 28, // 15: clients.v1.sams_required_scopes:extendee -> google.protobuf.MethodOptions + 0, // 16: clients.v1.UsersService.GetUser:input_type -> clients.v1.GetUserRequest + 3, // 17: clients.v1.UsersService.GetUsers:input_type -> clients.v1.GetUsersRequest + 5, // 18: clients.v1.UsersService.GetUserRoles:input_type -> clients.v1.GetUserRolesRequest + 8, // 19: clients.v1.UsersService.GetUserMetadata:input_type -> clients.v1.GetUserMetadataRequest + 11, // 20: clients.v1.UsersService.UpdateUserMetadata:input_type -> clients.v1.UpdateUserMetadataRequest + 13, // 21: clients.v1.SessionsService.GetSession:input_type -> clients.v1.GetSessionRequest + 16, // 22: clients.v1.SessionsService.SignOutSession:input_type -> clients.v1.SignOutSessionRequest + 19, // 23: clients.v1.TokensService.IntrospectToken:input_type -> clients.v1.IntrospectTokenRequest + 22, // 24: clients.v1.RolesService.RegisterRoleResources:input_type -> clients.v1.RegisterRoleResourcesRequest + 2, // 25: clients.v1.UsersService.GetUser:output_type -> clients.v1.GetUserResponse + 4, // 26: clients.v1.UsersService.GetUsers:output_type -> clients.v1.GetUsersResponse + 6, // 27: clients.v1.UsersService.GetUserRoles:output_type -> clients.v1.GetUserRolesResponse + 10, // 28: clients.v1.UsersService.GetUserMetadata:output_type -> clients.v1.GetUserMetadataResponse + 12, // 29: clients.v1.UsersService.UpdateUserMetadata:output_type -> clients.v1.UpdateUserMetadataResponse + 15, // 30: clients.v1.SessionsService.GetSession:output_type -> clients.v1.GetSessionResponse + 17, // 31: clients.v1.SessionsService.SignOutSession:output_type -> clients.v1.SignOutSessionResponse + 20, // 32: clients.v1.TokensService.IntrospectToken:output_type -> clients.v1.IntrospectTokenResponse + 23, // 33: clients.v1.RolesService.RegisterRoleResources:output_type -> clients.v1.RegisterRoleResourcesResponse + 25, // [25:34] is the sub-list for method output_type + 16, // [16:25] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 15, // [15:16] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_clients_v1_clients_proto_init() } @@ -1607,7 +1951,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSessionRequest); i { + switch v := v.(*GetUserMetadataRequest); i { case 0: return &v.state case 1: @@ -1619,7 +1963,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Session); i { + switch v := v.(*UserServiceMetadata); i { case 0: return &v.state case 1: @@ -1631,7 +1975,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSessionResponse); i { + switch v := v.(*GetUserMetadataResponse); i { case 0: return &v.state case 1: @@ -1643,7 +1987,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignOutSessionRequest); i { + switch v := v.(*UpdateUserMetadataRequest); i { case 0: return &v.state case 1: @@ -1655,7 +1999,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignOutSessionResponse); i { + switch v := v.(*UpdateUserMetadataResponse); i { case 0: return &v.state case 1: @@ -1667,7 +2011,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorRecordMismatch); i { + switch v := v.(*GetSessionRequest); i { case 0: return &v.state case 1: @@ -1679,7 +2023,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntrospectTokenRequest); i { + switch v := v.(*Session); i { case 0: return &v.state case 1: @@ -1691,7 +2035,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntrospectTokenResponse); i { + switch v := v.(*GetSessionResponse); i { case 0: return &v.state case 1: @@ -1703,7 +2047,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterRoleResourcesRequestMetadata); i { + switch v := v.(*SignOutSessionRequest); i { case 0: return &v.state case 1: @@ -1715,7 +2059,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterRoleResourcesRequest); i { + switch v := v.(*SignOutSessionResponse); i { case 0: return &v.state case 1: @@ -1727,7 +2071,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegisterRoleResourcesResponse); i { + switch v := v.(*ErrorRecordMismatch); i { case 0: return &v.state case 1: @@ -1739,7 +2083,7 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoleResource); i { + switch v := v.(*IntrospectTokenRequest); i { case 0: return &v.state case 1: @@ -1751,6 +2095,66 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IntrospectTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clients_v1_clients_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterRoleResourcesRequestMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clients_v1_clients_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterRoleResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clients_v1_clients_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterRoleResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clients_v1_clients_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoleResource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_clients_v1_clients_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RegisterRoleResourcesRequest_Resources); i { case 0: return &v.state @@ -1764,8 +2168,8 @@ func file_clients_v1_clients_proto_init() { } } file_clients_v1_clients_proto_msgTypes[7].OneofWrappers = []interface{}{} - file_clients_v1_clients_proto_msgTypes[9].OneofWrappers = []interface{}{} - file_clients_v1_clients_proto_msgTypes[17].OneofWrappers = []interface{}{ + file_clients_v1_clients_proto_msgTypes[14].OneofWrappers = []interface{}{} + file_clients_v1_clients_proto_msgTypes[22].OneofWrappers = []interface{}{ (*RegisterRoleResourcesRequest_Metadata)(nil), (*RegisterRoleResourcesRequest_Resources_)(nil), } @@ -1775,7 +2179,7 @@ func file_clients_v1_clients_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_clients_v1_clients_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 26, NumExtensions: 1, NumServices: 4, }, diff --git a/clients/v1/clients.proto b/clients/v1/clients.proto index 5f20f4c..9b76a1f 100644 --- a/clients/v1/clients.proto +++ b/clients/v1/clients.proto @@ -4,6 +4,7 @@ package clients.v1; import "google/protobuf/timestamp.proto"; import "google/protobuf/descriptor.proto"; +import "google/protobuf/struct.proto"; option go_package = "github.com/sourcegraph/sourcegraph-accounts-sdk-go/clients/v1;clientsv1"; @@ -39,6 +40,22 @@ service UsersService { rpc GetUserRoles(GetUserRolesRequest) returns (GetUserRolesResponse) { option (sams_required_scopes) = "sams::user.roles::read"; }; + // GetUserMetadata retrieves metadata for a SAMS user. + // + // Required scopes: 'sams::user.metadata::read' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::read' + rpc GetUserMetadata(GetUserMetadataRequest) returns (GetUserMetadataResponse) { + // Cannot use 'sams_required_scopes' due to metadata-namespace-specific scopes. + // See docstring for required scopes. + } + // UpdateUserMetadata updates the metadata of a SAMS user. + // + // Required scopes: 'sams::user.metadata::write' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::write' + rpc UpdateUserMetadata(UpdateUserMetadataRequest) returns (UpdateUserMetadataResponse) { + // Cannot use 'sams_required_scopes' due to metadata-namespace-specific scopes. + // See docstring for required scopes. + } } // Exactly one attribute can be set. @@ -102,6 +119,55 @@ message Role { optional string resource_type = 4; } +message GetUserMetadataRequest { + // The user's external ID. + string id = 1; + // The list of namespace to filter the metadata. "*" can be used to return + // metadata for all namespaces. + // + // Requires the scope for the requested namespace(s); for example: + // - namespaces: ['*'] requires 'sams::user.metadata::read' + // - namespaces: ['dotcom'] requires 'sams::user.metadata.dotcom::read'. + repeated string namespaces = 2; +} + +// The metadata associated with a user for a specific namespace. +message UserServiceMetadata { + // The user's external ID. + // + // Behaviour: IDENTIFIER + string user_id = 1; + // The metadata namespace. + // + // Behaviour: IDENTIFIER + string namespace = 2; + // Metadata associated with this user for the specified namespace. + google.protobuf.Struct metadata = 3; +} + +message GetUserMetadataResponse { + // The requested metadata for the user. + repeated UserServiceMetadata metadata = 1; +} + +message UpdateUserMetadataRequest { + // The following fields are used to identify the workspace to update: + // - user_id + // - namespace + // Both user_id and namespace are required to apply an update. + // + // An update requires the scope for the requested namespace(s); for example + // namespaces: ['dotcom'] requires 'sams::user.metadata.dotcom::write' or the wildcard 'sams::user.metadata::write'. + // + // The wildcard '*' namespace is not allowed in an update. + UserServiceMetadata metadata = 1; +} + +message UpdateUserMetadataResponse { + // The updated user metadata. + UserServiceMetadata metadata = 1; +} + service SessionsService { // GetSession returns the SAMS session with the given ID. It returns // connect.CodeNotFound if no such session exists. The session's `User` field is diff --git a/clients/v1/clientsv1connect/clients.connect.go b/clients/v1/clientsv1connect/clients.connect.go index ccc62ab..687070a 100644 --- a/clients/v1/clientsv1connect/clients.connect.go +++ b/clients/v1/clientsv1connect/clients.connect.go @@ -46,6 +46,12 @@ const ( // UsersServiceGetUserRolesProcedure is the fully-qualified name of the UsersService's GetUserRoles // RPC. UsersServiceGetUserRolesProcedure = "/clients.v1.UsersService/GetUserRoles" + // UsersServiceGetUserMetadataProcedure is the fully-qualified name of the UsersService's + // GetUserMetadata RPC. + UsersServiceGetUserMetadataProcedure = "/clients.v1.UsersService/GetUserMetadata" + // UsersServiceUpdateUserMetadataProcedure is the fully-qualified name of the UsersService's + // UpdateUserMetadata RPC. + UsersServiceUpdateUserMetadataProcedure = "/clients.v1.UsersService/UpdateUserMetadata" // SessionsServiceGetSessionProcedure is the fully-qualified name of the SessionsService's // GetSession RPC. SessionsServiceGetSessionProcedure = "/clients.v1.SessionsService/GetSession" @@ -66,6 +72,8 @@ var ( usersServiceGetUserMethodDescriptor = usersServiceServiceDescriptor.Methods().ByName("GetUser") usersServiceGetUsersMethodDescriptor = usersServiceServiceDescriptor.Methods().ByName("GetUsers") usersServiceGetUserRolesMethodDescriptor = usersServiceServiceDescriptor.Methods().ByName("GetUserRoles") + usersServiceGetUserMetadataMethodDescriptor = usersServiceServiceDescriptor.Methods().ByName("GetUserMetadata") + usersServiceUpdateUserMetadataMethodDescriptor = usersServiceServiceDescriptor.Methods().ByName("UpdateUserMetadata") sessionsServiceServiceDescriptor = v1.File_clients_v1_clients_proto.Services().ByName("SessionsService") sessionsServiceGetSessionMethodDescriptor = sessionsServiceServiceDescriptor.Methods().ByName("GetSession") sessionsServiceSignOutSessionMethodDescriptor = sessionsServiceServiceDescriptor.Methods().ByName("SignOutSession") @@ -94,6 +102,16 @@ type UsersServiceClient interface { // // Required scopes: sams::user.roles::read GetUserRoles(context.Context, *connect.Request[v1.GetUserRolesRequest]) (*connect.Response[v1.GetUserRolesResponse], error) + // GetUserMetadata retrieves metadata for a SAMS user. + // + // Required scopes: 'sams::user.metadata::read' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::read' + GetUserMetadata(context.Context, *connect.Request[v1.GetUserMetadataRequest]) (*connect.Response[v1.GetUserMetadataResponse], error) + // UpdateUserMetadata updates the metadata of a SAMS user. + // + // Required scopes: 'sams::user.metadata::write' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::write' + UpdateUserMetadata(context.Context, *connect.Request[v1.UpdateUserMetadataRequest]) (*connect.Response[v1.UpdateUserMetadataResponse], error) } // NewUsersServiceClient constructs a client for the clients.v1.UsersService service. By default, it @@ -124,14 +142,28 @@ func NewUsersServiceClient(httpClient connect.HTTPClient, baseURL string, opts . connect.WithSchema(usersServiceGetUserRolesMethodDescriptor), connect.WithClientOptions(opts...), ), + getUserMetadata: connect.NewClient[v1.GetUserMetadataRequest, v1.GetUserMetadataResponse]( + httpClient, + baseURL+UsersServiceGetUserMetadataProcedure, + connect.WithSchema(usersServiceGetUserMetadataMethodDescriptor), + connect.WithClientOptions(opts...), + ), + updateUserMetadata: connect.NewClient[v1.UpdateUserMetadataRequest, v1.UpdateUserMetadataResponse]( + httpClient, + baseURL+UsersServiceUpdateUserMetadataProcedure, + connect.WithSchema(usersServiceUpdateUserMetadataMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // usersServiceClient implements UsersServiceClient. type usersServiceClient struct { - getUser *connect.Client[v1.GetUserRequest, v1.GetUserResponse] - getUsers *connect.Client[v1.GetUsersRequest, v1.GetUsersResponse] - getUserRoles *connect.Client[v1.GetUserRolesRequest, v1.GetUserRolesResponse] + getUser *connect.Client[v1.GetUserRequest, v1.GetUserResponse] + getUsers *connect.Client[v1.GetUsersRequest, v1.GetUsersResponse] + getUserRoles *connect.Client[v1.GetUserRolesRequest, v1.GetUserRolesResponse] + getUserMetadata *connect.Client[v1.GetUserMetadataRequest, v1.GetUserMetadataResponse] + updateUserMetadata *connect.Client[v1.UpdateUserMetadataRequest, v1.UpdateUserMetadataResponse] } // GetUser calls clients.v1.UsersService.GetUser. @@ -149,6 +181,16 @@ func (c *usersServiceClient) GetUserRoles(ctx context.Context, req *connect.Requ return c.getUserRoles.CallUnary(ctx, req) } +// GetUserMetadata calls clients.v1.UsersService.GetUserMetadata. +func (c *usersServiceClient) GetUserMetadata(ctx context.Context, req *connect.Request[v1.GetUserMetadataRequest]) (*connect.Response[v1.GetUserMetadataResponse], error) { + return c.getUserMetadata.CallUnary(ctx, req) +} + +// UpdateUserMetadata calls clients.v1.UsersService.UpdateUserMetadata. +func (c *usersServiceClient) UpdateUserMetadata(ctx context.Context, req *connect.Request[v1.UpdateUserMetadataRequest]) (*connect.Response[v1.UpdateUserMetadataResponse], error) { + return c.updateUserMetadata.CallUnary(ctx, req) +} + // UsersServiceHandler is an implementation of the clients.v1.UsersService service. type UsersServiceHandler interface { // GetUser returns the SAMS user with the given query. It returns connect.CodeNotFound @@ -168,6 +210,16 @@ type UsersServiceHandler interface { // // Required scopes: sams::user.roles::read GetUserRoles(context.Context, *connect.Request[v1.GetUserRolesRequest]) (*connect.Response[v1.GetUserRolesResponse], error) + // GetUserMetadata retrieves metadata for a SAMS user. + // + // Required scopes: 'sams::user.metadata::read' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::read' + GetUserMetadata(context.Context, *connect.Request[v1.GetUserMetadataRequest]) (*connect.Response[v1.GetUserMetadataResponse], error) + // UpdateUserMetadata updates the metadata of a SAMS user. + // + // Required scopes: 'sams::user.metadata::write' or metadata-namespace-specific + // variant scope, such as 'sams::user.metadata.dotcom::write' + UpdateUserMetadata(context.Context, *connect.Request[v1.UpdateUserMetadataRequest]) (*connect.Response[v1.UpdateUserMetadataResponse], error) } // NewUsersServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -194,6 +246,18 @@ func NewUsersServiceHandler(svc UsersServiceHandler, opts ...connect.HandlerOpti connect.WithSchema(usersServiceGetUserRolesMethodDescriptor), connect.WithHandlerOptions(opts...), ) + usersServiceGetUserMetadataHandler := connect.NewUnaryHandler( + UsersServiceGetUserMetadataProcedure, + svc.GetUserMetadata, + connect.WithSchema(usersServiceGetUserMetadataMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) + usersServiceUpdateUserMetadataHandler := connect.NewUnaryHandler( + UsersServiceUpdateUserMetadataProcedure, + svc.UpdateUserMetadata, + connect.WithSchema(usersServiceUpdateUserMetadataMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/clients.v1.UsersService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case UsersServiceGetUserProcedure: @@ -202,6 +266,10 @@ func NewUsersServiceHandler(svc UsersServiceHandler, opts ...connect.HandlerOpti usersServiceGetUsersHandler.ServeHTTP(w, r) case UsersServiceGetUserRolesProcedure: usersServiceGetUserRolesHandler.ServeHTTP(w, r) + case UsersServiceGetUserMetadataProcedure: + usersServiceGetUserMetadataHandler.ServeHTTP(w, r) + case UsersServiceUpdateUserMetadataProcedure: + usersServiceUpdateUserMetadataHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -223,6 +291,14 @@ func (UnimplementedUsersServiceHandler) GetUserRoles(context.Context, *connect.R return nil, connect.NewError(connect.CodeUnimplemented, errors.New("clients.v1.UsersService.GetUserRoles is not implemented")) } +func (UnimplementedUsersServiceHandler) GetUserMetadata(context.Context, *connect.Request[v1.GetUserMetadataRequest]) (*connect.Response[v1.GetUserMetadataResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("clients.v1.UsersService.GetUserMetadata is not implemented")) +} + +func (UnimplementedUsersServiceHandler) UpdateUserMetadata(context.Context, *connect.Request[v1.UpdateUserMetadataRequest]) (*connect.Response[v1.UpdateUserMetadataResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("clients.v1.UsersService.UpdateUserMetadata is not implemented")) +} + // SessionsServiceClient is a client for the clients.v1.SessionsService service. type SessionsServiceClient interface { // GetSession returns the SAMS session with the given ID. It returns diff --git a/scopes/metadata.go b/scopes/metadata.go new file mode 100644 index 0000000..774d7f0 --- /dev/null +++ b/scopes/metadata.go @@ -0,0 +1,25 @@ +package scopes + +import ( + "strings" + + "github.com/sourcegraph/sourcegraph/lib/errors" +) + +// PermissionToMetadataScope extracts the metadata scope from a permission. +// Only valid for 'user.metadata'-prefixed permissions. +// +// Examples: +// - user.metadata => * +// - user.metadata.cody => cody +// - user.metadata.dotcom => dotcom +func PermissionToMetadataScope(permission Permission) (string, error) { + const prefix = "user.metadata" + if !strings.HasPrefix(string(permission), prefix) { + return "", errors.New("permission is not a metadata permission") + } + if permission == prefix { + return "*", nil + } + return strings.TrimPrefix(string(permission), prefix+"."), nil +} diff --git a/scopes/metadata_test.go b/scopes/metadata_test.go new file mode 100644 index 0000000..c32d54e --- /dev/null +++ b/scopes/metadata_test.go @@ -0,0 +1,29 @@ +package scopes + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTokenScopeToMetadataScope(t *testing.T) { + for _, tc := range []struct { + permission Permission + expected string + }{ + {"user.metadata", "*"}, + {"user.metadata.cody", "cody"}, + {"user.metadata.dotcom", "dotcom"}, + {"user.metadata.cody_gatekeeper", "cody_gatekeeper"}, + } { + got, err := PermissionToMetadataScope(tc.permission) + require.NoError(t, err) + assert.Equal(t, tc.expected, got) + } + + t.Run("invalid permission", func(t *testing.T) { + _, err := PermissionToMetadataScope("not-a-metadata-permission") + assert.Error(t, err) + }) +} diff --git a/scopes/scopes.go b/scopes/scopes.go index 8026b74..3a3c30f 100644 --- a/scopes/scopes.go +++ b/scopes/scopes.go @@ -89,9 +89,17 @@ var ( "user", "user.profile", "user.roles", + + // Grants access to all scopes - use sparingly. "user.metadata", + // Cody Pro and SSC metadata "user.metadata.cody", + // Legacy Sourcegraph.com metadata "user.metadata.dotcom", + // Metadata owned by the 'Cody Gatekeeper' service. + "user.metadata.cody_gatekeeper", + // Metadata owned by PLG efforts for supporting community members. + "user.metadata.plg", "session", diff --git a/scopes/scopes_test.go b/scopes/scopes_test.go index c8a5009..f1b62ee 100644 --- a/scopes/scopes_test.go +++ b/scopes/scopes_test.go @@ -38,6 +38,12 @@ func TestAllowedGoldenList(t *testing.T) { Scope("sams::user.metadata.dotcom::read"), Scope("sams::user.metadata.dotcom::write"), Scope("sams::user.metadata.dotcom::delete"), + Scope("sams::user.metadata.cody_gatekeeper::read"), + Scope("sams::user.metadata.cody_gatekeeper::write"), + Scope("sams::user.metadata.cody_gatekeeper::delete"), + Scope("sams::user.metadata.plg::read"), + Scope("sams::user.metadata.plg::write"), + Scope("sams::user.metadata.plg::delete"), Scope("sams::session::read"), Scope("sams::session::write"), Scope("sams::session::delete"),