From 5288a5d9b1a8282ac5cc3ae4610e1b950eb6d4f5 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 14:33:31 +0200 Subject: [PATCH 01/11] feat(groups): Allow to list projects a group is member of Signed-off-by: Javier Rodriguez --- .../api/controlplane/v1/group.pb.go | 644 ++++++++-------- .../api/controlplane/v1/group.proto | 36 +- .../api/controlplane/v1/group_grpc.pb.go | 39 + .../api/controlplane/v1/project.pb.go | 708 ++++++------------ .../api/controlplane/v1/project.proto | 27 - .../api/controlplane/v1/shared_message.pb.go | 437 ++++++++++- .../api/controlplane/v1/shared_message.proto | 49 ++ .../api/gen/frontend/controlplane/v1/group.ts | 379 ++++++---- .../gen/frontend/controlplane/v1/project.ts | 180 +---- .../controlplane/v1/shared_message.ts | 379 ++++++++++ ...ServiceListProjectsRequest.jsonschema.json | 27 + ...roupServiceListProjectsRequest.schema.json | 27 + ...erviceListProjectsResponse.jsonschema.json | 30 + ...oupServiceListProjectsResponse.schema.json | 30 + .../controlplane.v1.Project.jsonschema.json | 60 ++ .../controlplane.v1.Project.schema.json | 60 ++ ...trolplane.v1.ProjectMember.jsonschema.json | 8 + .../controlplane.v1.ProjectMember.schema.json | 8 + app/controlplane/internal/service/group.go | 49 ++ app/controlplane/internal/service/project.go | 5 + app/controlplane/pkg/biz/group.go | 35 + app/controlplane/pkg/biz/project.go | 2 + app/controlplane/pkg/data/group.go | 105 +++ 23 files changed, 2150 insertions(+), 1174 deletions(-) create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.schema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.Project.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.Project.schema.json diff --git a/app/controlplane/api/controlplane/v1/group.pb.go b/app/controlplane/api/controlplane/v1/group.pb.go index f1bf62e1a..78a6e8de8 100644 --- a/app/controlplane/api/controlplane/v1/group.pb.go +++ b/app/controlplane/api/controlplane/v1/group.pb.go @@ -1107,109 +1107,6 @@ func (x *PendingGroupInvitation) GetInvitationId() string { return "" } -// Group represents a collection of users with shared access to resources -type Group struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Unique identifier for the group - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Human-readable name of the group - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // Additional details about the group's purpose - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - // UUID of the organization that this group belongs to - OrganizationId string `protobuf:"bytes,4,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` - // Count of members in the group - MemberCount int32 `protobuf:"varint,5,opt,name=member_count,json=memberCount,proto3" json:"member_count,omitempty"` - // Timestamp when the group was created - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // Timestamp when the group was last modified - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` -} - -func (x *Group) Reset() { - *x = Group{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Group) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Group) ProtoMessage() {} - -func (x *Group) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Group.ProtoReflect.Descriptor instead. -func (*Group) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{19} -} - -func (x *Group) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Group) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Group) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Group) GetOrganizationId() string { - if x != nil { - return x.OrganizationId - } - return "" -} - -func (x *Group) GetMemberCount() int32 { - if x != nil { - return x.MemberCount - } - return 0 -} - -func (x *Group) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Group) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - // GroupMember represents a user's membership within a group with their role information type GroupMember struct { state protoimpl.MessageState @@ -1229,7 +1126,7 @@ type GroupMember struct { func (x *GroupMember) Reset() { *x = GroupMember{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[20] + mi := &file_controlplane_v1_group_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1242,7 +1139,7 @@ func (x *GroupMember) String() string { func (*GroupMember) ProtoMessage() {} func (x *GroupMember) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[20] + mi := &file_controlplane_v1_group_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1255,7 +1152,7 @@ func (x *GroupMember) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMember.ProtoReflect.Descriptor instead. func (*GroupMember) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{20} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{19} } func (x *GroupMember) GetUser() *User { @@ -1303,7 +1200,7 @@ type GroupServiceUpdateMemberMaintainerStatusRequest struct { func (x *GroupServiceUpdateMemberMaintainerStatusRequest) Reset() { *x = GroupServiceUpdateMemberMaintainerStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[21] + mi := &file_controlplane_v1_group_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1316,7 +1213,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusRequest) String() string { func (*GroupServiceUpdateMemberMaintainerStatusRequest) ProtoMessage() {} func (x *GroupServiceUpdateMemberMaintainerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[21] + mi := &file_controlplane_v1_group_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1329,7 +1226,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusRequest) ProtoReflect() protore // Deprecated: Use GroupServiceUpdateMemberMaintainerStatusRequest.ProtoReflect.Descriptor instead. func (*GroupServiceUpdateMemberMaintainerStatusRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{21} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{20} } func (x *GroupServiceUpdateMemberMaintainerStatusRequest) GetGroupReference() *IdentityReference { @@ -1363,7 +1260,7 @@ type GroupServiceUpdateMemberMaintainerStatusResponse struct { func (x *GroupServiceUpdateMemberMaintainerStatusResponse) Reset() { *x = GroupServiceUpdateMemberMaintainerStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[22] + mi := &file_controlplane_v1_group_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1376,7 +1273,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusResponse) String() string { func (*GroupServiceUpdateMemberMaintainerStatusResponse) ProtoMessage() {} func (x *GroupServiceUpdateMemberMaintainerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[22] + mi := &file_controlplane_v1_group_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1389,9 +1286,125 @@ func (x *GroupServiceUpdateMemberMaintainerStatusResponse) ProtoReflect() protor // Deprecated: Use GroupServiceUpdateMemberMaintainerStatusResponse.ProtoReflect.Descriptor instead. func (*GroupServiceUpdateMemberMaintainerStatusResponse) Descriptor() ([]byte, []int) { + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{21} +} + +// GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group +type GroupServiceListProjectsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // IdentityReference is used to specify the group by either its ID or name + GroupReference *IdentityReference `protobuf:"bytes,1,opt,name=group_reference,json=groupReference,proto3" json:"group_reference,omitempty"` + // Pagination parameters to limit and offset results + Pagination *OffsetPaginationRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *GroupServiceListProjectsRequest) Reset() { + *x = GroupServiceListProjectsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_group_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GroupServiceListProjectsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupServiceListProjectsRequest) ProtoMessage() {} + +func (x *GroupServiceListProjectsRequest) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_group_proto_msgTypes[22] + 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 GroupServiceListProjectsRequest.ProtoReflect.Descriptor instead. +func (*GroupServiceListProjectsRequest) Descriptor() ([]byte, []int) { return file_controlplane_v1_group_proto_rawDescGZIP(), []int{22} } +func (x *GroupServiceListProjectsRequest) GetGroupReference() *IdentityReference { + if x != nil { + return x.GroupReference + } + return nil +} + +func (x *GroupServiceListProjectsRequest) GetPagination() *OffsetPaginationRequest { + if x != nil { + return x.Pagination + } + return nil +} + +// GroupServiceListProjectsResponse contains a paginated list of projects for a group +type GroupServiceListProjectsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of projects memberships matching the request criteria + ProjectMembers []*ProjectMember `protobuf:"bytes,1,rep,name=project_members,json=projectMembers,proto3" json:"project_members,omitempty"` + // Pagination information for the response + Pagination *OffsetPaginationResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *GroupServiceListProjectsResponse) Reset() { + *x = GroupServiceListProjectsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_group_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GroupServiceListProjectsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupServiceListProjectsResponse) ProtoMessage() {} + +func (x *GroupServiceListProjectsResponse) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_group_proto_msgTypes[23] + 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 GroupServiceListProjectsResponse.ProtoReflect.Descriptor instead. +func (*GroupServiceListProjectsResponse) Descriptor() ([]byte, []int) { + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{23} +} + +func (x *GroupServiceListProjectsResponse) GetProjectMembers() []*ProjectMember { + if x != nil { + return x.ProjectMembers + } + return nil +} + +func (x *GroupServiceListProjectsResponse) GetPagination() *OffsetPaginationResponse { + if x != nil { + return x.Pagination + } + return nil +} + var File_controlplane_v1_group_proto protoreflect.FileDescriptor var file_controlplane_v1_group_proto_rawDesc = []byte{ @@ -1581,133 +1594,147 @@ var file_controlplane_v1_group_proto_rawDesc = []byte{ 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, - 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x22, 0x8f, 0x02, 0x0a, - 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 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, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, - 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 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, 0xd3, - 0x01, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, - 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, - 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x2f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, - 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, - 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, - 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x32, 0x0a, 0x30, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8f, 0x09, 0x0a, - 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, - 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, - 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, - 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x22, 0xd3, 0x01, 0x0a, + 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, + 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x2f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, + 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x07, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, + 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x32, 0x0a, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x1f, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, + 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, + 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb6, 0x01, + 0x0a, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0e, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, + 0x47, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, + 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, - 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, - 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, - 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1722,7 +1749,7 @@ func file_controlplane_v1_group_proto_rawDescGZIP() []byte { return file_controlplane_v1_group_proto_rawDescData } -var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceCreateRequest)(nil), // 0: controlplane.v1.GroupServiceCreateRequest (*GroupServiceCreateResponse)(nil), // 1: controlplane.v1.GroupServiceCreateResponse @@ -1743,69 +1770,76 @@ var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceListPendingInvitationsRequest)(nil), // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest (*GroupServiceListPendingInvitationsResponse)(nil), // 17: controlplane.v1.GroupServiceListPendingInvitationsResponse (*PendingGroupInvitation)(nil), // 18: controlplane.v1.PendingGroupInvitation - (*Group)(nil), // 19: controlplane.v1.Group - (*GroupMember)(nil), // 20: controlplane.v1.GroupMember - (*GroupServiceUpdateMemberMaintainerStatusRequest)(nil), // 21: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - (*GroupServiceUpdateMemberMaintainerStatusResponse)(nil), // 22: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - (*IdentityReference)(nil), // 23: controlplane.v1.IdentityReference - (*OffsetPaginationRequest)(nil), // 24: controlplane.v1.OffsetPaginationRequest - (*OffsetPaginationResponse)(nil), // 25: controlplane.v1.OffsetPaginationResponse - (*User)(nil), // 26: controlplane.v1.User - (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp + (*GroupMember)(nil), // 19: controlplane.v1.GroupMember + (*GroupServiceUpdateMemberMaintainerStatusRequest)(nil), // 20: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + (*GroupServiceUpdateMemberMaintainerStatusResponse)(nil), // 21: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + (*GroupServiceListProjectsRequest)(nil), // 22: controlplane.v1.GroupServiceListProjectsRequest + (*GroupServiceListProjectsResponse)(nil), // 23: controlplane.v1.GroupServiceListProjectsResponse + (*Group)(nil), // 24: controlplane.v1.Group + (*IdentityReference)(nil), // 25: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 26: controlplane.v1.OffsetPaginationRequest + (*OffsetPaginationResponse)(nil), // 27: controlplane.v1.OffsetPaginationResponse + (*User)(nil), // 28: controlplane.v1.User + (*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp + (*ProjectMember)(nil), // 30: controlplane.v1.ProjectMember } var file_controlplane_v1_group_proto_depIdxs = []int32{ - 19, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group - 23, // 1: controlplane.v1.GroupServiceGetRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 19, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group - 24, // 3: controlplane.v1.GroupServiceListRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 19, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group - 25, // 5: controlplane.v1.GroupServiceListResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 23, // 6: controlplane.v1.GroupServiceUpdateRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 19, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group - 23, // 8: controlplane.v1.GroupServiceDeleteRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 20, // 9: controlplane.v1.GroupServiceListMembersResponse.members:type_name -> controlplane.v1.GroupMember - 25, // 10: controlplane.v1.GroupServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 23, // 11: controlplane.v1.GroupServiceListMembersRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 24, // 12: controlplane.v1.GroupServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 23, // 13: controlplane.v1.GroupServiceAddMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 23, // 14: controlplane.v1.GroupServiceRemoveMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 23, // 15: controlplane.v1.GroupServiceListPendingInvitationsRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 24, // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 24, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group + 25, // 1: controlplane.v1.GroupServiceGetRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 24, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group + 26, // 3: controlplane.v1.GroupServiceListRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 24, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group + 27, // 5: controlplane.v1.GroupServiceListResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 25, // 6: controlplane.v1.GroupServiceUpdateRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 24, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group + 25, // 8: controlplane.v1.GroupServiceDeleteRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 19, // 9: controlplane.v1.GroupServiceListMembersResponse.members:type_name -> controlplane.v1.GroupMember + 27, // 10: controlplane.v1.GroupServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 25, // 11: controlplane.v1.GroupServiceListMembersRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 12: controlplane.v1.GroupServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 25, // 13: controlplane.v1.GroupServiceAddMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 14: controlplane.v1.GroupServiceRemoveMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 15: controlplane.v1.GroupServiceListPendingInvitationsRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest 18, // 17: controlplane.v1.GroupServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingGroupInvitation - 25, // 18: controlplane.v1.GroupServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 26, // 19: controlplane.v1.PendingGroupInvitation.invited_by:type_name -> controlplane.v1.User - 27, // 20: controlplane.v1.PendingGroupInvitation.created_at:type_name -> google.protobuf.Timestamp - 27, // 21: controlplane.v1.Group.created_at:type_name -> google.protobuf.Timestamp - 27, // 22: controlplane.v1.Group.updated_at:type_name -> google.protobuf.Timestamp - 26, // 23: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User - 27, // 24: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp - 27, // 25: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp - 23, // 26: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 0, // 27: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest - 2, // 28: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest - 4, // 29: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest - 6, // 30: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest - 8, // 31: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest - 11, // 32: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest - 12, // 33: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest - 14, // 34: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest - 21, // 35: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - 16, // 36: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest - 1, // 37: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse - 3, // 38: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse - 5, // 39: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse - 7, // 40: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse - 9, // 41: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse - 10, // 42: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse - 13, // 43: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse - 15, // 44: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse - 22, // 45: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - 17, // 46: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse - 37, // [37:47] is the sub-list for method output_type - 27, // [27:37] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 27, // 18: controlplane.v1.GroupServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 28, // 19: controlplane.v1.PendingGroupInvitation.invited_by:type_name -> controlplane.v1.User + 29, // 20: controlplane.v1.PendingGroupInvitation.created_at:type_name -> google.protobuf.Timestamp + 28, // 21: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User + 29, // 22: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp + 29, // 23: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp + 25, // 24: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 25: controlplane.v1.GroupServiceListProjectsRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 26: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 30, // 27: controlplane.v1.GroupServiceListProjectsResponse.project_members:type_name -> controlplane.v1.ProjectMember + 27, // 28: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 0, // 29: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest + 2, // 30: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest + 4, // 31: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest + 6, // 32: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest + 8, // 33: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest + 11, // 34: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest + 12, // 35: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest + 14, // 36: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest + 20, // 37: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + 16, // 38: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest + 22, // 39: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest + 1, // 40: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse + 3, // 41: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse + 5, // 42: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse + 7, // 43: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse + 9, // 44: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse + 10, // 45: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse + 13, // 46: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse + 15, // 47: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse + 21, // 48: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + 17, // 49: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse + 23, // 50: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse + 40, // [40:51] is the sub-list for method output_type + 29, // [29:40] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_controlplane_v1_group_proto_init() } @@ -2046,7 +2080,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Group); i { + switch v := v.(*GroupMember); i { case 0: return &v.state case 1: @@ -2058,7 +2092,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupMember); i { + switch v := v.(*GroupServiceUpdateMemberMaintainerStatusRequest); i { case 0: return &v.state case 1: @@ -2070,7 +2104,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceUpdateMemberMaintainerStatusRequest); i { + switch v := v.(*GroupServiceUpdateMemberMaintainerStatusResponse); i { case 0: return &v.state case 1: @@ -2082,7 +2116,19 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceUpdateMemberMaintainerStatusResponse); i { + switch v := v.(*GroupServiceListProjectsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controlplane_v1_group_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupServiceListProjectsResponse); i { case 0: return &v.state case 1: @@ -2104,7 +2150,7 @@ func file_controlplane_v1_group_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_group_proto_rawDesc, NumEnums: 0, - NumMessages: 23, + NumMessages: 24, NumExtensions: 0, NumServices: 1, }, diff --git a/app/controlplane/api/controlplane/v1/group.proto b/app/controlplane/api/controlplane/v1/group.proto index fd5488859..ea8ca378b 100644 --- a/app/controlplane/api/controlplane/v1/group.proto +++ b/app/controlplane/api/controlplane/v1/group.proto @@ -47,6 +47,8 @@ service GroupService { rpc UpdateMemberMaintainerStatus(GroupServiceUpdateMemberMaintainerStatusRequest) returns (GroupServiceUpdateMemberMaintainerStatusResponse) {} // ListPendingInvitations retrieves pending invitations for a group rpc ListPendingInvitations(GroupServiceListPendingInvitationsRequest) returns (GroupServiceListPendingInvitationsResponse) {} + // ListProjects retrieves a paginated list of projects the group is a member of + rpc ListProjects(GroupServiceListProjectsRequest) returns (GroupServiceListProjectsResponse) {} } // GroupServiceCreateRequest contains the information needed to create a new group @@ -191,24 +193,6 @@ message PendingGroupInvitation { string invitation_id = 4; } -// Group represents a collection of users with shared access to resources -message Group { - // Unique identifier for the group - string id = 1; - // Human-readable name of the group - string name = 2; - // Additional details about the group's purpose - string description = 3; - // UUID of the organization that this group belongs to - string organization_id = 4; - // Count of members in the group - int32 member_count = 5; - // Timestamp when the group was created - google.protobuf.Timestamp created_at = 6; - // Timestamp when the group was last modified - google.protobuf.Timestamp updated_at = 7; -} - // GroupMember represents a user's membership within a group with their role information message GroupMember { // The user who is a member of the group @@ -236,3 +220,19 @@ message GroupServiceUpdateMemberMaintainerStatusRequest { // GroupServiceUpdateMemberMaintainerStatusResponse is returned upon successful update of a member's maintainer status message GroupServiceUpdateMemberMaintainerStatusResponse {} + +// GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group +message GroupServiceListProjectsRequest { + // IdentityReference is used to specify the group by either its ID or name + IdentityReference group_reference = 1 [(buf.validate.field).required = true]; + // Pagination parameters to limit and offset results + OffsetPaginationRequest pagination = 2; +} + +// GroupServiceListProjectsResponse contains a paginated list of projects for a group +message GroupServiceListProjectsResponse { + // List of projects memberships matching the request criteria + repeated ProjectMember project_members = 1; + // Pagination information for the response + OffsetPaginationResponse pagination = 2; +} diff --git a/app/controlplane/api/controlplane/v1/group_grpc.pb.go b/app/controlplane/api/controlplane/v1/group_grpc.pb.go index eb3102cf2..4a57fbd1f 100644 --- a/app/controlplane/api/controlplane/v1/group_grpc.pb.go +++ b/app/controlplane/api/controlplane/v1/group_grpc.pb.go @@ -44,6 +44,7 @@ const ( GroupService_RemoveMember_FullMethodName = "/controlplane.v1.GroupService/RemoveMember" GroupService_UpdateMemberMaintainerStatus_FullMethodName = "/controlplane.v1.GroupService/UpdateMemberMaintainerStatus" GroupService_ListPendingInvitations_FullMethodName = "/controlplane.v1.GroupService/ListPendingInvitations" + GroupService_ListProjects_FullMethodName = "/controlplane.v1.GroupService/ListProjects" ) // GroupServiceClient is the client API for GroupService service. @@ -70,6 +71,8 @@ type GroupServiceClient interface { UpdateMemberMaintainerStatus(ctx context.Context, in *GroupServiceUpdateMemberMaintainerStatusRequest, opts ...grpc.CallOption) (*GroupServiceUpdateMemberMaintainerStatusResponse, error) // ListPendingInvitations retrieves pending invitations for a group ListPendingInvitations(ctx context.Context, in *GroupServiceListPendingInvitationsRequest, opts ...grpc.CallOption) (*GroupServiceListPendingInvitationsResponse, error) + // ListProjects retrieves a paginated list of projects the group is a member of + ListProjects(ctx context.Context, in *GroupServiceListProjectsRequest, opts ...grpc.CallOption) (*GroupServiceListProjectsResponse, error) } type groupServiceClient struct { @@ -170,6 +173,15 @@ func (c *groupServiceClient) ListPendingInvitations(ctx context.Context, in *Gro return out, nil } +func (c *groupServiceClient) ListProjects(ctx context.Context, in *GroupServiceListProjectsRequest, opts ...grpc.CallOption) (*GroupServiceListProjectsResponse, error) { + out := new(GroupServiceListProjectsResponse) + err := c.cc.Invoke(ctx, GroupService_ListProjects_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // GroupServiceServer is the server API for GroupService service. // All implementations must embed UnimplementedGroupServiceServer // for forward compatibility @@ -194,6 +206,8 @@ type GroupServiceServer interface { UpdateMemberMaintainerStatus(context.Context, *GroupServiceUpdateMemberMaintainerStatusRequest) (*GroupServiceUpdateMemberMaintainerStatusResponse, error) // ListPendingInvitations retrieves pending invitations for a group ListPendingInvitations(context.Context, *GroupServiceListPendingInvitationsRequest) (*GroupServiceListPendingInvitationsResponse, error) + // ListProjects retrieves a paginated list of projects the group is a member of + ListProjects(context.Context, *GroupServiceListProjectsRequest) (*GroupServiceListProjectsResponse, error) mustEmbedUnimplementedGroupServiceServer() } @@ -231,6 +245,9 @@ func (UnimplementedGroupServiceServer) UpdateMemberMaintainerStatus(context.Cont func (UnimplementedGroupServiceServer) ListPendingInvitations(context.Context, *GroupServiceListPendingInvitationsRequest) (*GroupServiceListPendingInvitationsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPendingInvitations not implemented") } +func (UnimplementedGroupServiceServer) ListProjects(context.Context, *GroupServiceListProjectsRequest) (*GroupServiceListProjectsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListProjects not implemented") +} func (UnimplementedGroupServiceServer) mustEmbedUnimplementedGroupServiceServer() {} // UnsafeGroupServiceServer may be embedded to opt out of forward compatibility for this service. @@ -424,6 +441,24 @@ func _GroupService_ListPendingInvitations_Handler(srv interface{}, ctx context.C return interceptor(ctx, in, info, handler) } +func _GroupService_ListProjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GroupServiceListProjectsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GroupServiceServer).ListProjects(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GroupService_ListProjects_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GroupServiceServer).ListProjects(ctx, req.(*GroupServiceListProjectsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // GroupService_ServiceDesc is the grpc.ServiceDesc for GroupService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -471,6 +506,10 @@ var GroupService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListPendingInvitations", Handler: _GroupService_ListPendingInvitations_Handler, }, + { + MethodName: "ListProjects", + Handler: _GroupService_ListProjects_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "controlplane/v1/group.proto", diff --git a/app/controlplane/api/controlplane/v1/project.pb.go b/app/controlplane/api/controlplane/v1/project.pb.go index 618dfc62c..60506b1a1 100644 --- a/app/controlplane/api/controlplane/v1/project.pb.go +++ b/app/controlplane/api/controlplane/v1/project.pb.go @@ -37,59 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// ProjectMemberRole defines the roles a member can have in a project -type ProjectMemberRole int32 - -const ( - // Default role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 - // Admin role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 - // Viewer role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 -) - -// Enum value maps for ProjectMemberRole. -var ( - ProjectMemberRole_name = map[int32]string{ - 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", - 1: "PROJECT_MEMBER_ROLE_ADMIN", - 2: "PROJECT_MEMBER_ROLE_VIEWER", - } - ProjectMemberRole_value = map[string]int32{ - "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, - "PROJECT_MEMBER_ROLE_ADMIN": 1, - "PROJECT_MEMBER_ROLE_VIEWER": 2, - } -) - -func (x ProjectMemberRole) Enum() *ProjectMemberRole { - p := new(ProjectMemberRole) - *p = x - return p -} - -func (x ProjectMemberRole) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { - return file_controlplane_v1_project_proto_enumTypes[0].Descriptor() -} - -func (ProjectMemberRole) Type() protoreflect.EnumType { - return &file_controlplane_v1_project_proto_enumTypes[0] -} - -func (x ProjectMemberRole) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ProjectMemberRole.Descriptor instead. -func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} -} - // ProjectServiceListMembersRequest contains the information needed to list members of a project type ProjectServiceListMembersRequest struct { state protoimpl.MessageState @@ -206,119 +153,6 @@ func (x *ProjectServiceListMembersResponse) GetPagination() *OffsetPaginationRes return nil } -// ProjectMember represents an user or group who is a member of a project -type ProjectMember struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Subject can be either a user or a group - // - // Types that are assignable to Subject: - // - // *ProjectMember_User - // *ProjectMember_Group - Subject isProjectMember_Subject `protobuf_oneof:"subject"` - // The role of the user in the project - Role ProjectMemberRole `protobuf:"varint,3,opt,name=role,proto3,enum=controlplane.v1.ProjectMemberRole" json:"role,omitempty"` - // Timestamp when the project membership was created - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // Timestamp when the project membership was last modified - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` -} - -func (x *ProjectMember) Reset() { - *x = ProjectMember{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectMember) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectMember) ProtoMessage() {} - -func (x *ProjectMember) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectMember.ProtoReflect.Descriptor instead. -func (*ProjectMember) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} -} - -func (m *ProjectMember) GetSubject() isProjectMember_Subject { - if m != nil { - return m.Subject - } - return nil -} - -func (x *ProjectMember) GetUser() *User { - if x, ok := x.GetSubject().(*ProjectMember_User); ok { - return x.User - } - return nil -} - -func (x *ProjectMember) GetGroup() *Group { - if x, ok := x.GetSubject().(*ProjectMember_Group); ok { - return x.Group - } - return nil -} - -func (x *ProjectMember) GetRole() ProjectMemberRole { - if x != nil { - return x.Role - } - return ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED -} - -func (x *ProjectMember) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *ProjectMember) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -type isProjectMember_Subject interface { - isProjectMember_Subject() -} - -type ProjectMember_User struct { - // The user who is a member of the project - User *User `protobuf:"bytes,1,opt,name=user,proto3,oneof"` -} - -type ProjectMember_Group struct { - // The group who is a member of the project - Group *Group `protobuf:"bytes,2,opt,name=group,proto3,oneof"` -} - -func (*ProjectMember_User) isProjectMember_Subject() {} - -func (*ProjectMember_Group) isProjectMember_Subject() {} - // ProjectServiceAddMemberRequest contains the information needed to add a user to a project type ProjectServiceAddMemberRequest struct { state protoimpl.MessageState @@ -336,7 +170,7 @@ type ProjectServiceAddMemberRequest struct { func (x *ProjectServiceAddMemberRequest) Reset() { *x = ProjectServiceAddMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[3] + mi := &file_controlplane_v1_project_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -349,7 +183,7 @@ func (x *ProjectServiceAddMemberRequest) String() string { func (*ProjectServiceAddMemberRequest) ProtoMessage() {} func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[3] + mi := &file_controlplane_v1_project_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -362,7 +196,7 @@ func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} } func (x *ProjectServiceAddMemberRequest) GetProjectReference() *IdentityReference { @@ -396,7 +230,7 @@ type ProjectServiceAddMemberResponse struct { func (x *ProjectServiceAddMemberResponse) Reset() { *x = ProjectServiceAddMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[4] + mi := &file_controlplane_v1_project_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -409,7 +243,7 @@ func (x *ProjectServiceAddMemberResponse) String() string { func (*ProjectServiceAddMemberResponse) ProtoMessage() {} func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[4] + mi := &file_controlplane_v1_project_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -422,7 +256,7 @@ func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} } type ProjectServiceRemoveMemberRequest struct { @@ -439,7 +273,7 @@ type ProjectServiceRemoveMemberRequest struct { func (x *ProjectServiceRemoveMemberRequest) Reset() { *x = ProjectServiceRemoveMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[5] + mi := &file_controlplane_v1_project_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -452,7 +286,7 @@ func (x *ProjectServiceRemoveMemberRequest) String() string { func (*ProjectServiceRemoveMemberRequest) ProtoMessage() {} func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[5] + mi := &file_controlplane_v1_project_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -465,7 +299,7 @@ func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} } func (x *ProjectServiceRemoveMemberRequest) GetProjectReference() *IdentityReference { @@ -492,7 +326,7 @@ type ProjectServiceRemoveMemberResponse struct { func (x *ProjectServiceRemoveMemberResponse) Reset() { *x = ProjectServiceRemoveMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -505,7 +339,7 @@ func (x *ProjectServiceRemoveMemberResponse) String() string { func (*ProjectServiceRemoveMemberResponse) ProtoMessage() {} func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -518,7 +352,7 @@ func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} } // ProjectMembershipReference is used to reference a user or group in the context of project membership @@ -539,7 +373,7 @@ type ProjectMembershipReference struct { func (x *ProjectMembershipReference) Reset() { *x = ProjectMembershipReference{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -552,7 +386,7 @@ func (x *ProjectMembershipReference) String() string { func (*ProjectMembershipReference) ProtoMessage() {} func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -565,7 +399,7 @@ func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectMembershipReference.ProtoReflect.Descriptor instead. func (*ProjectMembershipReference) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} } func (m *ProjectMembershipReference) GetMembershipReference() isProjectMembershipReference_MembershipReference { @@ -625,7 +459,7 @@ type ProjectServiceUpdateMemberRoleRequest struct { func (x *ProjectServiceUpdateMemberRoleRequest) Reset() { *x = ProjectServiceUpdateMemberRoleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -638,7 +472,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) String() string { func (*ProjectServiceUpdateMemberRoleRequest) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -651,7 +485,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use ProjectServiceUpdateMemberRoleRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} } func (x *ProjectServiceUpdateMemberRoleRequest) GetProjectReference() *IdentityReference { @@ -685,7 +519,7 @@ type ProjectServiceUpdateMemberRoleResponse struct { func (x *ProjectServiceUpdateMemberRoleResponse) Reset() { *x = ProjectServiceUpdateMemberRoleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -698,7 +532,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) String() string { func (*ProjectServiceUpdateMemberRoleResponse) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -711,7 +545,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use ProjectServiceUpdateMemberRoleResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} } type ProjectServiceListPendingInvitationsRequest struct { @@ -728,7 +562,7 @@ type ProjectServiceListPendingInvitationsRequest struct { func (x *ProjectServiceListPendingInvitationsRequest) Reset() { *x = ProjectServiceListPendingInvitationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -741,7 +575,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) String() string { func (*ProjectServiceListPendingInvitationsRequest) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -754,7 +588,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflec // Deprecated: Use ProjectServiceListPendingInvitationsRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} } func (x *ProjectServiceListPendingInvitationsRequest) GetProjectReference() *IdentityReference { @@ -786,7 +620,7 @@ type ProjectServiceListPendingInvitationsResponse struct { func (x *ProjectServiceListPendingInvitationsResponse) Reset() { *x = ProjectServiceListPendingInvitationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -799,7 +633,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) String() string { func (*ProjectServiceListPendingInvitationsResponse) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -812,7 +646,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protorefle // Deprecated: Use ProjectServiceListPendingInvitationsResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} } func (x *ProjectServiceListPendingInvitationsResponse) GetInvitations() []*PendingProjectInvitation { @@ -848,7 +682,7 @@ type PendingProjectInvitation struct { func (x *PendingProjectInvitation) Reset() { *x = PendingProjectInvitation{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[12] + mi := &file_controlplane_v1_project_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -861,7 +695,7 @@ func (x *PendingProjectInvitation) String() string { func (*PendingProjectInvitation) ProtoMessage() {} func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[12] + mi := &file_controlplane_v1_project_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -874,7 +708,7 @@ func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { // Deprecated: Use PendingProjectInvitation.ProtoReflect.Descriptor instead. func (*PendingProjectInvitation) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{12} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} } func (x *PendingProjectInvitation) GetUserEmail() string { @@ -947,189 +781,163 @@ var file_controlplane_v1_project_proto_rawDesc = []byte{ 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xa5, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, - 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, - 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x09, 0x0a, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, - 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, - 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, - 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x0e, 0xba, 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, - 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, - 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, - 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, - 0x22, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, - 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, - 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, - 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, - 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x0e, 0xba, + 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, + 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0a, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, + 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x25, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, + 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, - 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, - 0x26, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, - 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, + 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, + 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6e, 0x65, + 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, + 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xec, 0x01, 0x0a, 0x18, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x26, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, - 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, - 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, - 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, - 0x62, 0x79, 0x2a, 0x77, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, - 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, - 0x4f, 0x4c, 0x45, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, - 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, - 0x4c, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x32, 0x8f, 0x05, 0x0a, 0x0e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, - 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, - 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, + 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xec, 0x01, 0x0a, 0x18, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, + 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x69, + 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x0a, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, + 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, + 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x32, 0x8f, 0x05, 0x0a, 0x0e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, + 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, - 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, - 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, + 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, + 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1144,70 +952,63 @@ func file_controlplane_v1_project_proto_rawDescGZIP() []byte { return file_controlplane_v1_project_proto_rawDescData } -var file_controlplane_v1_project_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_controlplane_v1_project_proto_goTypes = []interface{}{ - (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole - (*ProjectServiceListMembersRequest)(nil), // 1: controlplane.v1.ProjectServiceListMembersRequest - (*ProjectServiceListMembersResponse)(nil), // 2: controlplane.v1.ProjectServiceListMembersResponse - (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember - (*ProjectServiceAddMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceAddMemberRequest - (*ProjectServiceAddMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceAddMemberResponse - (*ProjectServiceRemoveMemberRequest)(nil), // 6: controlplane.v1.ProjectServiceRemoveMemberRequest - (*ProjectServiceRemoveMemberResponse)(nil), // 7: controlplane.v1.ProjectServiceRemoveMemberResponse - (*ProjectMembershipReference)(nil), // 8: controlplane.v1.ProjectMembershipReference - (*ProjectServiceUpdateMemberRoleRequest)(nil), // 9: controlplane.v1.ProjectServiceUpdateMemberRoleRequest - (*ProjectServiceUpdateMemberRoleResponse)(nil), // 10: controlplane.v1.ProjectServiceUpdateMemberRoleResponse - (*ProjectServiceListPendingInvitationsRequest)(nil), // 11: controlplane.v1.ProjectServiceListPendingInvitationsRequest - (*ProjectServiceListPendingInvitationsResponse)(nil), // 12: controlplane.v1.ProjectServiceListPendingInvitationsResponse - (*PendingProjectInvitation)(nil), // 13: controlplane.v1.PendingProjectInvitation - (*IdentityReference)(nil), // 14: controlplane.v1.IdentityReference - (*OffsetPaginationRequest)(nil), // 15: controlplane.v1.OffsetPaginationRequest - (*OffsetPaginationResponse)(nil), // 16: controlplane.v1.OffsetPaginationResponse + (*ProjectServiceListMembersRequest)(nil), // 0: controlplane.v1.ProjectServiceListMembersRequest + (*ProjectServiceListMembersResponse)(nil), // 1: controlplane.v1.ProjectServiceListMembersResponse + (*ProjectServiceAddMemberRequest)(nil), // 2: controlplane.v1.ProjectServiceAddMemberRequest + (*ProjectServiceAddMemberResponse)(nil), // 3: controlplane.v1.ProjectServiceAddMemberResponse + (*ProjectServiceRemoveMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceRemoveMemberRequest + (*ProjectServiceRemoveMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceRemoveMemberResponse + (*ProjectMembershipReference)(nil), // 6: controlplane.v1.ProjectMembershipReference + (*ProjectServiceUpdateMemberRoleRequest)(nil), // 7: controlplane.v1.ProjectServiceUpdateMemberRoleRequest + (*ProjectServiceUpdateMemberRoleResponse)(nil), // 8: controlplane.v1.ProjectServiceUpdateMemberRoleResponse + (*ProjectServiceListPendingInvitationsRequest)(nil), // 9: controlplane.v1.ProjectServiceListPendingInvitationsRequest + (*ProjectServiceListPendingInvitationsResponse)(nil), // 10: controlplane.v1.ProjectServiceListPendingInvitationsResponse + (*PendingProjectInvitation)(nil), // 11: controlplane.v1.PendingProjectInvitation + (*IdentityReference)(nil), // 12: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 13: controlplane.v1.OffsetPaginationRequest + (*ProjectMember)(nil), // 14: controlplane.v1.ProjectMember + (*OffsetPaginationResponse)(nil), // 15: controlplane.v1.OffsetPaginationResponse + (ProjectMemberRole)(0), // 16: controlplane.v1.ProjectMemberRole (*User)(nil), // 17: controlplane.v1.User - (*Group)(nil), // 18: controlplane.v1.Group - (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp + (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp } var file_controlplane_v1_project_proto_depIdxs = []int32{ - 14, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 15, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 3, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember - 16, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 17, // 4: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User - 18, // 5: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group - 0, // 6: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole - 19, // 7: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp - 19, // 8: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp - 14, // 9: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 10: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 11: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole - 14, // 12: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 13: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 14, // 14: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference - 14, // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 16: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 17: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole - 14, // 18: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 15, // 19: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 13, // 20: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation - 16, // 21: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 17, // 22: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User - 19, // 23: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp - 1, // 24: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest - 4, // 25: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest - 6, // 26: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest - 9, // 27: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest - 11, // 28: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest - 2, // 29: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse - 5, // 30: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse - 7, // 31: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse - 10, // 32: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse - 12, // 33: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse - 29, // [29:34] is the sub-list for method output_type - 24, // [24:29] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 12, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 13, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 14, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember + 15, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 12, // 4: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 6, // 5: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 16, // 6: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole + 12, // 7: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 6, // 8: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 12, // 9: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference + 12, // 10: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 6, // 11: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 16, // 12: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole + 12, // 13: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 13, // 14: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 11, // 15: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation + 15, // 16: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 17, // 17: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User + 18, // 18: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp + 0, // 19: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest + 2, // 20: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest + 4, // 21: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest + 7, // 22: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest + 9, // 23: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest + 1, // 24: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse + 3, // 25: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse + 5, // 26: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse + 8, // 27: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse + 10, // 28: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse + 24, // [24:29] is the sub-list for method output_type + 19, // [19:24] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_controlplane_v1_project_proto_init() } @@ -1245,18 +1046,6 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectMember); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_project_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceAddMemberRequest); i { case 0: return &v.state @@ -1268,7 +1057,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceAddMemberResponse); i { case 0: return &v.state @@ -1280,7 +1069,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceRemoveMemberRequest); i { case 0: return &v.state @@ -1292,7 +1081,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceRemoveMemberResponse); i { case 0: return &v.state @@ -1304,7 +1093,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectMembershipReference); i { case 0: return &v.state @@ -1316,7 +1105,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceUpdateMemberRoleRequest); i { case 0: return &v.state @@ -1328,7 +1117,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceUpdateMemberRoleResponse); i { case 0: return &v.state @@ -1340,7 +1129,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListPendingInvitationsRequest); i { case 0: return &v.state @@ -1352,7 +1141,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectServiceListPendingInvitationsResponse); i { case 0: return &v.state @@ -1364,7 +1153,7 @@ func file_controlplane_v1_project_proto_init() { return nil } } - file_controlplane_v1_project_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_controlplane_v1_project_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PendingProjectInvitation); i { case 0: return &v.state @@ -1377,28 +1166,23 @@ func file_controlplane_v1_project_proto_init() { } } } - file_controlplane_v1_project_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*ProjectMember_User)(nil), - (*ProjectMember_Group)(nil), - } - file_controlplane_v1_project_proto_msgTypes[7].OneofWrappers = []interface{}{ + file_controlplane_v1_project_proto_msgTypes[6].OneofWrappers = []interface{}{ (*ProjectMembershipReference_UserEmail)(nil), (*ProjectMembershipReference_GroupReference)(nil), } - file_controlplane_v1_project_proto_msgTypes[12].OneofWrappers = []interface{}{} + file_controlplane_v1_project_proto_msgTypes[11].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_project_proto_rawDesc, - NumEnums: 1, - NumMessages: 13, + NumEnums: 0, + NumMessages: 12, NumExtensions: 0, NumServices: 1, }, GoTypes: file_controlplane_v1_project_proto_goTypes, DependencyIndexes: file_controlplane_v1_project_proto_depIdxs, - EnumInfos: file_controlplane_v1_project_proto_enumTypes, MessageInfos: file_controlplane_v1_project_proto_msgTypes, }.Build() File_controlplane_v1_project_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/project.proto b/app/controlplane/api/controlplane/v1/project.proto index b4248d2d9..2b9ec0d4b 100644 --- a/app/controlplane/api/controlplane/v1/project.proto +++ b/app/controlplane/api/controlplane/v1/project.proto @@ -51,23 +51,6 @@ message ProjectServiceListMembersResponse { OffsetPaginationResponse pagination = 2; } -// ProjectMember represents an user or group who is a member of a project -message ProjectMember { - // Subject can be either a user or a group - oneof subject { - // The user who is a member of the project - User user = 1; - // The group who is a member of the project - Group group = 2; - } - // The role of the user in the project - ProjectMemberRole role = 3; - // Timestamp when the project membership was created - google.protobuf.Timestamp created_at = 4; - // Timestamp when the project membership was last modified - google.protobuf.Timestamp updated_at = 5; -} - // ProjectServiceAddMemberRequest contains the information needed to add a user to a project message ProjectServiceAddMemberRequest { // IdentityReference is used to specify the project by either its ID or name @@ -108,16 +91,6 @@ message ProjectMembershipReference { } } -// ProjectMemberRole defines the roles a member can have in a project -enum ProjectMemberRole { - // Default role for a project member - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; - // Admin role for a project member - PROJECT_MEMBER_ROLE_ADMIN = 1; - // Viewer role for a project member - PROJECT_MEMBER_ROLE_VIEWER = 2; -} - // ProjectServiceUpdateMemberRoleRequest contains the information needed to update a member's role in a project message ProjectServiceUpdateMemberRoleRequest { // IdentityReference is used to specify the project by either its ID or name diff --git a/app/controlplane/api/controlplane/v1/shared_message.pb.go b/app/controlplane/api/controlplane/v1/shared_message.pb.go index 8f5cedb7c..b9efa67b3 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.pb.go +++ b/app/controlplane/api/controlplane/v1/shared_message.pb.go @@ -25,6 +25,7 @@ import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -36,6 +37,59 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// ProjectMemberRole defines the roles a member can have in a project +type ProjectMemberRole int32 + +const ( + // Default role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 + // Admin role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 + // Viewer role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 +) + +// Enum value maps for ProjectMemberRole. +var ( + ProjectMemberRole_name = map[int32]string{ + 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", + 1: "PROJECT_MEMBER_ROLE_ADMIN", + 2: "PROJECT_MEMBER_ROLE_VIEWER", + } + ProjectMemberRole_value = map[string]int32{ + "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, + "PROJECT_MEMBER_ROLE_ADMIN": 1, + "PROJECT_MEMBER_ROLE_VIEWER": 2, + } +) + +func (x ProjectMemberRole) Enum() *ProjectMemberRole { + p := new(ProjectMemberRole) + *p = x + return p +} + +func (x ProjectMemberRole) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { + return file_controlplane_v1_shared_message_proto_enumTypes[0].Descriptor() +} + +func (ProjectMemberRole) Type() protoreflect.EnumType { + return &file_controlplane_v1_shared_message_proto_enumTypes[0] +} + +func (x ProjectMemberRole) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProjectMemberRole.Descriptor instead. +func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { + return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{0} +} + // IdentityReference represents a reference to an identity in the system. type IdentityReference struct { state protoimpl.MessageState @@ -94,6 +148,231 @@ func (x *IdentityReference) GetName() string { return "" } +// Group represents a collection of users with shared access to resources +type Group struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier for the group + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Human-readable name of the group + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Additional details about the group's purpose + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // UUID of the organization that this group belongs to + OrganizationId string `protobuf:"bytes,4,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` + // Count of members in the group + MemberCount int32 `protobuf:"varint,5,opt,name=member_count,json=memberCount,proto3" json:"member_count,omitempty"` + // Timestamp when the group was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Timestamp when the group was last modified + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *Group) Reset() { + *x = Group{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_shared_message_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Group) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group) ProtoMessage() {} + +func (x *Group) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_shared_message_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group.ProtoReflect.Descriptor instead. +func (*Group) Descriptor() ([]byte, []int) { + return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{1} +} + +func (x *Group) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Group) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Group) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Group) GetOrganizationId() string { + if x != nil { + return x.OrganizationId + } + return "" +} + +func (x *Group) GetMemberCount() int32 { + if x != nil { + return x.MemberCount + } + return 0 +} + +func (x *Group) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Group) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// ProjectMember represents an user or group who is a member of a project +type ProjectMember struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Subject can be either a user or a group + // + // Types that are assignable to Subject: + // + // *ProjectMember_User + // *ProjectMember_Group + Subject isProjectMember_Subject `protobuf_oneof:"subject"` + // The role of the user in the project + Role ProjectMemberRole `protobuf:"varint,3,opt,name=role,proto3,enum=controlplane.v1.ProjectMemberRole" json:"role,omitempty"` + // Timestamp when the project membership was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Timestamp when the project membership was last modified + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + // The ID of latest project version this member is associated with + LatestProjectVersionId string `protobuf:"bytes,6,opt,name=latest_project_version_id,json=latestProjectVersionId,proto3" json:"latest_project_version_id,omitempty"` +} + +func (x *ProjectMember) Reset() { + *x = ProjectMember{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_shared_message_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProjectMember) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProjectMember) ProtoMessage() {} + +func (x *ProjectMember) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_shared_message_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProjectMember.ProtoReflect.Descriptor instead. +func (*ProjectMember) Descriptor() ([]byte, []int) { + return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{2} +} + +func (m *ProjectMember) GetSubject() isProjectMember_Subject { + if m != nil { + return m.Subject + } + return nil +} + +func (x *ProjectMember) GetUser() *User { + if x, ok := x.GetSubject().(*ProjectMember_User); ok { + return x.User + } + return nil +} + +func (x *ProjectMember) GetGroup() *Group { + if x, ok := x.GetSubject().(*ProjectMember_Group); ok { + return x.Group + } + return nil +} + +func (x *ProjectMember) GetRole() ProjectMemberRole { + if x != nil { + return x.Role + } + return ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED +} + +func (x *ProjectMember) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ProjectMember) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *ProjectMember) GetLatestProjectVersionId() string { + if x != nil { + return x.LatestProjectVersionId + } + return "" +} + +type isProjectMember_Subject interface { + isProjectMember_Subject() +} + +type ProjectMember_User struct { + // The user who is a member of the project + User *User `protobuf:"bytes,1,opt,name=user,proto3,oneof"` +} + +type ProjectMember_Group struct { + // The group who is a member of the project + Group *Group `protobuf:"bytes,2,opt,name=group,proto3,oneof"` +} + +func (*ProjectMember_User) isProjectMember_Subject() {} + +func (*ProjectMember_Group) isProjectMember_Subject() {} + var File_controlplane_v1_shared_message_proto protoreflect.FileDescriptor var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ @@ -102,29 +381,80 @@ var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd0, 0x01, 0x01, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xd0, - 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, - 0x01, 0x3a, 0x9b, 0x01, 0xba, 0x48, 0x97, 0x01, 0x1a, 0x94, 0x01, 0x0a, 0x13, 0x69, 0x64, 0x5f, - 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x12, 0x31, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x64, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, - 0x74, 0x68, 0x2e, 0x1a, 0x4a, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, - 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, - 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, - 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, - 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, - 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, + 0x02, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd0, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, + 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xd0, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, + 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x3a, 0x9b, 0x01, 0xba, 0x48, + 0x97, 0x01, 0x1a, 0x94, 0x01, 0x0a, 0x13, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x31, 0x65, 0x69, 0x74, 0x68, + 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2c, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x2e, 0x1a, 0x4a, 0x21, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, + 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, + 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8f, 0x02, 0x0a, 0x05, 0x47, 0x72, + 0x6f, 0x75, 0x70, 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, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 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, 0xe0, 0x02, 0x0a, 0x0d, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2b, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x05, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x19, 0x6c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x6c, 0x61, 0x74, + 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2a, 0x77, + 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, + 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, + 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x4a, + 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, + 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, 0x45, + 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x56, + 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, + 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, + 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, + 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -139,16 +469,29 @@ func file_controlplane_v1_shared_message_proto_rawDescGZIP() []byte { return file_controlplane_v1_shared_message_proto_rawDescData } -var file_controlplane_v1_shared_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_controlplane_v1_shared_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_controlplane_v1_shared_message_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_controlplane_v1_shared_message_proto_goTypes = []interface{}{ - (*IdentityReference)(nil), // 0: controlplane.v1.IdentityReference + (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole + (*IdentityReference)(nil), // 1: controlplane.v1.IdentityReference + (*Group)(nil), // 2: controlplane.v1.Group + (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp + (*User)(nil), // 5: controlplane.v1.User } var file_controlplane_v1_shared_message_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 4, // 0: controlplane.v1.Group.created_at:type_name -> google.protobuf.Timestamp + 4, // 1: controlplane.v1.Group.updated_at:type_name -> google.protobuf.Timestamp + 5, // 2: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User + 2, // 3: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group + 0, // 4: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole + 4, // 5: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp + 4, // 6: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_controlplane_v1_shared_message_proto_init() } @@ -156,6 +499,7 @@ func file_controlplane_v1_shared_message_proto_init() { if File_controlplane_v1_shared_message_proto != nil { return } + file_controlplane_v1_response_messages_proto_init() if !protoimpl.UnsafeEnabled { file_controlplane_v1_shared_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IdentityReference); i { @@ -169,20 +513,49 @@ func file_controlplane_v1_shared_message_proto_init() { return nil } } + file_controlplane_v1_shared_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Group); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controlplane_v1_shared_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProjectMember); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_controlplane_v1_shared_message_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_controlplane_v1_shared_message_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*ProjectMember_User)(nil), + (*ProjectMember_Group)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_shared_message_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, + NumEnums: 1, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, GoTypes: file_controlplane_v1_shared_message_proto_goTypes, DependencyIndexes: file_controlplane_v1_shared_message_proto_depIdxs, + EnumInfos: file_controlplane_v1_shared_message_proto_enumTypes, MessageInfos: file_controlplane_v1_shared_message_proto_msgTypes, }.Build() File_controlplane_v1_shared_message_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/shared_message.proto b/app/controlplane/api/controlplane/v1/shared_message.proto index a7df1113d..28fe60865 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.proto +++ b/app/controlplane/api/controlplane/v1/shared_message.proto @@ -18,6 +18,8 @@ syntax = "proto3"; package controlplane.v1; import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; +import "controlplane/v1/response_messages.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; @@ -41,3 +43,50 @@ message IdentityReference { message: "either id or name must be provided, but not both." }; } + +// Group represents a collection of users with shared access to resources +message Group { + // Unique identifier for the group + string id = 1; + // Human-readable name of the group + string name = 2; + // Additional details about the group's purpose + string description = 3; + // UUID of the organization that this group belongs to + string organization_id = 4; + // Count of members in the group + int32 member_count = 5; + // Timestamp when the group was created + google.protobuf.Timestamp created_at = 6; + // Timestamp when the group was last modified + google.protobuf.Timestamp updated_at = 7; +} + +// ProjectMember represents an user or group who is a member of a project +message ProjectMember { + // Subject can be either a user or a group + oneof subject { + // The user who is a member of the project + User user = 1; + // The group who is a member of the project + Group group = 2; + } + // The role of the user in the project + ProjectMemberRole role = 3; + // Timestamp when the project membership was created + google.protobuf.Timestamp created_at = 4; + // Timestamp when the project membership was last modified + google.protobuf.Timestamp updated_at = 5; + // The ID of latest project version this member is associated with + string latest_project_version_id = 6; +} + +// ProjectMemberRole defines the roles a member can have in a project +enum ProjectMemberRole { + // Default role for a project member + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; + // Admin role for a project member + PROJECT_MEMBER_ROLE_ADMIN = 1; + // Viewer role for a project member + PROJECT_MEMBER_ROLE_VIEWER = 2; +} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts index cb445ae8f..576a0f692 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts @@ -5,7 +5,7 @@ import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { IdentityReference } from "./shared_message"; +import { Group, IdentityReference, ProjectMember } from "./shared_message"; export const protobufPackage = "controlplane.v1"; @@ -167,24 +167,6 @@ export interface PendingGroupInvitation { invitationId: string; } -/** Group represents a collection of users with shared access to resources */ -export interface Group { - /** Unique identifier for the group */ - id: string; - /** Human-readable name of the group */ - name: string; - /** Additional details about the group's purpose */ - description: string; - /** UUID of the organization that this group belongs to */ - organizationId: string; - /** Count of members in the group */ - memberCount: number; - /** Timestamp when the group was created */ - createdAt?: Date; - /** Timestamp when the group was last modified */ - updatedAt?: Date; -} - /** GroupMember represents a user's membership within a group with their role information */ export interface GroupMember { /** The user who is a member of the group */ @@ -211,6 +193,22 @@ export interface GroupServiceUpdateMemberMaintainerStatusRequest { export interface GroupServiceUpdateMemberMaintainerStatusResponse { } +/** GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group */ +export interface GroupServiceListProjectsRequest { + /** IdentityReference is used to specify the group by either its ID or name */ + groupReference?: IdentityReference; + /** Pagination parameters to limit and offset results */ + pagination?: OffsetPaginationRequest; +} + +/** GroupServiceListProjectsResponse contains a paginated list of projects for a group */ +export interface GroupServiceListProjectsResponse { + /** List of projects memberships matching the request criteria */ + projectMembers: ProjectMember[]; + /** Pagination information for the response */ + pagination?: OffsetPaginationResponse; +} + function createBaseGroupServiceCreateRequest(): GroupServiceCreateRequest { return { name: "", description: "" }; } @@ -1585,150 +1583,6 @@ export const PendingGroupInvitation = { }, }; -function createBaseGroup(): Group { - return { - id: "", - name: "", - description: "", - organizationId: "", - memberCount: 0, - createdAt: undefined, - updatedAt: undefined, - }; -} - -export const Group = { - encode(message: Group, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - if (message.description !== "") { - writer.uint32(26).string(message.description); - } - if (message.organizationId !== "") { - writer.uint32(34).string(message.organizationId); - } - if (message.memberCount !== 0) { - writer.uint32(40).int32(message.memberCount); - } - if (message.createdAt !== undefined) { - Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(50).fork()).ldelim(); - } - if (message.updatedAt !== undefined) { - Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(58).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): Group { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGroup(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.id = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.name = reader.string(); - continue; - case 3: - if (tag !== 26) { - break; - } - - message.description = reader.string(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.organizationId = reader.string(); - continue; - case 5: - if (tag !== 40) { - break; - } - - message.memberCount = reader.int32(); - continue; - case 6: - if (tag !== 50) { - break; - } - - message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - case 7: - if (tag !== 58) { - break; - } - - message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): Group { - return { - id: isSet(object.id) ? String(object.id) : "", - name: isSet(object.name) ? String(object.name) : "", - description: isSet(object.description) ? String(object.description) : "", - organizationId: isSet(object.organizationId) ? String(object.organizationId) : "", - memberCount: isSet(object.memberCount) ? Number(object.memberCount) : 0, - createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, - updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, - }; - }, - - toJSON(message: Group): unknown { - const obj: any = {}; - message.id !== undefined && (obj.id = message.id); - message.name !== undefined && (obj.name = message.name); - message.description !== undefined && (obj.description = message.description); - message.organizationId !== undefined && (obj.organizationId = message.organizationId); - message.memberCount !== undefined && (obj.memberCount = Math.round(message.memberCount)); - message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); - message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); - return obj; - }, - - create, I>>(base?: I): Group { - return Group.fromPartial(base ?? {}); - }, - - fromPartial, I>>(object: I): Group { - const message = createBaseGroup(); - message.id = object.id ?? ""; - message.name = object.name ?? ""; - message.description = object.description ?? ""; - message.organizationId = object.organizationId ?? ""; - message.memberCount = object.memberCount ?? 0; - message.createdAt = object.createdAt ?? undefined; - message.updatedAt = object.updatedAt ?? undefined; - return message; - }, -}; - function createBaseGroupMember(): GroupMember { return { user: undefined, isMaintainer: false, createdAt: undefined, updatedAt: undefined }; } @@ -1968,6 +1822,169 @@ export const GroupServiceUpdateMemberMaintainerStatusResponse = { }, }; +function createBaseGroupServiceListProjectsRequest(): GroupServiceListProjectsRequest { + return { groupReference: undefined, pagination: undefined }; +} + +export const GroupServiceListProjectsRequest = { + encode(message: GroupServiceListProjectsRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.groupReference !== undefined) { + IdentityReference.encode(message.groupReference, writer.uint32(10).fork()).ldelim(); + } + if (message.pagination !== undefined) { + OffsetPaginationRequest.encode(message.pagination, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GroupServiceListProjectsRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGroupServiceListProjectsRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.groupReference = IdentityReference.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.pagination = OffsetPaginationRequest.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): GroupServiceListProjectsRequest { + return { + groupReference: isSet(object.groupReference) ? IdentityReference.fromJSON(object.groupReference) : undefined, + pagination: isSet(object.pagination) ? OffsetPaginationRequest.fromJSON(object.pagination) : undefined, + }; + }, + + toJSON(message: GroupServiceListProjectsRequest): unknown { + const obj: any = {}; + message.groupReference !== undefined && + (obj.groupReference = message.groupReference ? IdentityReference.toJSON(message.groupReference) : undefined); + message.pagination !== undefined && + (obj.pagination = message.pagination ? OffsetPaginationRequest.toJSON(message.pagination) : undefined); + return obj; + }, + + create, I>>(base?: I): GroupServiceListProjectsRequest { + return GroupServiceListProjectsRequest.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): GroupServiceListProjectsRequest { + const message = createBaseGroupServiceListProjectsRequest(); + message.groupReference = (object.groupReference !== undefined && object.groupReference !== null) + ? IdentityReference.fromPartial(object.groupReference) + : undefined; + message.pagination = (object.pagination !== undefined && object.pagination !== null) + ? OffsetPaginationRequest.fromPartial(object.pagination) + : undefined; + return message; + }, +}; + +function createBaseGroupServiceListProjectsResponse(): GroupServiceListProjectsResponse { + return { projectMembers: [], pagination: undefined }; +} + +export const GroupServiceListProjectsResponse = { + encode(message: GroupServiceListProjectsResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.projectMembers) { + ProjectMember.encode(v!, writer.uint32(10).fork()).ldelim(); + } + if (message.pagination !== undefined) { + OffsetPaginationResponse.encode(message.pagination, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GroupServiceListProjectsResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGroupServiceListProjectsResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.projectMembers.push(ProjectMember.decode(reader, reader.uint32())); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.pagination = OffsetPaginationResponse.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): GroupServiceListProjectsResponse { + return { + projectMembers: Array.isArray(object?.projectMembers) + ? object.projectMembers.map((e: any) => ProjectMember.fromJSON(e)) + : [], + pagination: isSet(object.pagination) ? OffsetPaginationResponse.fromJSON(object.pagination) : undefined, + }; + }, + + toJSON(message: GroupServiceListProjectsResponse): unknown { + const obj: any = {}; + if (message.projectMembers) { + obj.projectMembers = message.projectMembers.map((e) => e ? ProjectMember.toJSON(e) : undefined); + } else { + obj.projectMembers = []; + } + message.pagination !== undefined && + (obj.pagination = message.pagination ? OffsetPaginationResponse.toJSON(message.pagination) : undefined); + return obj; + }, + + create, I>>( + base?: I, + ): GroupServiceListProjectsResponse { + return GroupServiceListProjectsResponse.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): GroupServiceListProjectsResponse { + const message = createBaseGroupServiceListProjectsResponse(); + message.projectMembers = object.projectMembers?.map((e) => ProjectMember.fromPartial(e)) || []; + message.pagination = (object.pagination !== undefined && object.pagination !== null) + ? OffsetPaginationResponse.fromPartial(object.pagination) + : undefined; + return message; + }, +}; + /** GroupService provides operations for managing groups within the system */ export interface GroupService { /** Create creates a new group with the specified name and description */ @@ -2014,6 +2031,11 @@ export interface GroupService { request: DeepPartial, metadata?: grpc.Metadata, ): Promise; + /** ListProjects retrieves a paginated list of projects the group is a member of */ + ListProjects( + request: DeepPartial, + metadata?: grpc.Metadata, + ): Promise; } export class GroupServiceClientImpl implements GroupService { @@ -2031,6 +2053,7 @@ export class GroupServiceClientImpl implements GroupService { this.RemoveMember = this.RemoveMember.bind(this); this.UpdateMemberMaintainerStatus = this.UpdateMemberMaintainerStatus.bind(this); this.ListPendingInvitations = this.ListPendingInvitations.bind(this); + this.ListProjects = this.ListProjects.bind(this); } Create( @@ -2104,6 +2127,13 @@ export class GroupServiceClientImpl implements GroupService { metadata, ); } + + ListProjects( + request: DeepPartial, + metadata?: grpc.Metadata, + ): Promise { + return this.rpc.unary(GroupServiceListProjectsDesc, GroupServiceListProjectsRequest.fromPartial(request), metadata); + } } export const GroupServiceDesc = { serviceName: "controlplane.v1.GroupService" }; @@ -2338,6 +2368,29 @@ export const GroupServiceListPendingInvitationsDesc: UnaryMethodDefinitionish = } as any, }; +export const GroupServiceListProjectsDesc: UnaryMethodDefinitionish = { + methodName: "ListProjects", + service: GroupServiceDesc, + requestStream: false, + responseStream: false, + requestType: { + serializeBinary() { + return GroupServiceListProjectsRequest.encode(this).finish(); + }, + } as any, + responseType: { + deserializeBinary(data: Uint8Array) { + const value = GroupServiceListProjectsResponse.decode(data); + return { + ...value, + toObject() { + return value; + }, + }; + }, + } as any, +}; + interface UnaryMethodDefinitionishR extends grpc.UnaryMethodDefinition { requestStream: any; responseStream: any; diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts index 2e4341abb..d7d04f376 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts @@ -3,56 +3,18 @@ import { grpc } from "@improbable-eng/grpc-web"; import { BrowserHeaders } from "browser-headers"; import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; -import { Group } from "./group"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { IdentityReference } from "./shared_message"; +import { + IdentityReference, + ProjectMember, + ProjectMemberRole, + projectMemberRoleFromJSON, + projectMemberRoleToJSON, +} from "./shared_message"; export const protobufPackage = "controlplane.v1"; -/** ProjectMemberRole defines the roles a member can have in a project */ -export enum ProjectMemberRole { - /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, - /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ - PROJECT_MEMBER_ROLE_ADMIN = 1, - /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ - PROJECT_MEMBER_ROLE_VIEWER = 2, - UNRECOGNIZED = -1, -} - -export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { - switch (object) { - case 0: - case "PROJECT_MEMBER_ROLE_UNSPECIFIED": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; - case 1: - case "PROJECT_MEMBER_ROLE_ADMIN": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; - case 2: - case "PROJECT_MEMBER_ROLE_VIEWER": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; - case -1: - case "UNRECOGNIZED": - default: - return ProjectMemberRole.UNRECOGNIZED; - } -} - -export function projectMemberRoleToJSON(object: ProjectMemberRole): string { - switch (object) { - case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: - return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: - return "PROJECT_MEMBER_ROLE_ADMIN"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: - return "PROJECT_MEMBER_ROLE_VIEWER"; - case ProjectMemberRole.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - /** ProjectServiceListMembersRequest contains the information needed to list members of a project */ export interface ProjectServiceListMembersRequest { /** IdentityReference is used to specify the project by either its ID or name */ @@ -69,24 +31,6 @@ export interface ProjectServiceListMembersResponse { pagination?: OffsetPaginationResponse; } -/** ProjectMember represents an user or group who is a member of a project */ -export interface ProjectMember { - /** The user who is a member of the project */ - user?: - | User - | undefined; - /** The group who is a member of the project */ - group?: - | Group - | undefined; - /** The role of the user in the project */ - role: ProjectMemberRole; - /** Timestamp when the project membership was created */ - createdAt?: Date; - /** Timestamp when the project membership was last modified */ - updatedAt?: Date; -} - /** ProjectServiceAddMemberRequest contains the information needed to add a user to a project */ export interface ProjectServiceAddMemberRequest { /** IdentityReference is used to specify the project by either its ID or name */ @@ -332,116 +276,6 @@ export const ProjectServiceListMembersResponse = { }, }; -function createBaseProjectMember(): ProjectMember { - return { user: undefined, group: undefined, role: 0, createdAt: undefined, updatedAt: undefined }; -} - -export const ProjectMember = { - encode(message: ProjectMember, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.user !== undefined) { - User.encode(message.user, writer.uint32(10).fork()).ldelim(); - } - if (message.group !== undefined) { - Group.encode(message.group, writer.uint32(18).fork()).ldelim(); - } - if (message.role !== 0) { - writer.uint32(24).int32(message.role); - } - if (message.createdAt !== undefined) { - Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).ldelim(); - } - if (message.updatedAt !== undefined) { - Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(42).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectMember { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectMember(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.user = User.decode(reader, reader.uint32()); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.group = Group.decode(reader, reader.uint32()); - continue; - case 3: - if (tag !== 24) { - break; - } - - message.role = reader.int32() as any; - continue; - case 4: - if (tag !== 34) { - break; - } - - message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectMember { - return { - user: isSet(object.user) ? User.fromJSON(object.user) : undefined, - group: isSet(object.group) ? Group.fromJSON(object.group) : undefined, - role: isSet(object.role) ? projectMemberRoleFromJSON(object.role) : 0, - createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, - updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, - }; - }, - - toJSON(message: ProjectMember): unknown { - const obj: any = {}; - message.user !== undefined && (obj.user = message.user ? User.toJSON(message.user) : undefined); - message.group !== undefined && (obj.group = message.group ? Group.toJSON(message.group) : undefined); - message.role !== undefined && (obj.role = projectMemberRoleToJSON(message.role)); - message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); - message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); - return obj; - }, - - create, I>>(base?: I): ProjectMember { - return ProjectMember.fromPartial(base ?? {}); - }, - - fromPartial, I>>(object: I): ProjectMember { - const message = createBaseProjectMember(); - message.user = (object.user !== undefined && object.user !== null) ? User.fromPartial(object.user) : undefined; - message.group = (object.group !== undefined && object.group !== null) ? Group.fromPartial(object.group) : undefined; - message.role = object.role ?? 0; - message.createdAt = object.createdAt ?? undefined; - message.updatedAt = object.updatedAt ?? undefined; - return message; - }, -}; - function createBaseProjectServiceAddMemberRequest(): ProjectServiceAddMemberRequest { return { projectReference: undefined, memberReference: undefined, role: 0 }; } diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts index f8ccfe269..a882d6ac3 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts @@ -1,8 +1,53 @@ /* eslint-disable */ import _m0 from "protobufjs/minimal"; +import { Timestamp } from "../../google/protobuf/timestamp"; +import { User } from "./response_messages"; export const protobufPackage = "controlplane.v1"; +/** ProjectMemberRole defines the roles a member can have in a project */ +export enum ProjectMemberRole { + /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, + /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ + PROJECT_MEMBER_ROLE_ADMIN = 1, + /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ + PROJECT_MEMBER_ROLE_VIEWER = 2, + UNRECOGNIZED = -1, +} + +export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { + switch (object) { + case 0: + case "PROJECT_MEMBER_ROLE_UNSPECIFIED": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; + case 1: + case "PROJECT_MEMBER_ROLE_ADMIN": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; + case 2: + case "PROJECT_MEMBER_ROLE_VIEWER": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; + case -1: + case "UNRECOGNIZED": + default: + return ProjectMemberRole.UNRECOGNIZED; + } +} + +export function projectMemberRoleToJSON(object: ProjectMemberRole): string { + switch (object) { + case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: + return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: + return "PROJECT_MEMBER_ROLE_ADMIN"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: + return "PROJECT_MEMBER_ROLE_VIEWER"; + case ProjectMemberRole.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + /** IdentityReference represents a reference to an identity in the system. */ export interface IdentityReference { /** ID is optional, but if provided, it must be a valid UUID. */ @@ -13,6 +58,44 @@ export interface IdentityReference { name?: string | undefined; } +/** Group represents a collection of users with shared access to resources */ +export interface Group { + /** Unique identifier for the group */ + id: string; + /** Human-readable name of the group */ + name: string; + /** Additional details about the group's purpose */ + description: string; + /** UUID of the organization that this group belongs to */ + organizationId: string; + /** Count of members in the group */ + memberCount: number; + /** Timestamp when the group was created */ + createdAt?: Date; + /** Timestamp when the group was last modified */ + updatedAt?: Date; +} + +/** ProjectMember represents an user or group who is a member of a project */ +export interface ProjectMember { + /** The user who is a member of the project */ + user?: + | User + | undefined; + /** The group who is a member of the project */ + group?: + | Group + | undefined; + /** The role of the user in the project */ + role: ProjectMemberRole; + /** Timestamp when the project membership was created */ + createdAt?: Date; + /** Timestamp when the project membership was last modified */ + updatedAt?: Date; + /** The ID of latest project version this member is associated with */ + latestProjectVersionId: string; +} + function createBaseIdentityReference(): IdentityReference { return { id: undefined, name: undefined }; } @@ -84,6 +167,280 @@ export const IdentityReference = { }, }; +function createBaseGroup(): Group { + return { + id: "", + name: "", + description: "", + organizationId: "", + memberCount: 0, + createdAt: undefined, + updatedAt: undefined, + }; +} + +export const Group = { + encode(message: Group, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.description !== "") { + writer.uint32(26).string(message.description); + } + if (message.organizationId !== "") { + writer.uint32(34).string(message.organizationId); + } + if (message.memberCount !== 0) { + writer.uint32(40).int32(message.memberCount); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(50).fork()).ldelim(); + } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Group { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGroup(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.description = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.organizationId = reader.string(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.memberCount = reader.int32(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Group { + return { + id: isSet(object.id) ? String(object.id) : "", + name: isSet(object.name) ? String(object.name) : "", + description: isSet(object.description) ? String(object.description) : "", + organizationId: isSet(object.organizationId) ? String(object.organizationId) : "", + memberCount: isSet(object.memberCount) ? Number(object.memberCount) : 0, + createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, + }; + }, + + toJSON(message: Group): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.name !== undefined && (obj.name = message.name); + message.description !== undefined && (obj.description = message.description); + message.organizationId !== undefined && (obj.organizationId = message.organizationId); + message.memberCount !== undefined && (obj.memberCount = Math.round(message.memberCount)); + message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); + return obj; + }, + + create, I>>(base?: I): Group { + return Group.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): Group { + const message = createBaseGroup(); + message.id = object.id ?? ""; + message.name = object.name ?? ""; + message.description = object.description ?? ""; + message.organizationId = object.organizationId ?? ""; + message.memberCount = object.memberCount ?? 0; + message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; + return message; + }, +}; + +function createBaseProjectMember(): ProjectMember { + return { + user: undefined, + group: undefined, + role: 0, + createdAt: undefined, + updatedAt: undefined, + latestProjectVersionId: "", + }; +} + +export const ProjectMember = { + encode(message: ProjectMember, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.user !== undefined) { + User.encode(message.user, writer.uint32(10).fork()).ldelim(); + } + if (message.group !== undefined) { + Group.encode(message.group, writer.uint32(18).fork()).ldelim(); + } + if (message.role !== 0) { + writer.uint32(24).int32(message.role); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).ldelim(); + } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(42).fork()).ldelim(); + } + if (message.latestProjectVersionId !== "") { + writer.uint32(50).string(message.latestProjectVersionId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ProjectMember { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseProjectMember(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.user = User.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.group = Group.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.role = reader.int32() as any; + continue; + case 4: + if (tag !== 34) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.latestProjectVersionId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): ProjectMember { + return { + user: isSet(object.user) ? User.fromJSON(object.user) : undefined, + group: isSet(object.group) ? Group.fromJSON(object.group) : undefined, + role: isSet(object.role) ? projectMemberRoleFromJSON(object.role) : 0, + createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, + latestProjectVersionId: isSet(object.latestProjectVersionId) ? String(object.latestProjectVersionId) : "", + }; + }, + + toJSON(message: ProjectMember): unknown { + const obj: any = {}; + message.user !== undefined && (obj.user = message.user ? User.toJSON(message.user) : undefined); + message.group !== undefined && (obj.group = message.group ? Group.toJSON(message.group) : undefined); + message.role !== undefined && (obj.role = projectMemberRoleToJSON(message.role)); + message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); + message.latestProjectVersionId !== undefined && (obj.latestProjectVersionId = message.latestProjectVersionId); + return obj; + }, + + create, I>>(base?: I): ProjectMember { + return ProjectMember.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): ProjectMember { + const message = createBaseProjectMember(); + message.user = (object.user !== undefined && object.user !== null) ? User.fromPartial(object.user) : undefined; + message.group = (object.group !== undefined && object.group !== null) ? Group.fromPartial(object.group) : undefined; + message.role = object.role ?? 0; + message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; + message.latestProjectVersionId = object.latestProjectVersionId ?? ""; + return message; + }, +}; + type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; export type DeepPartial = T extends Builtin ? T @@ -95,6 +452,28 @@ type KeysOfUnion = T extends T ? keyof T : never; export type Exact = P extends Builtin ? P : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; +function toTimestamp(date: Date): Timestamp { + const seconds = date.getTime() / 1_000; + const nanos = (date.getTime() % 1_000) * 1_000_000; + return { seconds, nanos }; +} + +function fromTimestamp(t: Timestamp): Date { + let millis = (t.seconds || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new Date(millis); +} + +function fromJsonTimestamp(o: any): Date { + if (o instanceof Date) { + return o; + } else if (typeof o === "string") { + return new Date(o); + } else { + return fromTimestamp(Timestamp.fromJSON(o)); + } +} + function isSet(value: any): boolean { return value !== null && value !== undefined; } diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.jsonschema.json new file mode 100644 index 000000000..f38976452 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.jsonschema.json @@ -0,0 +1,27 @@ +{ + "$id": "controlplane.v1.GroupServiceListProjectsRequest.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group", + "patternProperties": { + "^(group_reference)$": { + "$ref": "controlplane.v1.IdentityReference.jsonschema.json", + "description": "IdentityReference is used to specify the group by either its ID or name" + } + }, + "properties": { + "groupReference": { + "$ref": "controlplane.v1.IdentityReference.jsonschema.json", + "description": "IdentityReference is used to specify the group by either its ID or name" + }, + "pagination": { + "$ref": "controlplane.v1.OffsetPaginationRequest.jsonschema.json", + "description": "Pagination parameters to limit and offset results" + } + }, + "required": [ + "group_reference" + ], + "title": "Group Service List Projects Request", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.schema.json new file mode 100644 index 000000000..efe11ae28 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsRequest.schema.json @@ -0,0 +1,27 @@ +{ + "$id": "controlplane.v1.GroupServiceListProjectsRequest.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group", + "patternProperties": { + "^(groupReference)$": { + "$ref": "controlplane.v1.IdentityReference.schema.json", + "description": "IdentityReference is used to specify the group by either its ID or name" + } + }, + "properties": { + "group_reference": { + "$ref": "controlplane.v1.IdentityReference.schema.json", + "description": "IdentityReference is used to specify the group by either its ID or name" + }, + "pagination": { + "$ref": "controlplane.v1.OffsetPaginationRequest.schema.json", + "description": "Pagination parameters to limit and offset results" + } + }, + "required": [ + "group_reference" + ], + "title": "Group Service List Projects Request", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json new file mode 100644 index 000000000..0bfd2bb0c --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json @@ -0,0 +1,30 @@ +{ + "$id": "controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "GroupServiceListProjectsResponse contains a paginated list of projects for a group", + "patternProperties": { + "^(project_members)$": { + "description": "List of projects memberships matching the request criteria", + "items": { + "$ref": "controlplane.v1.ProjectMember.jsonschema.json" + }, + "type": "array" + } + }, + "properties": { + "pagination": { + "$ref": "controlplane.v1.OffsetPaginationResponse.jsonschema.json", + "description": "Pagination information for the response" + }, + "projectMembers": { + "description": "List of projects memberships matching the request criteria", + "items": { + "$ref": "controlplane.v1.ProjectMember.jsonschema.json" + }, + "type": "array" + } + }, + "title": "Group Service List Projects Response", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json new file mode 100644 index 000000000..5145f2702 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json @@ -0,0 +1,30 @@ +{ + "$id": "controlplane.v1.GroupServiceListProjectsResponse.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "GroupServiceListProjectsResponse contains a paginated list of projects for a group", + "patternProperties": { + "^(projectMembers)$": { + "description": "List of projects memberships matching the request criteria", + "items": { + "$ref": "controlplane.v1.ProjectMember.schema.json" + }, + "type": "array" + } + }, + "properties": { + "pagination": { + "$ref": "controlplane.v1.OffsetPaginationResponse.schema.json", + "description": "Pagination information for the response" + }, + "project_members": { + "description": "List of projects memberships matching the request criteria", + "items": { + "$ref": "controlplane.v1.ProjectMember.schema.json" + }, + "type": "array" + } + }, + "title": "Group Service List Projects Response", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.jsonschema.json new file mode 100644 index 000000000..ead3f6544 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.jsonschema.json @@ -0,0 +1,60 @@ +{ + "$id": "controlplane.v1.Project.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "Project represents a project within the system", + "patternProperties": { + "^(created_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was created" + }, + "^(member_count)$": { + "description": "Count of members in the project", + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + }, + "^(organization_id)$": { + "description": "UUID of the organization that this project belongs to", + "type": "string" + }, + "^(updated_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was last modified" + } + }, + "properties": { + "createdAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was created" + }, + "description": { + "description": "Additional details about the project's purpose", + "type": "string" + }, + "id": { + "description": "Unique identifier for the project", + "type": "string" + }, + "memberCount": { + "description": "Count of members in the project", + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + }, + "name": { + "description": "Human-readable name of the project", + "type": "string" + }, + "organizationId": { + "description": "UUID of the organization that this project belongs to", + "type": "string" + }, + "updatedAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was last modified" + } + }, + "title": "Project", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.schema.json new file mode 100644 index 000000000..8a0902dea --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.Project.schema.json @@ -0,0 +1,60 @@ +{ + "$id": "controlplane.v1.Project.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "Project represents a project within the system", + "patternProperties": { + "^(createdAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was created" + }, + "^(memberCount)$": { + "description": "Count of members in the project", + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + }, + "^(organizationId)$": { + "description": "UUID of the organization that this project belongs to", + "type": "string" + }, + "^(updatedAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was last modified" + } + }, + "properties": { + "created_at": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was created" + }, + "description": { + "description": "Additional details about the project's purpose", + "type": "string" + }, + "id": { + "description": "Unique identifier for the project", + "type": "string" + }, + "member_count": { + "description": "Count of members in the project", + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + }, + "name": { + "description": "Human-readable name of the project", + "type": "string" + }, + "organization_id": { + "description": "UUID of the organization that this project belongs to", + "type": "string" + }, + "updated_at": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was last modified" + } + }, + "title": "Project", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.jsonschema.json index 4e044ac1e..a0fda6b8e 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.jsonschema.json @@ -8,6 +8,10 @@ "$ref": "google.protobuf.Timestamp.jsonschema.json", "description": "Timestamp when the project membership was created" }, + "^(latest_project_version_id)$": { + "description": "The ID of latest project version this member is associated with", + "type": "string" + }, "^(updated_at)$": { "$ref": "google.protobuf.Timestamp.jsonschema.json", "description": "Timestamp when the project membership was last modified" @@ -22,6 +26,10 @@ "$ref": "controlplane.v1.Group.jsonschema.json", "description": "The group who is a member of the project" }, + "latestProjectVersionId": { + "description": "The ID of latest project version this member is associated with", + "type": "string" + }, "role": { "anyOf": [ { diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.schema.json index b3965d425..c8379f59c 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectMember.schema.json @@ -8,6 +8,10 @@ "$ref": "google.protobuf.Timestamp.schema.json", "description": "Timestamp when the project membership was created" }, + "^(latestProjectVersionId)$": { + "description": "The ID of latest project version this member is associated with", + "type": "string" + }, "^(updatedAt)$": { "$ref": "google.protobuf.Timestamp.schema.json", "description": "Timestamp when the project membership was last modified" @@ -22,6 +26,10 @@ "$ref": "controlplane.v1.Group.schema.json", "description": "The group who is a member of the project" }, + "latest_project_version_id": { + "description": "The ID of latest project version this member is associated with", + "type": "string" + }, "role": { "anyOf": [ { diff --git a/app/controlplane/internal/service/group.go b/app/controlplane/internal/service/group.go index 585619a4e..a06860444 100644 --- a/app/controlplane/internal/service/group.go +++ b/app/controlplane/internal/service/group.go @@ -479,6 +479,55 @@ func (g *GroupService) UpdateMemberMaintainerStatus(ctx context.Context, req *pb return &pb.GroupServiceUpdateMemberMaintainerStatusResponse{}, nil } +// ListProjects retrieves a paginated list of projects that a group is a member of. +func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceListProjectsRequest) (*pb.GroupServiceListProjectsResponse, error) { + currentOrg, err := requireCurrentOrg(ctx) + if err != nil { + return nil, err + } + + // Parse orgID + orgUUID, err := uuid.Parse(currentOrg.ID) + if err != nil { + return nil, errors.BadRequest("invalid", "invalid organization ID") + } + + // Parse groupID and groupName from the request + id, name, err := req.GetGroupReference().Parse() + if err != nil { + return nil, errors.BadRequest("invalid", fmt.Sprintf("invalid group reference: %s", err.Error())) + } + + // Initialize the options for getting projects + groupOpts := &biz.IdentityReference{ + ID: id, + Name: name, + } + + // Initialize the pagination options, with default values + paginationOpts, err := initializePaginationOpts(req.GetPagination()) + if err != nil { + return nil, handleUseCaseErr(err, g.log) + } + + // Retrieve the list of project members + projectMembers, count, err := g.groupUseCase.ListProjectsByGroup(ctx, orgUUID, groupOpts, paginationOpts) + if err != nil { + return nil, handleUseCaseErr(err, g.log) + } + + // Convert the projectMembers to protobuf messages + result := make([]*pb.ProjectMember, 0, len(projectMembers)) + for _, project := range projectMembers { + result = append(result, bizProjectMembershipToPb(project)) + } + + return &pb.GroupServiceListProjectsResponse{ + ProjectMembers: result, + Pagination: paginationToPb(count, paginationOpts.Offset(), paginationOpts.Limit()), + }, nil +} + // bizGroupToPb converts a biz.Group to a pb.Group protobuf message. func bizGroupToPb(gr *biz.Group) *pb.Group { base := &pb.Group{ diff --git a/app/controlplane/internal/service/project.go b/app/controlplane/internal/service/project.go index 0ac18fd78..94ed6ebf3 100644 --- a/app/controlplane/internal/service/project.go +++ b/app/controlplane/internal/service/project.go @@ -410,9 +410,14 @@ func bizProjectMembershipToPb(m *biz.ProjectMembership) *pb.ProjectMember { } } + if m.LatestProjectVersionID != nil { + pbMember.LatestProjectVersionId = m.LatestProjectVersionID.String() + } + if m.CreatedAt != nil { pbMember.CreatedAt = timestamppb.New(*m.CreatedAt) } + if m.UpdatedAt != nil { pbMember.UpdatedAt = timestamppb.New(*m.UpdatedAt) } diff --git a/app/controlplane/pkg/biz/group.go b/app/controlplane/pkg/biz/group.go index 8f5723a9a..87caabb49 100644 --- a/app/controlplane/pkg/biz/group.go +++ b/app/controlplane/pkg/biz/group.go @@ -53,6 +53,8 @@ type GroupRepo interface { UpdateMemberMaintainerStatus(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, userID uuid.UUID, isMaintainer bool) error // ListPendingInvitationsByGroup retrieves a list of pending invitations for a group ListPendingInvitationsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*OrgInvitation, int, error) + // ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. + ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*ProjectMembership, int, error) } // GroupMembership represents a membership of a user in a group. @@ -853,3 +855,36 @@ func (uc *GroupUseCase) ValidateGroupIdentifier(ctx context.Context, orgID uuid. return group.ID, nil } + +// ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. +func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, opts *IdentityReference, paginationOpts *pagination.OffsetPaginationOpts) ([]*ProjectMembership, int, error) { + if opts == nil { + return nil, 0, NewErrValidationStr("options cannot be nil") + } + + if orgID == uuid.Nil { + return nil, 0, NewErrValidationStr("organization ID cannot be empty") + } + + resolvedGroupID, err := uc.ValidateGroupIdentifier(ctx, orgID, opts.ID, opts.Name) + if err != nil { + return nil, 0, err + } + + // Check the group exists + existingGroup, err := uc.groupRepo.FindByOrgAndID(ctx, orgID, resolvedGroupID) + if err != nil { + return nil, 0, fmt.Errorf("failed to find group: %w", err) + } + + if existingGroup == nil { + return nil, 0, NewErrNotFound("group") + } + + pgOpts := pagination.NewDefaultOffsetPaginationOpts() + if paginationOpts != nil { + pgOpts = paginationOpts + } + + return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, pgOpts) +} diff --git a/app/controlplane/pkg/biz/project.go b/app/controlplane/pkg/biz/project.go index 8c1666c2f..611aacb85 100644 --- a/app/controlplane/pkg/biz/project.go +++ b/app/controlplane/pkg/biz/project.go @@ -88,6 +88,8 @@ type ProjectMembership struct { MembershipType authz.MembershipType // Role represents the role of the user/group in the project (admin or viewer). Role authz.Role + // LatestProjectVersionID is the ID of the latest project version this membership is associated with. + LatestProjectVersionID *uuid.UUID // CreatedAt is the timestamp when the user/group was added to the project. CreatedAt *time.Time // UpdatedAt is the timestamp when the membership was last updated. diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index a9a1932f5..bcb26e25a 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -20,6 +20,10 @@ import ( "fmt" "time" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/projectversion" + + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/project" + "entgo.io/ent/dialect/sql/sqljson" "entgo.io/ent/dialect/sql" @@ -573,6 +577,107 @@ func (g GroupRepo) UpdateMemberMaintainerStatus(ctx context.Context, orgID uuid. }) } +// ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. +func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*biz.ProjectMembership, int, error) { + if paginationOpts == nil { + paginationOpts = pagination.NewDefaultOffsetPaginationOpts() + } + + // Check the group exists in the organization + _, err := g.data.DB.Group.Query(). + Where(group.ID(groupID), group.OrganizationIDEQ(orgID), group.DeletedAtIsNil()). + Only(ctx) + if err != nil { + if ent.IsNotFound(err) { + return nil, 0, biz.NewErrNotFound("group") + } + return nil, 0, err + } + + // Get all memberships where this group is a member and the resource type is a project + // Apply pagination directly on the memberships query + membershipQuery := g.data.DB.Membership.Query(). + Where( + membership.MemberIDEQ(groupID), + membership.MembershipTypeEQ(authz.MembershipTypeGroup), + membership.ResourceTypeEQ(authz.ResourceTypeProject), + membership.HasOrganizationWith(organization.IDEQ(orgID)), + ) + + // Get total count first + count, err := membershipQuery.Count(ctx) + if err != nil { + return nil, 0, fmt.Errorf("failed to count project memberships: %w", err) + } + + // Apply pagination to the memberships query + memberships, err := membershipQuery. + Order(ent.Desc(membership.FieldCreatedAt)). + Offset(paginationOpts.Offset()). + Limit(paginationOpts.Limit()). + All(ctx) + if err != nil { + return nil, 0, fmt.Errorf("failed to query memberships: %w", err) + } + + // If no memberships found, return empty result + if len(memberships) == 0 { + return []*biz.ProjectMembership{}, count, nil + } + + // Extract project IDs from memberships + var projectIDs []uuid.UUID + // Create a map to store role by project ID for later use + projectRoles := make(map[uuid.UUID]authz.Role) + for _, m := range memberships { + projectIDs = append(projectIDs, m.ResourceID) + projectRoles[m.ResourceID] = m.Role + } + + // Query the actual projects using the project IDs + entProjects, err := g.data.DB.Project.Query(). + Where( + project.IDIn(projectIDs...), + project.OrganizationID(orgID), + project.DeletedAtIsNil(), + ). + WithVersions(func(query *ent.ProjectVersionQuery) { + query.Where(projectversion.Latest(true)).Select(projectversion.FieldID) + }). + All(ctx) + if err != nil { + return nil, 0, fmt.Errorf("failed to fetch projects: %w", err) + } + + // Get the group for membership + existingGroup, err := g.data.DB.Group.Query(). + Where(group.ID(groupID), group.OrganizationIDEQ(orgID), group.DeletedAtIsNil()). + Only(ctx) + if err != nil { + return nil, 0, fmt.Errorf("failed to fetch group: %w", err) + } + + // Convert to business layer project memberships + projectMemberships := make([]*biz.ProjectMembership, 0, len(entProjects)) + for _, p := range entProjects { + projectMembership := &biz.ProjectMembership{ + Group: entGroupToBiz(existingGroup), + MembershipType: authz.MembershipTypeGroup, + Role: projectRoles[p.ID], // Use the role we stored earlier + CreatedAt: toTimePtr(p.CreatedAt), + } + + // If the project has versions, include the latest version ID + if len(p.Edges.Versions) > 0 { + projectMembership.LatestProjectVersionID = &p.Edges.Versions[0].ID + } + + projectMemberships = append(projectMemberships, projectMembership) + } + + return projectMemberships, count, nil +} + // entGroupToBiz converts an ent.Group to a biz.Group. func entGroupToBiz(gr *ent.Group) *biz.Group { grp := &biz.Group{ From 25c5f1006cb25df776523fa3ea81d3efe25f85a9 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 15:43:57 +0200 Subject: [PATCH 02/11] update logic and add authz Signed-off-by: Javier Rodriguez --- .../api/controlplane/v1/group.pb.go | 434 +++++++++++------- .../api/controlplane/v1/group.proto | 18 +- .../api/gen/frontend/controlplane/v1/group.ts | 165 ++++++- ...erviceListProjectsResponse.jsonschema.json | 13 +- ...oupServiceListProjectsResponse.schema.json | 13 +- ...ontrolplane.v1.ProjectInfo.jsonschema.json | 44 ++ .../controlplane.v1.ProjectInfo.schema.json | 44 ++ app/controlplane/cmd/wire_gen.go | 2 +- app/controlplane/internal/service/group.go | 55 ++- app/controlplane/pkg/authz/authz.go | 3 +- app/controlplane/pkg/biz/group.go | 29 +- app/controlplane/pkg/biz/project.go | 18 + .../pkg/biz/testhelpers/wire_gen.go | 2 +- app/controlplane/pkg/data/group.go | 46 +- 14 files changed, 652 insertions(+), 234 deletions(-) create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json diff --git a/app/controlplane/api/controlplane/v1/group.pb.go b/app/controlplane/api/controlplane/v1/group.pb.go index 78a6e8de8..dd3686f3e 100644 --- a/app/controlplane/api/controlplane/v1/group.pb.go +++ b/app/controlplane/api/controlplane/v1/group.pb.go @@ -1354,7 +1354,7 @@ type GroupServiceListProjectsResponse struct { unknownFields protoimpl.UnknownFields // List of projects memberships matching the request criteria - ProjectMembers []*ProjectMember `protobuf:"bytes,1,rep,name=project_members,json=projectMembers,proto3" json:"project_members,omitempty"` + Projects []*ProjectInfo `protobuf:"bytes,1,rep,name=projects,proto3" json:"projects,omitempty"` // Pagination information for the response Pagination *OffsetPaginationResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -1391,9 +1391,9 @@ func (*GroupServiceListProjectsResponse) Descriptor() ([]byte, []int) { return file_controlplane_v1_group_proto_rawDescGZIP(), []int{23} } -func (x *GroupServiceListProjectsResponse) GetProjectMembers() []*ProjectMember { +func (x *GroupServiceListProjectsResponse) GetProjects() []*ProjectInfo { if x != nil { - return x.ProjectMembers + return x.Projects } return nil } @@ -1405,6 +1405,100 @@ func (x *GroupServiceListProjectsResponse) GetPagination() *OffsetPaginationResp return nil } +// ProjectInfo represents detailed information about a project that a group is a member of +type ProjectInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier of the project + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Name of the project + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Description of the project + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // Role of the group in the project (admin or viewer) + Role string `protobuf:"bytes,4,opt,name=role,proto3" json:"role,omitempty"` + // The latest version ID of the project, if available + LatestVersionId *string `protobuf:"bytes,5,opt,name=latest_version_id,json=latestVersionId,proto3,oneof" json:"latest_version_id,omitempty"` + // Timestamp when the project was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` +} + +func (x *ProjectInfo) Reset() { + *x = ProjectInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_group_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProjectInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProjectInfo) ProtoMessage() {} + +func (x *ProjectInfo) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_group_proto_msgTypes[24] + 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 ProjectInfo.ProtoReflect.Descriptor instead. +func (*ProjectInfo) Descriptor() ([]byte, []int) { + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{24} +} + +func (x *ProjectInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ProjectInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ProjectInfo) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ProjectInfo) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *ProjectInfo) GetLatestVersionId() string { + if x != nil && x.LatestVersionId != nil { + return *x.LatestVersionId + } + return "" +} + +func (x *ProjectInfo) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + var File_controlplane_v1_group_proto protoreflect.FileDescriptor var file_controlplane_v1_group_proto_rawDesc = []byte{ @@ -1636,105 +1730,119 @@ var file_controlplane_v1_group_proto_rawDesc = []byte{ 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb6, 0x01, + 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x01, 0x0a, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0e, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, - 0x47, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, + 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, + 0x01, 0x01, 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, 0x42, 0x14, 0x0a, + 0x12, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x2a, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, + 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, + 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, + 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, + 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, + 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1749,7 +1857,7 @@ func file_controlplane_v1_group_proto_rawDescGZIP() []byte { return file_controlplane_v1_group_proto_rawDescData } -var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceCreateRequest)(nil), // 0: controlplane.v1.GroupServiceCreateRequest (*GroupServiceCreateResponse)(nil), // 1: controlplane.v1.GroupServiceCreateResponse @@ -1775,71 +1883,72 @@ var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceUpdateMemberMaintainerStatusResponse)(nil), // 21: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse (*GroupServiceListProjectsRequest)(nil), // 22: controlplane.v1.GroupServiceListProjectsRequest (*GroupServiceListProjectsResponse)(nil), // 23: controlplane.v1.GroupServiceListProjectsResponse - (*Group)(nil), // 24: controlplane.v1.Group - (*IdentityReference)(nil), // 25: controlplane.v1.IdentityReference - (*OffsetPaginationRequest)(nil), // 26: controlplane.v1.OffsetPaginationRequest - (*OffsetPaginationResponse)(nil), // 27: controlplane.v1.OffsetPaginationResponse - (*User)(nil), // 28: controlplane.v1.User - (*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp - (*ProjectMember)(nil), // 30: controlplane.v1.ProjectMember + (*ProjectInfo)(nil), // 24: controlplane.v1.ProjectInfo + (*Group)(nil), // 25: controlplane.v1.Group + (*IdentityReference)(nil), // 26: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 27: controlplane.v1.OffsetPaginationRequest + (*OffsetPaginationResponse)(nil), // 28: controlplane.v1.OffsetPaginationResponse + (*User)(nil), // 29: controlplane.v1.User + (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp } var file_controlplane_v1_group_proto_depIdxs = []int32{ - 24, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group - 25, // 1: controlplane.v1.GroupServiceGetRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 24, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group - 26, // 3: controlplane.v1.GroupServiceListRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 24, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group - 27, // 5: controlplane.v1.GroupServiceListResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 25, // 6: controlplane.v1.GroupServiceUpdateRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 24, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group - 25, // 8: controlplane.v1.GroupServiceDeleteRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group + 26, // 1: controlplane.v1.GroupServiceGetRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group + 27, // 3: controlplane.v1.GroupServiceListRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 25, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group + 28, // 5: controlplane.v1.GroupServiceListResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 26, // 6: controlplane.v1.GroupServiceUpdateRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 25, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group + 26, // 8: controlplane.v1.GroupServiceDeleteRequest.group_reference:type_name -> controlplane.v1.IdentityReference 19, // 9: controlplane.v1.GroupServiceListMembersResponse.members:type_name -> controlplane.v1.GroupMember - 27, // 10: controlplane.v1.GroupServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 25, // 11: controlplane.v1.GroupServiceListMembersRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 26, // 12: controlplane.v1.GroupServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 25, // 13: controlplane.v1.GroupServiceAddMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 25, // 14: controlplane.v1.GroupServiceRemoveMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 25, // 15: controlplane.v1.GroupServiceListPendingInvitationsRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 26, // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 28, // 10: controlplane.v1.GroupServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 26, // 11: controlplane.v1.GroupServiceListMembersRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 27, // 12: controlplane.v1.GroupServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 26, // 13: controlplane.v1.GroupServiceAddMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 14: controlplane.v1.GroupServiceRemoveMemberRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 15: controlplane.v1.GroupServiceListPendingInvitationsRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 27, // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest 18, // 17: controlplane.v1.GroupServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingGroupInvitation - 27, // 18: controlplane.v1.GroupServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 28, // 19: controlplane.v1.PendingGroupInvitation.invited_by:type_name -> controlplane.v1.User - 29, // 20: controlplane.v1.PendingGroupInvitation.created_at:type_name -> google.protobuf.Timestamp - 28, // 21: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User - 29, // 22: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp - 29, // 23: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp - 25, // 24: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 25, // 25: controlplane.v1.GroupServiceListProjectsRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 26, // 26: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 30, // 27: controlplane.v1.GroupServiceListProjectsResponse.project_members:type_name -> controlplane.v1.ProjectMember - 27, // 28: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 0, // 29: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest - 2, // 30: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest - 4, // 31: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest - 6, // 32: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest - 8, // 33: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest - 11, // 34: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest - 12, // 35: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest - 14, // 36: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest - 20, // 37: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - 16, // 38: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest - 22, // 39: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest - 1, // 40: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse - 3, // 41: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse - 5, // 42: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse - 7, // 43: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse - 9, // 44: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse - 10, // 45: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse - 13, // 46: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse - 15, // 47: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse - 21, // 48: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - 17, // 49: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse - 23, // 50: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse - 40, // [40:51] is the sub-list for method output_type - 29, // [29:40] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 28, // 18: controlplane.v1.GroupServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 29, // 19: controlplane.v1.PendingGroupInvitation.invited_by:type_name -> controlplane.v1.User + 30, // 20: controlplane.v1.PendingGroupInvitation.created_at:type_name -> google.protobuf.Timestamp + 29, // 21: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User + 30, // 22: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp + 30, // 23: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp + 26, // 24: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 25: controlplane.v1.GroupServiceListProjectsRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 27, // 26: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 24, // 27: controlplane.v1.GroupServiceListProjectsResponse.projects:type_name -> controlplane.v1.ProjectInfo + 28, // 28: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 30, // 29: controlplane.v1.ProjectInfo.created_at:type_name -> google.protobuf.Timestamp + 0, // 30: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest + 2, // 31: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest + 4, // 32: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest + 6, // 33: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest + 8, // 34: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest + 11, // 35: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest + 12, // 36: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest + 14, // 37: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest + 20, // 38: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + 16, // 39: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest + 22, // 40: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest + 1, // 41: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse + 3, // 42: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse + 5, // 43: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse + 7, // 44: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse + 9, // 45: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse + 10, // 46: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse + 13, // 47: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse + 15, // 48: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse + 21, // 49: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + 17, // 50: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse + 23, // 51: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse + 41, // [41:52] is the sub-list for method output_type + 30, // [30:41] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_controlplane_v1_group_proto_init() } @@ -2139,18 +2248,31 @@ func file_controlplane_v1_group_proto_init() { return nil } } + file_controlplane_v1_group_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProjectInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_controlplane_v1_group_proto_msgTypes[4].OneofWrappers = []interface{}{} file_controlplane_v1_group_proto_msgTypes[6].OneofWrappers = []interface{}{} file_controlplane_v1_group_proto_msgTypes[11].OneofWrappers = []interface{}{} file_controlplane_v1_group_proto_msgTypes[18].OneofWrappers = []interface{}{} + file_controlplane_v1_group_proto_msgTypes[24].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_group_proto_rawDesc, NumEnums: 0, - NumMessages: 24, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/app/controlplane/api/controlplane/v1/group.proto b/app/controlplane/api/controlplane/v1/group.proto index ea8ca378b..edc12dd6c 100644 --- a/app/controlplane/api/controlplane/v1/group.proto +++ b/app/controlplane/api/controlplane/v1/group.proto @@ -232,7 +232,23 @@ message GroupServiceListProjectsRequest { // GroupServiceListProjectsResponse contains a paginated list of projects for a group message GroupServiceListProjectsResponse { // List of projects memberships matching the request criteria - repeated ProjectMember project_members = 1; + repeated ProjectInfo projects = 1; // Pagination information for the response OffsetPaginationResponse pagination = 2; } + +// ProjectInfo represents detailed information about a project that a group is a member of +message ProjectInfo { + // Unique identifier of the project + string id = 1; + // Name of the project + string name = 2; + // Description of the project + string description = 3; + // Role of the group in the project (admin or viewer) + string role = 4; + // The latest version ID of the project, if available + optional string latest_version_id = 5; + // Timestamp when the project was created + google.protobuf.Timestamp created_at = 6; +} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts index 576a0f692..e2eb7d645 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts @@ -5,7 +5,7 @@ import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { Group, IdentityReference, ProjectMember } from "./shared_message"; +import { Group, IdentityReference } from "./shared_message"; export const protobufPackage = "controlplane.v1"; @@ -204,11 +204,29 @@ export interface GroupServiceListProjectsRequest { /** GroupServiceListProjectsResponse contains a paginated list of projects for a group */ export interface GroupServiceListProjectsResponse { /** List of projects memberships matching the request criteria */ - projectMembers: ProjectMember[]; + projects: ProjectInfo[]; /** Pagination information for the response */ pagination?: OffsetPaginationResponse; } +/** ProjectInfo represents detailed information about a project that a group is a member of */ +export interface ProjectInfo { + /** Unique identifier of the project */ + id: string; + /** Name of the project */ + name: string; + /** Description of the project */ + description: string; + /** Role of the group in the project (admin or viewer) */ + role: string; + /** The latest version ID of the project, if available */ + latestVersionId?: + | string + | undefined; + /** Timestamp when the project was created */ + createdAt?: Date; +} + function createBaseGroupServiceCreateRequest(): GroupServiceCreateRequest { return { name: "", description: "" }; } @@ -1902,13 +1920,13 @@ export const GroupServiceListProjectsRequest = { }; function createBaseGroupServiceListProjectsResponse(): GroupServiceListProjectsResponse { - return { projectMembers: [], pagination: undefined }; + return { projects: [], pagination: undefined }; } export const GroupServiceListProjectsResponse = { encode(message: GroupServiceListProjectsResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - for (const v of message.projectMembers) { - ProjectMember.encode(v!, writer.uint32(10).fork()).ldelim(); + for (const v of message.projects) { + ProjectInfo.encode(v!, writer.uint32(10).fork()).ldelim(); } if (message.pagination !== undefined) { OffsetPaginationResponse.encode(message.pagination, writer.uint32(18).fork()).ldelim(); @@ -1928,7 +1946,7 @@ export const GroupServiceListProjectsResponse = { break; } - message.projectMembers.push(ProjectMember.decode(reader, reader.uint32())); + message.projects.push(ProjectInfo.decode(reader, reader.uint32())); continue; case 2: if (tag !== 18) { @@ -1948,19 +1966,17 @@ export const GroupServiceListProjectsResponse = { fromJSON(object: any): GroupServiceListProjectsResponse { return { - projectMembers: Array.isArray(object?.projectMembers) - ? object.projectMembers.map((e: any) => ProjectMember.fromJSON(e)) - : [], + projects: Array.isArray(object?.projects) ? object.projects.map((e: any) => ProjectInfo.fromJSON(e)) : [], pagination: isSet(object.pagination) ? OffsetPaginationResponse.fromJSON(object.pagination) : undefined, }; }, toJSON(message: GroupServiceListProjectsResponse): unknown { const obj: any = {}; - if (message.projectMembers) { - obj.projectMembers = message.projectMembers.map((e) => e ? ProjectMember.toJSON(e) : undefined); + if (message.projects) { + obj.projects = message.projects.map((e) => e ? ProjectInfo.toJSON(e) : undefined); } else { - obj.projectMembers = []; + obj.projects = []; } message.pagination !== undefined && (obj.pagination = message.pagination ? OffsetPaginationResponse.toJSON(message.pagination) : undefined); @@ -1977,7 +1993,7 @@ export const GroupServiceListProjectsResponse = { object: I, ): GroupServiceListProjectsResponse { const message = createBaseGroupServiceListProjectsResponse(); - message.projectMembers = object.projectMembers?.map((e) => ProjectMember.fromPartial(e)) || []; + message.projects = object.projects?.map((e) => ProjectInfo.fromPartial(e)) || []; message.pagination = (object.pagination !== undefined && object.pagination !== null) ? OffsetPaginationResponse.fromPartial(object.pagination) : undefined; @@ -1985,6 +2001,129 @@ export const GroupServiceListProjectsResponse = { }, }; +function createBaseProjectInfo(): ProjectInfo { + return { id: "", name: "", description: "", role: "", latestVersionId: undefined, createdAt: undefined }; +} + +export const ProjectInfo = { + encode(message: ProjectInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.description !== "") { + writer.uint32(26).string(message.description); + } + if (message.role !== "") { + writer.uint32(34).string(message.role); + } + if (message.latestVersionId !== undefined) { + writer.uint32(42).string(message.latestVersionId); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(50).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ProjectInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseProjectInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.description = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.role = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.latestVersionId = reader.string(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): ProjectInfo { + return { + id: isSet(object.id) ? String(object.id) : "", + name: isSet(object.name) ? String(object.name) : "", + description: isSet(object.description) ? String(object.description) : "", + role: isSet(object.role) ? String(object.role) : "", + latestVersionId: isSet(object.latestVersionId) ? String(object.latestVersionId) : undefined, + createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + }; + }, + + toJSON(message: ProjectInfo): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.name !== undefined && (obj.name = message.name); + message.description !== undefined && (obj.description = message.description); + message.role !== undefined && (obj.role = message.role); + message.latestVersionId !== undefined && (obj.latestVersionId = message.latestVersionId); + message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + return obj; + }, + + create, I>>(base?: I): ProjectInfo { + return ProjectInfo.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): ProjectInfo { + const message = createBaseProjectInfo(); + message.id = object.id ?? ""; + message.name = object.name ?? ""; + message.description = object.description ?? ""; + message.role = object.role ?? ""; + message.latestVersionId = object.latestVersionId ?? undefined; + message.createdAt = object.createdAt ?? undefined; + return message; + }, +}; + /** GroupService provides operations for managing groups within the system */ export interface GroupService { /** Create creates a new group with the specified name and description */ diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json index 0bfd2bb0c..287fd1dc5 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.jsonschema.json @@ -3,24 +3,15 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "description": "GroupServiceListProjectsResponse contains a paginated list of projects for a group", - "patternProperties": { - "^(project_members)$": { - "description": "List of projects memberships matching the request criteria", - "items": { - "$ref": "controlplane.v1.ProjectMember.jsonschema.json" - }, - "type": "array" - } - }, "properties": { "pagination": { "$ref": "controlplane.v1.OffsetPaginationResponse.jsonschema.json", "description": "Pagination information for the response" }, - "projectMembers": { + "projects": { "description": "List of projects memberships matching the request criteria", "items": { - "$ref": "controlplane.v1.ProjectMember.jsonschema.json" + "$ref": "controlplane.v1.ProjectInfo.jsonschema.json" }, "type": "array" } diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json index 5145f2702..15be117c9 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.GroupServiceListProjectsResponse.schema.json @@ -3,24 +3,15 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "description": "GroupServiceListProjectsResponse contains a paginated list of projects for a group", - "patternProperties": { - "^(projectMembers)$": { - "description": "List of projects memberships matching the request criteria", - "items": { - "$ref": "controlplane.v1.ProjectMember.schema.json" - }, - "type": "array" - } - }, "properties": { "pagination": { "$ref": "controlplane.v1.OffsetPaginationResponse.schema.json", "description": "Pagination information for the response" }, - "project_members": { + "projects": { "description": "List of projects memberships matching the request criteria", "items": { - "$ref": "controlplane.v1.ProjectMember.schema.json" + "$ref": "controlplane.v1.ProjectInfo.schema.json" }, "type": "array" } diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json new file mode 100644 index 000000000..24c5a6dc3 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json @@ -0,0 +1,44 @@ +{ + "$id": "controlplane.v1.ProjectInfo.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "ProjectInfo represents detailed information about a project that a group is a member of", + "patternProperties": { + "^(created_at)$": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was created" + }, + "^(latest_version_id)$": { + "description": "The latest version ID of the project, if available", + "type": "string" + } + }, + "properties": { + "createdAt": { + "$ref": "google.protobuf.Timestamp.jsonschema.json", + "description": "Timestamp when the project was created" + }, + "description": { + "description": "Description of the project", + "type": "string" + }, + "id": { + "description": "Unique identifier of the project", + "type": "string" + }, + "latestVersionId": { + "description": "The latest version ID of the project, if available", + "type": "string" + }, + "name": { + "description": "Name of the project", + "type": "string" + }, + "role": { + "description": "Role of the group in the project (admin or viewer)", + "type": "string" + } + }, + "title": "Project Info", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json new file mode 100644 index 000000000..a9794c412 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json @@ -0,0 +1,44 @@ +{ + "$id": "controlplane.v1.ProjectInfo.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "ProjectInfo represents detailed information about a project that a group is a member of", + "patternProperties": { + "^(createdAt)$": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was created" + }, + "^(latestVersionId)$": { + "description": "The latest version ID of the project, if available", + "type": "string" + } + }, + "properties": { + "created_at": { + "$ref": "google.protobuf.Timestamp.schema.json", + "description": "Timestamp when the project was created" + }, + "description": { + "description": "Description of the project", + "type": "string" + }, + "id": { + "description": "Unique identifier of the project", + "type": "string" + }, + "latest_version_id": { + "description": "The latest version ID of the project, if available", + "type": "string" + }, + "name": { + "description": "Name of the project", + "type": "string" + }, + "role": { + "description": "Role of the group in the project (admin or viewer)", + "type": "string" + } + }, + "title": "Project Info", + "type": "object" +} diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index c6d007b20..e78d95a63 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -135,7 +135,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l cleanup() return nil, nil, err } - groupUseCase := biz.NewGroupUseCase(logger, groupRepo, membershipRepo, userRepo, orgInvitationUseCase, auditorUseCase, orgInvitationRepo, enforcer) + groupUseCase := biz.NewGroupUseCase(logger, groupRepo, membershipRepo, userRepo, orgInvitationUseCase, auditorUseCase, orgInvitationRepo, enforcer, membershipUseCase) projectUseCase := biz.NewProjectsUseCase(logger, projectsRepo, membershipRepo, auditorUseCase, groupUseCase, membershipUseCase, orgInvitationUseCase, orgInvitationRepo, enforcer) v5 := serviceOpts(logger, enforcer, projectUseCase, groupUseCase) workflowService := service.NewWorkflowService(workflowUseCase, workflowContractUseCase, projectUseCase, v5...) diff --git a/app/controlplane/internal/service/group.go b/app/controlplane/internal/service/group.go index a06860444..a745030bb 100644 --- a/app/controlplane/internal/service/group.go +++ b/app/controlplane/internal/service/group.go @@ -486,6 +486,11 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis return nil, err } + currentUser, err := requireCurrentUser(ctx) + if err != nil { + return nil, err + } + // Parse orgID orgUUID, err := uuid.Parse(currentOrg.ID) if err != nil { @@ -498,10 +503,19 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis return nil, errors.BadRequest("invalid", fmt.Sprintf("invalid group reference: %s", err.Error())) } + // Parse requesterID (current user) + requesterUUID, err := uuid.Parse(currentUser.ID) + if err != nil { + return nil, errors.BadRequest("invalid", "invalid user ID") + } + // Initialize the options for getting projects - groupOpts := &biz.IdentityReference{ - ID: id, - Name: name, + groupOpts := &biz.ListProjectsByGroupOpts{ + IdentityReference: &biz.IdentityReference{ + ID: id, + Name: name, + }, + RequesterID: &requesterUUID, } // Initialize the pagination options, with default values @@ -510,21 +524,21 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis return nil, handleUseCaseErr(err, g.log) } - // Retrieve the list of project members - projectMembers, count, err := g.groupUseCase.ListProjectsByGroup(ctx, orgUUID, groupOpts, paginationOpts) + // Retrieve the list of project info + projectInfoList, count, err := g.groupUseCase.ListProjectsByGroup(ctx, orgUUID, groupOpts, paginationOpts) if err != nil { return nil, handleUseCaseErr(err, g.log) } - // Convert the projectMembers to protobuf messages - result := make([]*pb.ProjectMember, 0, len(projectMembers)) - for _, project := range projectMembers { - result = append(result, bizProjectMembershipToPb(project)) + // Convert the GroupProjectInfo to protobuf messages + result := make([]*pb.ProjectInfo, 0, len(projectInfoList)) + for _, project := range projectInfoList { + result = append(result, bizGroupProjectInfoToPb(project)) } return &pb.GroupServiceListProjectsResponse{ - ProjectMembers: result, - Pagination: paginationToPb(count, paginationOpts.Offset(), paginationOpts.Limit()), + Projects: result, + Pagination: paginationToPb(count, paginationOpts.Offset(), paginationOpts.Limit()), }, nil } @@ -571,3 +585,22 @@ func bizOrgInvitationToPendingGroupInvitationPb(inv *biz.OrgInvitation) *pb.Pend return base } + +// bizGroupProjectInfoToPb converts a biz.GroupProjectInfo to a pb.ProjectInfo protobuf message. +func bizGroupProjectInfoToPb(info *biz.GroupProjectInfo) *pb.ProjectInfo { + projectInfo := &pb.ProjectInfo{ + Id: info.ID.String(), + Name: info.Name, + Description: info.Description, + Role: string(info.Role), + CreatedAt: timestamppb.New(*info.CreatedAt), + } + + // Add the latest version ID if available + if info.LatestVersionID != nil { + latestVersionID := info.LatestVersionID.String() + projectInfo.LatestVersionId = &latestVersionID + } + + return projectInfo +} diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index 7c5b04b0b..882a0f0fc 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -393,7 +393,8 @@ var ServerOperationsMap = map[string][]*Policy{ "/controlplane.v1.GroupService/List": {PolicyGroupList}, "/controlplane.v1.GroupService/Get": {PolicyGroupRead}, // Group Memberships - "/controlplane.v1.GroupService/ListMembers": {PolicyGroupListMemberships}, + "/controlplane.v1.GroupService/ListMembers": {PolicyGroupListMemberships}, + "/controlplane.v1.GroupService/ListProjects": {PolicyGroupListMemberships}, // For the following endpoints, we rely on the service layer to check the permissions // That's why we let everyone access them (empty policies) "/controlplane.v1.GroupService/AddMember": {}, diff --git a/app/controlplane/pkg/biz/group.go b/app/controlplane/pkg/biz/group.go index 87caabb49..43230a0d0 100644 --- a/app/controlplane/pkg/biz/group.go +++ b/app/controlplane/pkg/biz/group.go @@ -54,7 +54,7 @@ type GroupRepo interface { // ListPendingInvitationsByGroup retrieves a list of pending invitations for a group ListPendingInvitationsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*OrgInvitation, int, error) // ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. - ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*ProjectMembership, int, error) + ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, visibleProjectIDs []uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*GroupProjectInfo, int, error) } // GroupMembership represents a membership of a user in a group. @@ -171,6 +171,15 @@ type UpdateMemberMaintainerStatusOpts struct { IsMaintainer bool } +// ListProjectsByGroupOpts defines options for listing projects by group. +type ListProjectsByGroupOpts struct { + // Group reference + *IdentityReference + // RequesterID is the ID of the user who is requesting to list projects. Optional. + // Used to scope down the projects to those visible to the requester. + RequesterID *uuid.UUID +} + type GroupUseCase struct { // logger is used to log messages. logger *log.Helper @@ -183,9 +192,10 @@ type GroupUseCase struct { // Use Cases orgInvitationUC *OrgInvitationUseCase auditorUC *AuditorUseCase + membershipUC *MembershipUseCase } -func NewGroupUseCase(logger log.Logger, groupRepo GroupRepo, membershipRepo MembershipRepo, userRepo UserRepo, orgInvitationUC *OrgInvitationUseCase, auditorUC *AuditorUseCase, invitationRepo OrgInvitationRepo, enforcer *authz.Enforcer) *GroupUseCase { +func NewGroupUseCase(logger log.Logger, groupRepo GroupRepo, membershipRepo MembershipRepo, userRepo UserRepo, orgInvitationUC *OrgInvitationUseCase, auditorUC *AuditorUseCase, invitationRepo OrgInvitationRepo, enforcer *authz.Enforcer, membershipUseCase *MembershipUseCase) *GroupUseCase { return &GroupUseCase{ logger: log.NewHelper(log.With(logger, "component", "biz/group")), groupRepo: groupRepo, @@ -195,6 +205,7 @@ func NewGroupUseCase(logger log.Logger, groupRepo GroupRepo, membershipRepo Memb auditorUC: auditorUC, orgInvitationRepo: invitationRepo, enforcer: enforcer, + membershipUC: membershipUseCase, } } @@ -857,7 +868,7 @@ func (uc *GroupUseCase) ValidateGroupIdentifier(ctx context.Context, orgID uuid. } // ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. -func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, opts *IdentityReference, paginationOpts *pagination.OffsetPaginationOpts) ([]*ProjectMembership, int, error) { +func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, opts *ListProjectsByGroupOpts, paginationOpts *pagination.OffsetPaginationOpts) ([]*GroupProjectInfo, int, error) { if opts == nil { return nil, 0, NewErrValidationStr("options cannot be nil") } @@ -886,5 +897,15 @@ func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID pgOpts = paginationOpts } - return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, pgOpts) + var requesterMemberships []*Membership + // If requesterID is provided, list all memberships for the requester + if opts.RequesterID != nil { + var listErr error + requesterMemberships, listErr = uc.membershipUC.ListAllMembershipsForUser(ctx, *opts.RequesterID) + if listErr != nil { + return nil, 0, fmt.Errorf("failed to list memberships: %w", listErr) + } + } + + return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, getProjectsWithMembershipInOrg(orgID, requesterMemberships), pgOpts) } diff --git a/app/controlplane/pkg/biz/project.go b/app/controlplane/pkg/biz/project.go index 611aacb85..91b2cbd42 100644 --- a/app/controlplane/pkg/biz/project.go +++ b/app/controlplane/pkg/biz/project.go @@ -96,6 +96,24 @@ type ProjectMembership struct { UpdatedAt *time.Time } +// GroupProjectInfo represents detailed information about a project that a group is a member of +type GroupProjectInfo struct { + // ID is the unique identifier of the project + ID uuid.UUID + // Name is the name of the project + Name string + // Description is the description of the project + Description string + // Role represents the role of the group in the project (admin or viewer) + Role authz.Role + // LatestVersionID is the ID of the latest version of the project, if available + LatestVersionID *uuid.UUID + // Group is the group that is a member of this project + Group *Group + // CreatedAt is the timestamp when the project was created + CreatedAt *time.Time +} + // AddMemberToProjectOpts defines options for adding a member to a project. type AddMemberToProjectOpts struct { // ProjectReference is the reference to the project. diff --git a/app/controlplane/pkg/biz/testhelpers/wire_gen.go b/app/controlplane/pkg/biz/testhelpers/wire_gen.go index 786e6afb8..8346da9df 100644 --- a/app/controlplane/pkg/biz/testhelpers/wire_gen.go +++ b/app/controlplane/pkg/biz/testhelpers/wire_gen.go @@ -152,7 +152,7 @@ func WireTestData(testDatabase *TestDatabase, t *testing.T, logger log.Logger, r } projectVersionRepo := data.NewProjectVersionRepo(dataData, logger) projectVersionUseCase := biz.NewProjectVersionUseCase(projectVersionRepo, logger) - groupUseCase := biz.NewGroupUseCase(logger, groupRepo, membershipRepo, userRepo, orgInvitationUseCase, auditorUseCase, orgInvitationRepo, enforcer) + groupUseCase := biz.NewGroupUseCase(logger, groupRepo, membershipRepo, userRepo, orgInvitationUseCase, auditorUseCase, orgInvitationRepo, enforcer, membershipUseCase) projectUseCase := biz.NewProjectsUseCase(logger, projectsRepo, membershipRepo, auditorUseCase, groupUseCase, membershipUseCase, orgInvitationUseCase, orgInvitationRepo, enforcer) testingRepos := &TestingRepos{ Membership: membershipRepo, diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index bcb26e25a..5a365ac53 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -578,13 +578,13 @@ func (g GroupRepo) UpdateMemberMaintainerStatus(ctx context.Context, orgID uuid. } // ListProjectsByGroup retrieves a list of projects that a group is a member of with pagination. -func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*biz.ProjectMembership, int, error) { +func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, groupID uuid.UUID, visibleProjectIDs []uuid.UUID, paginationOpts *pagination.OffsetPaginationOpts) ([]*biz.GroupProjectInfo, int, error) { if paginationOpts == nil { paginationOpts = pagination.NewDefaultOffsetPaginationOpts() } // Check the group exists in the organization - _, err := g.data.DB.Group.Query(). + existingGroup, err := g.data.DB.Group.Query(). Where(group.ID(groupID), group.OrganizationIDEQ(orgID), group.DeletedAtIsNil()). Only(ctx) if err != nil { @@ -595,7 +595,6 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro } // Get all memberships where this group is a member and the resource type is a project - // Apply pagination directly on the memberships query membershipQuery := g.data.DB.Membership.Query(). Where( membership.MemberIDEQ(groupID), @@ -604,7 +603,12 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro membership.HasOrganizationWith(organization.IDEQ(orgID)), ) - // Get total count first + // If visibleProjectIDs is provided, filter memberships to include only those projects + if len(visibleProjectIDs) > 0 { + membershipQuery = membershipQuery.Where(membership.ResourceIDIn(visibleProjectIDs...)) + } + + // Get total count first (after applying visibility filters) count, err := membershipQuery.Count(ctx) if err != nil { return nil, 0, fmt.Errorf("failed to count project memberships: %w", err) @@ -622,11 +626,11 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro // If no memberships found, return empty result if len(memberships) == 0 { - return []*biz.ProjectMembership{}, count, nil + return []*biz.GroupProjectInfo{}, count, nil } // Extract project IDs from memberships - var projectIDs []uuid.UUID + projectIDs := make([]uuid.UUID, 0, len(memberships)) // Create a map to store role by project ID for later use projectRoles := make(map[uuid.UUID]authz.Role) for _, m := range memberships { @@ -649,33 +653,27 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro return nil, 0, fmt.Errorf("failed to fetch projects: %w", err) } - // Get the group for membership - existingGroup, err := g.data.DB.Group.Query(). - Where(group.ID(groupID), group.OrganizationIDEQ(orgID), group.DeletedAtIsNil()). - Only(ctx) - if err != nil { - return nil, 0, fmt.Errorf("failed to fetch group: %w", err) - } - - // Convert to business layer project memberships - projectMemberships := make([]*biz.ProjectMembership, 0, len(entProjects)) + // Convert to business layer project info + projectInfos := make([]*biz.GroupProjectInfo, 0, len(entProjects)) for _, p := range entProjects { - projectMembership := &biz.ProjectMembership{ - Group: entGroupToBiz(existingGroup), - MembershipType: authz.MembershipTypeGroup, - Role: projectRoles[p.ID], // Use the role we stored earlier - CreatedAt: toTimePtr(p.CreatedAt), + projectInfo := &biz.GroupProjectInfo{ + ID: p.ID, + Name: p.Name, + Description: p.Description, + Role: projectRoles[p.ID], // Use the role we stored earlier + Group: entGroupToBiz(existingGroup), + CreatedAt: toTimePtr(p.CreatedAt), } // If the project has versions, include the latest version ID if len(p.Edges.Versions) > 0 { - projectMembership.LatestProjectVersionID = &p.Edges.Versions[0].ID + projectInfo.LatestVersionID = &p.Edges.Versions[0].ID } - projectMemberships = append(projectMemberships, projectMembership) + projectInfos = append(projectInfos, projectInfo) } - return projectMemberships, count, nil + return projectInfos, count, nil } // entGroupToBiz converts an ent.Group to a biz.Group. From 1e34227f8b44505b5e32d7fef7e94d45cace6354 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 15:46:14 +0200 Subject: [PATCH 03/11] undo changes on protos Signed-off-by: Javier Rodriguez --- .../api/controlplane/v1/group.pb.go | 578 +++++++++------ .../api/controlplane/v1/group.proto | 18 + .../api/controlplane/v1/project.pb.go | 684 ++++++++++++------ .../api/controlplane/v1/project.proto | 29 + .../api/controlplane/v1/shared_message.pb.go | 409 +---------- .../api/controlplane/v1/shared_message.proto | 49 +- .../api/gen/frontend/controlplane/v1/group.ts | 164 ++++- .../gen/frontend/controlplane/v1/project.ts | 202 +++++- .../controlplane/v1/shared_message.ts | 379 ---------- 9 files changed, 1239 insertions(+), 1273 deletions(-) diff --git a/app/controlplane/api/controlplane/v1/group.pb.go b/app/controlplane/api/controlplane/v1/group.pb.go index dd3686f3e..fa90f4d79 100644 --- a/app/controlplane/api/controlplane/v1/group.pb.go +++ b/app/controlplane/api/controlplane/v1/group.pb.go @@ -1107,6 +1107,109 @@ func (x *PendingGroupInvitation) GetInvitationId() string { return "" } +// Group represents a collection of users with shared access to resources +type Group struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Unique identifier for the group + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Human-readable name of the group + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Additional details about the group's purpose + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // UUID of the organization that this group belongs to + OrganizationId string `protobuf:"bytes,4,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` + // Count of members in the group + MemberCount int32 `protobuf:"varint,5,opt,name=member_count,json=memberCount,proto3" json:"member_count,omitempty"` + // Timestamp when the group was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Timestamp when the group was last modified + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` +} + +func (x *Group) Reset() { + *x = Group{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_group_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Group) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group) ProtoMessage() {} + +func (x *Group) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_group_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group.ProtoReflect.Descriptor instead. +func (*Group) Descriptor() ([]byte, []int) { + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{19} +} + +func (x *Group) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Group) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Group) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Group) GetOrganizationId() string { + if x != nil { + return x.OrganizationId + } + return "" +} + +func (x *Group) GetMemberCount() int32 { + if x != nil { + return x.MemberCount + } + return 0 +} + +func (x *Group) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Group) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + // GroupMember represents a user's membership within a group with their role information type GroupMember struct { state protoimpl.MessageState @@ -1126,7 +1229,7 @@ type GroupMember struct { func (x *GroupMember) Reset() { *x = GroupMember{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[19] + mi := &file_controlplane_v1_group_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1139,7 +1242,7 @@ func (x *GroupMember) String() string { func (*GroupMember) ProtoMessage() {} func (x *GroupMember) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[19] + mi := &file_controlplane_v1_group_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1152,7 +1255,7 @@ func (x *GroupMember) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMember.ProtoReflect.Descriptor instead. func (*GroupMember) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{19} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{20} } func (x *GroupMember) GetUser() *User { @@ -1200,7 +1303,7 @@ type GroupServiceUpdateMemberMaintainerStatusRequest struct { func (x *GroupServiceUpdateMemberMaintainerStatusRequest) Reset() { *x = GroupServiceUpdateMemberMaintainerStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[20] + mi := &file_controlplane_v1_group_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1213,7 +1316,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusRequest) String() string { func (*GroupServiceUpdateMemberMaintainerStatusRequest) ProtoMessage() {} func (x *GroupServiceUpdateMemberMaintainerStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[20] + mi := &file_controlplane_v1_group_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1226,7 +1329,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusRequest) ProtoReflect() protore // Deprecated: Use GroupServiceUpdateMemberMaintainerStatusRequest.ProtoReflect.Descriptor instead. func (*GroupServiceUpdateMemberMaintainerStatusRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{20} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{21} } func (x *GroupServiceUpdateMemberMaintainerStatusRequest) GetGroupReference() *IdentityReference { @@ -1260,7 +1363,7 @@ type GroupServiceUpdateMemberMaintainerStatusResponse struct { func (x *GroupServiceUpdateMemberMaintainerStatusResponse) Reset() { *x = GroupServiceUpdateMemberMaintainerStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[21] + mi := &file_controlplane_v1_group_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1273,7 +1376,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusResponse) String() string { func (*GroupServiceUpdateMemberMaintainerStatusResponse) ProtoMessage() {} func (x *GroupServiceUpdateMemberMaintainerStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[21] + mi := &file_controlplane_v1_group_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1286,7 +1389,7 @@ func (x *GroupServiceUpdateMemberMaintainerStatusResponse) ProtoReflect() protor // Deprecated: Use GroupServiceUpdateMemberMaintainerStatusResponse.ProtoReflect.Descriptor instead. func (*GroupServiceUpdateMemberMaintainerStatusResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{21} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{22} } // GroupServiceListProjectsRequest contains parameters for filtering and paginating project results for a group @@ -1304,7 +1407,7 @@ type GroupServiceListProjectsRequest struct { func (x *GroupServiceListProjectsRequest) Reset() { *x = GroupServiceListProjectsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[22] + mi := &file_controlplane_v1_group_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1317,7 +1420,7 @@ func (x *GroupServiceListProjectsRequest) String() string { func (*GroupServiceListProjectsRequest) ProtoMessage() {} func (x *GroupServiceListProjectsRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[22] + mi := &file_controlplane_v1_group_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1330,7 +1433,7 @@ func (x *GroupServiceListProjectsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupServiceListProjectsRequest.ProtoReflect.Descriptor instead. func (*GroupServiceListProjectsRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{22} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{23} } func (x *GroupServiceListProjectsRequest) GetGroupReference() *IdentityReference { @@ -1362,7 +1465,7 @@ type GroupServiceListProjectsResponse struct { func (x *GroupServiceListProjectsResponse) Reset() { *x = GroupServiceListProjectsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[23] + mi := &file_controlplane_v1_group_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1375,7 +1478,7 @@ func (x *GroupServiceListProjectsResponse) String() string { func (*GroupServiceListProjectsResponse) ProtoMessage() {} func (x *GroupServiceListProjectsResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[23] + mi := &file_controlplane_v1_group_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1388,7 +1491,7 @@ func (x *GroupServiceListProjectsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupServiceListProjectsResponse.ProtoReflect.Descriptor instead. func (*GroupServiceListProjectsResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{23} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{24} } func (x *GroupServiceListProjectsResponse) GetProjects() []*ProjectInfo { @@ -1428,7 +1531,7 @@ type ProjectInfo struct { func (x *ProjectInfo) Reset() { *x = ProjectInfo{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_group_proto_msgTypes[24] + mi := &file_controlplane_v1_group_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1441,7 +1544,7 @@ func (x *ProjectInfo) String() string { func (*ProjectInfo) ProtoMessage() {} func (x *ProjectInfo) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_group_proto_msgTypes[24] + mi := &file_controlplane_v1_group_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1454,7 +1557,7 @@ func (x *ProjectInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectInfo.ProtoReflect.Descriptor instead. func (*ProjectInfo) Descriptor() ([]byte, []int) { - return file_controlplane_v1_group_proto_rawDescGZIP(), []int{24} + return file_controlplane_v1_group_proto_rawDescGZIP(), []int{25} } func (x *ProjectInfo) GetId() string { @@ -1688,161 +1791,178 @@ var file_controlplane_v1_group_proto_rawDesc = []byte{ 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, - 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x22, 0xd3, 0x01, 0x0a, - 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x04, - 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, - 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x2f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, - 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, - 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x32, 0x0a, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x1f, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, - 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, - 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x01, - 0x0a, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0a, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, - 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, - 0x01, 0x01, 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, 0x42, 0x14, 0x0a, - 0x12, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x2a, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, - 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x22, 0x8f, 0x02, 0x0a, + 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 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, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 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, 0xd3, + 0x01, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, + 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x39, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x22, 0xd1, 0x01, 0x0a, 0x2f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x53, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, + 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x06, 0x75, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x4d, 0x61, + 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x32, 0x0a, 0x30, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc0, 0x01, 0x0a, + 0x1f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x53, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, + 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xa7, 0x01, 0x0a, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x49, + 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x01, 0x0a, 0x0b, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x88, 0x01, 0x01, 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, 0x42, + 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, 0x47, + 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, - 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, + 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, + 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, 0x6f, 0x6e, + 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, - 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, + 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1857,7 +1977,7 @@ func file_controlplane_v1_group_proto_rawDescGZIP() []byte { return file_controlplane_v1_group_proto_rawDescData } -var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_controlplane_v1_group_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceCreateRequest)(nil), // 0: controlplane.v1.GroupServiceCreateRequest (*GroupServiceCreateResponse)(nil), // 1: controlplane.v1.GroupServiceCreateResponse @@ -1878,13 +1998,13 @@ var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*GroupServiceListPendingInvitationsRequest)(nil), // 16: controlplane.v1.GroupServiceListPendingInvitationsRequest (*GroupServiceListPendingInvitationsResponse)(nil), // 17: controlplane.v1.GroupServiceListPendingInvitationsResponse (*PendingGroupInvitation)(nil), // 18: controlplane.v1.PendingGroupInvitation - (*GroupMember)(nil), // 19: controlplane.v1.GroupMember - (*GroupServiceUpdateMemberMaintainerStatusRequest)(nil), // 20: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - (*GroupServiceUpdateMemberMaintainerStatusResponse)(nil), // 21: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - (*GroupServiceListProjectsRequest)(nil), // 22: controlplane.v1.GroupServiceListProjectsRequest - (*GroupServiceListProjectsResponse)(nil), // 23: controlplane.v1.GroupServiceListProjectsResponse - (*ProjectInfo)(nil), // 24: controlplane.v1.ProjectInfo - (*Group)(nil), // 25: controlplane.v1.Group + (*Group)(nil), // 19: controlplane.v1.Group + (*GroupMember)(nil), // 20: controlplane.v1.GroupMember + (*GroupServiceUpdateMemberMaintainerStatusRequest)(nil), // 21: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + (*GroupServiceUpdateMemberMaintainerStatusResponse)(nil), // 22: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + (*GroupServiceListProjectsRequest)(nil), // 23: controlplane.v1.GroupServiceListProjectsRequest + (*GroupServiceListProjectsResponse)(nil), // 24: controlplane.v1.GroupServiceListProjectsResponse + (*ProjectInfo)(nil), // 25: controlplane.v1.ProjectInfo (*IdentityReference)(nil), // 26: controlplane.v1.IdentityReference (*OffsetPaginationRequest)(nil), // 27: controlplane.v1.OffsetPaginationRequest (*OffsetPaginationResponse)(nil), // 28: controlplane.v1.OffsetPaginationResponse @@ -1892,16 +2012,16 @@ var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp } var file_controlplane_v1_group_proto_depIdxs = []int32{ - 25, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group + 19, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group 26, // 1: controlplane.v1.GroupServiceGetRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 25, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group + 19, // 2: controlplane.v1.GroupServiceGetResponse.group:type_name -> controlplane.v1.Group 27, // 3: controlplane.v1.GroupServiceListRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 25, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group + 19, // 4: controlplane.v1.GroupServiceListResponse.groups:type_name -> controlplane.v1.Group 28, // 5: controlplane.v1.GroupServiceListResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse 26, // 6: controlplane.v1.GroupServiceUpdateRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 25, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group + 19, // 7: controlplane.v1.GroupServiceUpdateResponse.group:type_name -> controlplane.v1.Group 26, // 8: controlplane.v1.GroupServiceDeleteRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 19, // 9: controlplane.v1.GroupServiceListMembersResponse.members:type_name -> controlplane.v1.GroupMember + 20, // 9: controlplane.v1.GroupServiceListMembersResponse.members:type_name -> controlplane.v1.GroupMember 28, // 10: controlplane.v1.GroupServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse 26, // 11: controlplane.v1.GroupServiceListMembersRequest.group_reference:type_name -> controlplane.v1.IdentityReference 27, // 12: controlplane.v1.GroupServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest @@ -1913,42 +2033,44 @@ var file_controlplane_v1_group_proto_depIdxs = []int32{ 28, // 18: controlplane.v1.GroupServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse 29, // 19: controlplane.v1.PendingGroupInvitation.invited_by:type_name -> controlplane.v1.User 30, // 20: controlplane.v1.PendingGroupInvitation.created_at:type_name -> google.protobuf.Timestamp - 29, // 21: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User - 30, // 22: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp - 30, // 23: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp - 26, // 24: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 26, // 25: controlplane.v1.GroupServiceListProjectsRequest.group_reference:type_name -> controlplane.v1.IdentityReference - 27, // 26: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 24, // 27: controlplane.v1.GroupServiceListProjectsResponse.projects:type_name -> controlplane.v1.ProjectInfo - 28, // 28: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 30, // 29: controlplane.v1.ProjectInfo.created_at:type_name -> google.protobuf.Timestamp - 0, // 30: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest - 2, // 31: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest - 4, // 32: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest - 6, // 33: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest - 8, // 34: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest - 11, // 35: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest - 12, // 36: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest - 14, // 37: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest - 20, // 38: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - 16, // 39: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest - 22, // 40: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest - 1, // 41: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse - 3, // 42: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse - 5, // 43: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse - 7, // 44: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse - 9, // 45: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse - 10, // 46: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse - 13, // 47: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse - 15, // 48: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse - 21, // 49: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - 17, // 50: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse - 23, // 51: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse - 41, // [41:52] is the sub-list for method output_type - 30, // [30:41] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 30, // 21: controlplane.v1.Group.created_at:type_name -> google.protobuf.Timestamp + 30, // 22: controlplane.v1.Group.updated_at:type_name -> google.protobuf.Timestamp + 29, // 23: controlplane.v1.GroupMember.user:type_name -> controlplane.v1.User + 30, // 24: controlplane.v1.GroupMember.created_at:type_name -> google.protobuf.Timestamp + 30, // 25: controlplane.v1.GroupMember.updated_at:type_name -> google.protobuf.Timestamp + 26, // 26: controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 26, // 27: controlplane.v1.GroupServiceListProjectsRequest.group_reference:type_name -> controlplane.v1.IdentityReference + 27, // 28: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 25, // 29: controlplane.v1.GroupServiceListProjectsResponse.projects:type_name -> controlplane.v1.ProjectInfo + 28, // 30: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 30, // 31: controlplane.v1.ProjectInfo.created_at:type_name -> google.protobuf.Timestamp + 0, // 32: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest + 2, // 33: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest + 4, // 34: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest + 6, // 35: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest + 8, // 36: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest + 11, // 37: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest + 12, // 38: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest + 14, // 39: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest + 21, // 40: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + 16, // 41: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest + 23, // 42: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest + 1, // 43: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse + 3, // 44: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse + 5, // 45: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse + 7, // 46: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse + 9, // 47: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse + 10, // 48: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse + 13, // 49: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse + 15, // 50: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse + 22, // 51: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + 17, // 52: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse + 24, // 53: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse + 43, // [43:54] is the sub-list for method output_type + 32, // [32:43] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name } func init() { file_controlplane_v1_group_proto_init() } @@ -2189,7 +2311,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupMember); i { + switch v := v.(*Group); i { case 0: return &v.state case 1: @@ -2201,7 +2323,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceUpdateMemberMaintainerStatusRequest); i { + switch v := v.(*GroupMember); i { case 0: return &v.state case 1: @@ -2213,7 +2335,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceUpdateMemberMaintainerStatusResponse); i { + switch v := v.(*GroupServiceUpdateMemberMaintainerStatusRequest); i { case 0: return &v.state case 1: @@ -2225,7 +2347,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceListProjectsRequest); i { + switch v := v.(*GroupServiceUpdateMemberMaintainerStatusResponse); i { case 0: return &v.state case 1: @@ -2237,7 +2359,7 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupServiceListProjectsResponse); i { + switch v := v.(*GroupServiceListProjectsRequest); i { case 0: return &v.state case 1: @@ -2249,6 +2371,18 @@ func file_controlplane_v1_group_proto_init() { } } file_controlplane_v1_group_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupServiceListProjectsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controlplane_v1_group_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ProjectInfo); i { case 0: return &v.state @@ -2265,14 +2399,14 @@ func file_controlplane_v1_group_proto_init() { file_controlplane_v1_group_proto_msgTypes[6].OneofWrappers = []interface{}{} file_controlplane_v1_group_proto_msgTypes[11].OneofWrappers = []interface{}{} file_controlplane_v1_group_proto_msgTypes[18].OneofWrappers = []interface{}{} - file_controlplane_v1_group_proto_msgTypes[24].OneofWrappers = []interface{}{} + file_controlplane_v1_group_proto_msgTypes[25].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_group_proto_rawDesc, NumEnums: 0, - NumMessages: 25, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/app/controlplane/api/controlplane/v1/group.proto b/app/controlplane/api/controlplane/v1/group.proto index edc12dd6c..93d26c3e9 100644 --- a/app/controlplane/api/controlplane/v1/group.proto +++ b/app/controlplane/api/controlplane/v1/group.proto @@ -193,6 +193,24 @@ message PendingGroupInvitation { string invitation_id = 4; } +// Group represents a collection of users with shared access to resources +message Group { + // Unique identifier for the group + string id = 1; + // Human-readable name of the group + string name = 2; + // Additional details about the group's purpose + string description = 3; + // UUID of the organization that this group belongs to + string organization_id = 4; + // Count of members in the group + int32 member_count = 5; + // Timestamp when the group was created + google.protobuf.Timestamp created_at = 6; + // Timestamp when the group was last modified + google.protobuf.Timestamp updated_at = 7; +} + // GroupMember represents a user's membership within a group with their role information message GroupMember { // The user who is a member of the group diff --git a/app/controlplane/api/controlplane/v1/project.pb.go b/app/controlplane/api/controlplane/v1/project.pb.go index 60506b1a1..11de6686f 100644 --- a/app/controlplane/api/controlplane/v1/project.pb.go +++ b/app/controlplane/api/controlplane/v1/project.pb.go @@ -37,6 +37,59 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// ProjectMemberRole defines the roles a member can have in a project +type ProjectMemberRole int32 + +const ( + // Default role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 + // Admin role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 + // Viewer role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 +) + +// Enum value maps for ProjectMemberRole. +var ( + ProjectMemberRole_name = map[int32]string{ + 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", + 1: "PROJECT_MEMBER_ROLE_ADMIN", + 2: "PROJECT_MEMBER_ROLE_VIEWER", + } + ProjectMemberRole_value = map[string]int32{ + "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, + "PROJECT_MEMBER_ROLE_ADMIN": 1, + "PROJECT_MEMBER_ROLE_VIEWER": 2, + } +) + +func (x ProjectMemberRole) Enum() *ProjectMemberRole { + p := new(ProjectMemberRole) + *p = x + return p +} + +func (x ProjectMemberRole) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { + return file_controlplane_v1_project_proto_enumTypes[0].Descriptor() +} + +func (ProjectMemberRole) Type() protoreflect.EnumType { + return &file_controlplane_v1_project_proto_enumTypes[0] +} + +func (x ProjectMemberRole) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProjectMemberRole.Descriptor instead. +func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} +} + // ProjectServiceListMembersRequest contains the information needed to list members of a project type ProjectServiceListMembersRequest struct { state protoimpl.MessageState @@ -153,6 +206,128 @@ func (x *ProjectServiceListMembersResponse) GetPagination() *OffsetPaginationRes return nil } +// ProjectMember represents an user or group who is a member of a project +type ProjectMember struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Subject can be either a user or a group + // + // Types that are assignable to Subject: + // + // *ProjectMember_User + // *ProjectMember_Group + Subject isProjectMember_Subject `protobuf_oneof:"subject"` + // The role of the user in the project + Role ProjectMemberRole `protobuf:"varint,3,opt,name=role,proto3,enum=controlplane.v1.ProjectMemberRole" json:"role,omitempty"` + // Timestamp when the project membership was created + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Timestamp when the project membership was last modified + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + // The ID of latest project version this member is associated with + LatestProjectVersionId string `protobuf:"bytes,6,opt,name=latest_project_version_id,json=latestProjectVersionId,proto3" json:"latest_project_version_id,omitempty"` +} + +func (x *ProjectMember) Reset() { + *x = ProjectMember{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_project_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProjectMember) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProjectMember) ProtoMessage() {} + +func (x *ProjectMember) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_project_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProjectMember.ProtoReflect.Descriptor instead. +func (*ProjectMember) Descriptor() ([]byte, []int) { + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} +} + +func (m *ProjectMember) GetSubject() isProjectMember_Subject { + if m != nil { + return m.Subject + } + return nil +} + +func (x *ProjectMember) GetUser() *User { + if x, ok := x.GetSubject().(*ProjectMember_User); ok { + return x.User + } + return nil +} + +func (x *ProjectMember) GetGroup() *Group { + if x, ok := x.GetSubject().(*ProjectMember_Group); ok { + return x.Group + } + return nil +} + +func (x *ProjectMember) GetRole() ProjectMemberRole { + if x != nil { + return x.Role + } + return ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED +} + +func (x *ProjectMember) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ProjectMember) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *ProjectMember) GetLatestProjectVersionId() string { + if x != nil { + return x.LatestProjectVersionId + } + return "" +} + +type isProjectMember_Subject interface { + isProjectMember_Subject() +} + +type ProjectMember_User struct { + // The user who is a member of the project + User *User `protobuf:"bytes,1,opt,name=user,proto3,oneof"` +} + +type ProjectMember_Group struct { + // The group who is a member of the project + Group *Group `protobuf:"bytes,2,opt,name=group,proto3,oneof"` +} + +func (*ProjectMember_User) isProjectMember_Subject() {} + +func (*ProjectMember_Group) isProjectMember_Subject() {} + // ProjectServiceAddMemberRequest contains the information needed to add a user to a project type ProjectServiceAddMemberRequest struct { state protoimpl.MessageState @@ -170,7 +345,7 @@ type ProjectServiceAddMemberRequest struct { func (x *ProjectServiceAddMemberRequest) Reset() { *x = ProjectServiceAddMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[2] + mi := &file_controlplane_v1_project_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -183,7 +358,7 @@ func (x *ProjectServiceAddMemberRequest) String() string { func (*ProjectServiceAddMemberRequest) ProtoMessage() {} func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[2] + mi := &file_controlplane_v1_project_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -196,7 +371,7 @@ func (x *ProjectServiceAddMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{2} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} } func (x *ProjectServiceAddMemberRequest) GetProjectReference() *IdentityReference { @@ -230,7 +405,7 @@ type ProjectServiceAddMemberResponse struct { func (x *ProjectServiceAddMemberResponse) Reset() { *x = ProjectServiceAddMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[3] + mi := &file_controlplane_v1_project_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -243,7 +418,7 @@ func (x *ProjectServiceAddMemberResponse) String() string { func (*ProjectServiceAddMemberResponse) ProtoMessage() {} func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[3] + mi := &file_controlplane_v1_project_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -256,7 +431,7 @@ func (x *ProjectServiceAddMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectServiceAddMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceAddMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{3} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} } type ProjectServiceRemoveMemberRequest struct { @@ -273,7 +448,7 @@ type ProjectServiceRemoveMemberRequest struct { func (x *ProjectServiceRemoveMemberRequest) Reset() { *x = ProjectServiceRemoveMemberRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[4] + mi := &file_controlplane_v1_project_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -286,7 +461,7 @@ func (x *ProjectServiceRemoveMemberRequest) String() string { func (*ProjectServiceRemoveMemberRequest) ProtoMessage() {} func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[4] + mi := &file_controlplane_v1_project_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -299,7 +474,7 @@ func (x *ProjectServiceRemoveMemberRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{4} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} } func (x *ProjectServiceRemoveMemberRequest) GetProjectReference() *IdentityReference { @@ -326,7 +501,7 @@ type ProjectServiceRemoveMemberResponse struct { func (x *ProjectServiceRemoveMemberResponse) Reset() { *x = ProjectServiceRemoveMemberResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[5] + mi := &file_controlplane_v1_project_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -339,7 +514,7 @@ func (x *ProjectServiceRemoveMemberResponse) String() string { func (*ProjectServiceRemoveMemberResponse) ProtoMessage() {} func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[5] + mi := &file_controlplane_v1_project_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -352,7 +527,7 @@ func (x *ProjectServiceRemoveMemberResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ProjectServiceRemoveMemberResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceRemoveMemberResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{5} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} } // ProjectMembershipReference is used to reference a user or group in the context of project membership @@ -373,7 +548,7 @@ type ProjectMembershipReference struct { func (x *ProjectMembershipReference) Reset() { *x = ProjectMembershipReference{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -386,7 +561,7 @@ func (x *ProjectMembershipReference) String() string { func (*ProjectMembershipReference) ProtoMessage() {} func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[6] + mi := &file_controlplane_v1_project_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -399,7 +574,7 @@ func (x *ProjectMembershipReference) ProtoReflect() protoreflect.Message { // Deprecated: Use ProjectMembershipReference.ProtoReflect.Descriptor instead. func (*ProjectMembershipReference) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{6} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} } func (m *ProjectMembershipReference) GetMembershipReference() isProjectMembershipReference_MembershipReference { @@ -459,7 +634,7 @@ type ProjectServiceUpdateMemberRoleRequest struct { func (x *ProjectServiceUpdateMemberRoleRequest) Reset() { *x = ProjectServiceUpdateMemberRoleRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -472,7 +647,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) String() string { func (*ProjectServiceUpdateMemberRoleRequest) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[7] + mi := &file_controlplane_v1_project_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -485,7 +660,7 @@ func (x *ProjectServiceUpdateMemberRoleRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use ProjectServiceUpdateMemberRoleRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{7} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} } func (x *ProjectServiceUpdateMemberRoleRequest) GetProjectReference() *IdentityReference { @@ -519,7 +694,7 @@ type ProjectServiceUpdateMemberRoleResponse struct { func (x *ProjectServiceUpdateMemberRoleResponse) Reset() { *x = ProjectServiceUpdateMemberRoleResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -532,7 +707,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) String() string { func (*ProjectServiceUpdateMemberRoleResponse) ProtoMessage() {} func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[8] + mi := &file_controlplane_v1_project_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -545,7 +720,7 @@ func (x *ProjectServiceUpdateMemberRoleResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use ProjectServiceUpdateMemberRoleResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceUpdateMemberRoleResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{8} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} } type ProjectServiceListPendingInvitationsRequest struct { @@ -562,7 +737,7 @@ type ProjectServiceListPendingInvitationsRequest struct { func (x *ProjectServiceListPendingInvitationsRequest) Reset() { *x = ProjectServiceListPendingInvitationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -575,7 +750,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) String() string { func (*ProjectServiceListPendingInvitationsRequest) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[9] + mi := &file_controlplane_v1_project_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -588,7 +763,7 @@ func (x *ProjectServiceListPendingInvitationsRequest) ProtoReflect() protoreflec // Deprecated: Use ProjectServiceListPendingInvitationsRequest.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{9} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} } func (x *ProjectServiceListPendingInvitationsRequest) GetProjectReference() *IdentityReference { @@ -620,7 +795,7 @@ type ProjectServiceListPendingInvitationsResponse struct { func (x *ProjectServiceListPendingInvitationsResponse) Reset() { *x = ProjectServiceListPendingInvitationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -633,7 +808,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) String() string { func (*ProjectServiceListPendingInvitationsResponse) ProtoMessage() {} func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[10] + mi := &file_controlplane_v1_project_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -646,7 +821,7 @@ func (x *ProjectServiceListPendingInvitationsResponse) ProtoReflect() protorefle // Deprecated: Use ProjectServiceListPendingInvitationsResponse.ProtoReflect.Descriptor instead. func (*ProjectServiceListPendingInvitationsResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{10} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} } func (x *ProjectServiceListPendingInvitationsResponse) GetInvitations() []*PendingProjectInvitation { @@ -682,7 +857,7 @@ type PendingProjectInvitation struct { func (x *PendingProjectInvitation) Reset() { *x = PendingProjectInvitation{} if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -695,7 +870,7 @@ func (x *PendingProjectInvitation) String() string { func (*PendingProjectInvitation) ProtoMessage() {} func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_project_proto_msgTypes[11] + mi := &file_controlplane_v1_project_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -708,7 +883,7 @@ func (x *PendingProjectInvitation) ProtoReflect() protoreflect.Message { // Deprecated: Use PendingProjectInvitation.ProtoReflect.Descriptor instead. func (*PendingProjectInvitation) Descriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{11} + return file_controlplane_v1_project_proto_rawDescGZIP(), []int{12} } func (x *PendingProjectInvitation) GetUserEmail() string { @@ -781,56 +956,30 @@ var file_controlplane_v1_project_proto_rawDesc = []byte{ 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0xe0, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, + 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x0e, 0xba, - 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, + 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, + 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x19, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x16, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x1e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x21, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, - 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, - 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, - 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x0a, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, - 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, - 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xa7, 0x02, 0x0a, 0x25, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, @@ -842,102 +991,157 @@ var file_controlplane_v1_project_proto_rawDesc = []byte{ 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, - 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6e, 0x65, - 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x46, + 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, + 0x42, 0x0e, 0xba, 0x48, 0x0b, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, + 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x21, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, - 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, + 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xad, + 0x01, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x28, 0x0a, + 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x48, 0x00, 0x52, 0x09, 0x75, 0x73, + 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xa7, + 0x02, 0x0a, 0x25, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, + 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x5e, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x45, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, + 0x07, 0x6e, 0x65, 0x77, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x2b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xec, 0x01, 0x0a, 0x18, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, - 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, - 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x69, - 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, - 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, - 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x32, 0x8f, 0x05, 0x0a, 0x0e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, - 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x63, + 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x01, 0x0a, 0x2c, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xec, + 0x01, 0x0a, 0x18, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0a, 0x75, + 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x60, 0x01, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x39, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x48, 0x00, + 0x52, 0x09, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x42, 0x79, 0x88, 0x01, 0x01, 0x12, 0x39, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, + 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x2a, 0x77, 0x0a, + 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, + 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, + 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x4a, 0x45, + 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x41, + 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, + 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x56, 0x49, + 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x32, 0x8f, 0x05, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, + 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, - 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, - 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, + 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, + 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, + 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -952,63 +1156,70 @@ func file_controlplane_v1_project_proto_rawDescGZIP() []byte { return file_controlplane_v1_project_proto_rawDescData } -var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_controlplane_v1_project_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_controlplane_v1_project_proto_goTypes = []interface{}{ - (*ProjectServiceListMembersRequest)(nil), // 0: controlplane.v1.ProjectServiceListMembersRequest - (*ProjectServiceListMembersResponse)(nil), // 1: controlplane.v1.ProjectServiceListMembersResponse - (*ProjectServiceAddMemberRequest)(nil), // 2: controlplane.v1.ProjectServiceAddMemberRequest - (*ProjectServiceAddMemberResponse)(nil), // 3: controlplane.v1.ProjectServiceAddMemberResponse - (*ProjectServiceRemoveMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceRemoveMemberRequest - (*ProjectServiceRemoveMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceRemoveMemberResponse - (*ProjectMembershipReference)(nil), // 6: controlplane.v1.ProjectMembershipReference - (*ProjectServiceUpdateMemberRoleRequest)(nil), // 7: controlplane.v1.ProjectServiceUpdateMemberRoleRequest - (*ProjectServiceUpdateMemberRoleResponse)(nil), // 8: controlplane.v1.ProjectServiceUpdateMemberRoleResponse - (*ProjectServiceListPendingInvitationsRequest)(nil), // 9: controlplane.v1.ProjectServiceListPendingInvitationsRequest - (*ProjectServiceListPendingInvitationsResponse)(nil), // 10: controlplane.v1.ProjectServiceListPendingInvitationsResponse - (*PendingProjectInvitation)(nil), // 11: controlplane.v1.PendingProjectInvitation - (*IdentityReference)(nil), // 12: controlplane.v1.IdentityReference - (*OffsetPaginationRequest)(nil), // 13: controlplane.v1.OffsetPaginationRequest - (*ProjectMember)(nil), // 14: controlplane.v1.ProjectMember - (*OffsetPaginationResponse)(nil), // 15: controlplane.v1.OffsetPaginationResponse - (ProjectMemberRole)(0), // 16: controlplane.v1.ProjectMemberRole + (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole + (*ProjectServiceListMembersRequest)(nil), // 1: controlplane.v1.ProjectServiceListMembersRequest + (*ProjectServiceListMembersResponse)(nil), // 2: controlplane.v1.ProjectServiceListMembersResponse + (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember + (*ProjectServiceAddMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceAddMemberRequest + (*ProjectServiceAddMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceAddMemberResponse + (*ProjectServiceRemoveMemberRequest)(nil), // 6: controlplane.v1.ProjectServiceRemoveMemberRequest + (*ProjectServiceRemoveMemberResponse)(nil), // 7: controlplane.v1.ProjectServiceRemoveMemberResponse + (*ProjectMembershipReference)(nil), // 8: controlplane.v1.ProjectMembershipReference + (*ProjectServiceUpdateMemberRoleRequest)(nil), // 9: controlplane.v1.ProjectServiceUpdateMemberRoleRequest + (*ProjectServiceUpdateMemberRoleResponse)(nil), // 10: controlplane.v1.ProjectServiceUpdateMemberRoleResponse + (*ProjectServiceListPendingInvitationsRequest)(nil), // 11: controlplane.v1.ProjectServiceListPendingInvitationsRequest + (*ProjectServiceListPendingInvitationsResponse)(nil), // 12: controlplane.v1.ProjectServiceListPendingInvitationsResponse + (*PendingProjectInvitation)(nil), // 13: controlplane.v1.PendingProjectInvitation + (*IdentityReference)(nil), // 14: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 15: controlplane.v1.OffsetPaginationRequest + (*OffsetPaginationResponse)(nil), // 16: controlplane.v1.OffsetPaginationResponse (*User)(nil), // 17: controlplane.v1.User - (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp + (*Group)(nil), // 18: controlplane.v1.Group + (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp } var file_controlplane_v1_project_proto_depIdxs = []int32{ - 12, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 13, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 14, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember - 15, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 12, // 4: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 6, // 5: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 16, // 6: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole - 12, // 7: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 6, // 8: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 12, // 9: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference - 12, // 10: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 6, // 11: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 16, // 12: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole - 12, // 13: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 13, // 14: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 11, // 15: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation - 15, // 16: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 17, // 17: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User - 18, // 18: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp - 0, // 19: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest - 2, // 20: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest - 4, // 21: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest - 7, // 22: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest - 9, // 23: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest - 1, // 24: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse - 3, // 25: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse - 5, // 26: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse - 8, // 27: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse - 10, // 28: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse - 24, // [24:29] is the sub-list for method output_type - 19, // [19:24] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 14, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 15, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 3, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember + 16, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 17, // 4: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User + 18, // 5: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group + 0, // 6: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole + 19, // 7: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp + 19, // 8: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp + 14, // 9: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 10: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 0, // 11: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole + 14, // 12: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 13: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 14, // 14: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference + 14, // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 8, // 16: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 0, // 17: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole + 14, // 18: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 15, // 19: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 13, // 20: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation + 16, // 21: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 17, // 22: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User + 19, // 23: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp + 1, // 24: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest + 4, // 25: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest + 6, // 26: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest + 9, // 27: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest + 11, // 28: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest + 2, // 29: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse + 5, // 30: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse + 7, // 31: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse + 10, // 32: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse + 12, // 33: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse + 29, // [29:34] is the sub-list for method output_type + 24, // [24:29] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_controlplane_v1_project_proto_init() } @@ -1046,7 +1257,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAddMemberRequest); i { + switch v := v.(*ProjectMember); i { case 0: return &v.state case 1: @@ -1058,7 +1269,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceAddMemberResponse); i { + switch v := v.(*ProjectServiceAddMemberRequest); i { case 0: return &v.state case 1: @@ -1070,7 +1281,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceRemoveMemberRequest); i { + switch v := v.(*ProjectServiceAddMemberResponse); i { case 0: return &v.state case 1: @@ -1082,7 +1293,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceRemoveMemberResponse); i { + switch v := v.(*ProjectServiceRemoveMemberRequest); i { case 0: return &v.state case 1: @@ -1094,7 +1305,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectMembershipReference); i { + switch v := v.(*ProjectServiceRemoveMemberResponse); i { case 0: return &v.state case 1: @@ -1106,7 +1317,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceUpdateMemberRoleRequest); i { + switch v := v.(*ProjectMembershipReference); i { case 0: return &v.state case 1: @@ -1118,7 +1329,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceUpdateMemberRoleResponse); i { + switch v := v.(*ProjectServiceUpdateMemberRoleRequest); i { case 0: return &v.state case 1: @@ -1130,7 +1341,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceListPendingInvitationsRequest); i { + switch v := v.(*ProjectServiceUpdateMemberRoleResponse); i { case 0: return &v.state case 1: @@ -1142,7 +1353,7 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectServiceListPendingInvitationsResponse); i { + switch v := v.(*ProjectServiceListPendingInvitationsRequest); i { case 0: return &v.state case 1: @@ -1154,6 +1365,18 @@ func file_controlplane_v1_project_proto_init() { } } file_controlplane_v1_project_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProjectServiceListPendingInvitationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controlplane_v1_project_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PendingProjectInvitation); i { case 0: return &v.state @@ -1166,23 +1389,28 @@ func file_controlplane_v1_project_proto_init() { } } } - file_controlplane_v1_project_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_controlplane_v1_project_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*ProjectMember_User)(nil), + (*ProjectMember_Group)(nil), + } + file_controlplane_v1_project_proto_msgTypes[7].OneofWrappers = []interface{}{ (*ProjectMembershipReference_UserEmail)(nil), (*ProjectMembershipReference_GroupReference)(nil), } - file_controlplane_v1_project_proto_msgTypes[11].OneofWrappers = []interface{}{} + file_controlplane_v1_project_proto_msgTypes[12].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_project_proto_rawDesc, - NumEnums: 0, - NumMessages: 12, + NumEnums: 1, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, GoTypes: file_controlplane_v1_project_proto_goTypes, DependencyIndexes: file_controlplane_v1_project_proto_depIdxs, + EnumInfos: file_controlplane_v1_project_proto_enumTypes, MessageInfos: file_controlplane_v1_project_proto_msgTypes, }.Build() File_controlplane_v1_project_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/project.proto b/app/controlplane/api/controlplane/v1/project.proto index 2b9ec0d4b..5ea87d7b6 100644 --- a/app/controlplane/api/controlplane/v1/project.proto +++ b/app/controlplane/api/controlplane/v1/project.proto @@ -51,6 +51,25 @@ message ProjectServiceListMembersResponse { OffsetPaginationResponse pagination = 2; } +// ProjectMember represents an user or group who is a member of a project +message ProjectMember { + // Subject can be either a user or a group + oneof subject { + // The user who is a member of the project + User user = 1; + // The group who is a member of the project + Group group = 2; + } + // The role of the user in the project + ProjectMemberRole role = 3; + // Timestamp when the project membership was created + google.protobuf.Timestamp created_at = 4; + // Timestamp when the project membership was last modified + google.protobuf.Timestamp updated_at = 5; + // The ID of latest project version this member is associated with + string latest_project_version_id = 6; +} + // ProjectServiceAddMemberRequest contains the information needed to add a user to a project message ProjectServiceAddMemberRequest { // IdentityReference is used to specify the project by either its ID or name @@ -91,6 +110,16 @@ message ProjectMembershipReference { } } +// ProjectMemberRole defines the roles a member can have in a project +enum ProjectMemberRole { + // Default role for a project member + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; + // Admin role for a project member + PROJECT_MEMBER_ROLE_ADMIN = 1; + // Viewer role for a project member + PROJECT_MEMBER_ROLE_VIEWER = 2; +} + // ProjectServiceUpdateMemberRoleRequest contains the information needed to update a member's role in a project message ProjectServiceUpdateMemberRoleRequest { // IdentityReference is used to specify the project by either its ID or name diff --git a/app/controlplane/api/controlplane/v1/shared_message.pb.go b/app/controlplane/api/controlplane/v1/shared_message.pb.go index b9efa67b3..285aef31d 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.pb.go +++ b/app/controlplane/api/controlplane/v1/shared_message.pb.go @@ -25,7 +25,7 @@ import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" + _ "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -37,59 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// ProjectMemberRole defines the roles a member can have in a project -type ProjectMemberRole int32 - -const ( - // Default role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 - // Admin role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 - // Viewer role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 -) - -// Enum value maps for ProjectMemberRole. -var ( - ProjectMemberRole_name = map[int32]string{ - 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", - 1: "PROJECT_MEMBER_ROLE_ADMIN", - 2: "PROJECT_MEMBER_ROLE_VIEWER", - } - ProjectMemberRole_value = map[string]int32{ - "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, - "PROJECT_MEMBER_ROLE_ADMIN": 1, - "PROJECT_MEMBER_ROLE_VIEWER": 2, - } -) - -func (x ProjectMemberRole) Enum() *ProjectMemberRole { - p := new(ProjectMemberRole) - *p = x - return p -} - -func (x ProjectMemberRole) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { - return file_controlplane_v1_shared_message_proto_enumTypes[0].Descriptor() -} - -func (ProjectMemberRole) Type() protoreflect.EnumType { - return &file_controlplane_v1_shared_message_proto_enumTypes[0] -} - -func (x ProjectMemberRole) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ProjectMemberRole.Descriptor instead. -func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { - return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{0} -} - // IdentityReference represents a reference to an identity in the system. type IdentityReference struct { state protoimpl.MessageState @@ -148,231 +95,6 @@ func (x *IdentityReference) GetName() string { return "" } -// Group represents a collection of users with shared access to resources -type Group struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Unique identifier for the group - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Human-readable name of the group - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // Additional details about the group's purpose - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - // UUID of the organization that this group belongs to - OrganizationId string `protobuf:"bytes,4,opt,name=organization_id,json=organizationId,proto3" json:"organization_id,omitempty"` - // Count of members in the group - MemberCount int32 `protobuf:"varint,5,opt,name=member_count,json=memberCount,proto3" json:"member_count,omitempty"` - // Timestamp when the group was created - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // Timestamp when the group was last modified - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` -} - -func (x *Group) Reset() { - *x = Group{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_shared_message_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Group) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Group) ProtoMessage() {} - -func (x *Group) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_shared_message_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Group.ProtoReflect.Descriptor instead. -func (*Group) Descriptor() ([]byte, []int) { - return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{1} -} - -func (x *Group) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Group) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Group) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Group) GetOrganizationId() string { - if x != nil { - return x.OrganizationId - } - return "" -} - -func (x *Group) GetMemberCount() int32 { - if x != nil { - return x.MemberCount - } - return 0 -} - -func (x *Group) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Group) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -// ProjectMember represents an user or group who is a member of a project -type ProjectMember struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Subject can be either a user or a group - // - // Types that are assignable to Subject: - // - // *ProjectMember_User - // *ProjectMember_Group - Subject isProjectMember_Subject `protobuf_oneof:"subject"` - // The role of the user in the project - Role ProjectMemberRole `protobuf:"varint,3,opt,name=role,proto3,enum=controlplane.v1.ProjectMemberRole" json:"role,omitempty"` - // Timestamp when the project membership was created - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // Timestamp when the project membership was last modified - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - // The ID of latest project version this member is associated with - LatestProjectVersionId string `protobuf:"bytes,6,opt,name=latest_project_version_id,json=latestProjectVersionId,proto3" json:"latest_project_version_id,omitempty"` -} - -func (x *ProjectMember) Reset() { - *x = ProjectMember{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_shared_message_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProjectMember) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProjectMember) ProtoMessage() {} - -func (x *ProjectMember) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_shared_message_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProjectMember.ProtoReflect.Descriptor instead. -func (*ProjectMember) Descriptor() ([]byte, []int) { - return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{2} -} - -func (m *ProjectMember) GetSubject() isProjectMember_Subject { - if m != nil { - return m.Subject - } - return nil -} - -func (x *ProjectMember) GetUser() *User { - if x, ok := x.GetSubject().(*ProjectMember_User); ok { - return x.User - } - return nil -} - -func (x *ProjectMember) GetGroup() *Group { - if x, ok := x.GetSubject().(*ProjectMember_Group); ok { - return x.Group - } - return nil -} - -func (x *ProjectMember) GetRole() ProjectMemberRole { - if x != nil { - return x.Role - } - return ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED -} - -func (x *ProjectMember) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *ProjectMember) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *ProjectMember) GetLatestProjectVersionId() string { - if x != nil { - return x.LatestProjectVersionId - } - return "" -} - -type isProjectMember_Subject interface { - isProjectMember_Subject() -} - -type ProjectMember_User struct { - // The user who is a member of the project - User *User `protobuf:"bytes,1,opt,name=user,proto3,oneof"` -} - -type ProjectMember_Group struct { - // The group who is a member of the project - Group *Group `protobuf:"bytes,2,opt,name=group,proto3,oneof"` -} - -func (*ProjectMember_User) isProjectMember_Subject() {} - -func (*ProjectMember_Group) isProjectMember_Subject() {} - var File_controlplane_v1_shared_message_proto protoreflect.FileDescriptor var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ @@ -381,11 +103,11 @@ var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd0, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, @@ -402,59 +124,12 @@ var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, - 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8f, 0x02, 0x0a, 0x05, 0x47, 0x72, - 0x6f, 0x75, 0x70, 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, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x67, - 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 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, 0xe0, 0x02, 0x0a, 0x0d, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2b, 0x0a, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x05, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x48, 0x00, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x04, 0x72, 0x6f, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, - 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, - 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x19, 0x6c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x6c, 0x61, 0x74, - 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2a, 0x77, - 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, - 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x4a, - 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, - 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x56, - 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, - 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, - 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, + 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -469,29 +144,16 @@ func file_controlplane_v1_shared_message_proto_rawDescGZIP() []byte { return file_controlplane_v1_shared_message_proto_rawDescData } -var file_controlplane_v1_shared_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_controlplane_v1_shared_message_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_controlplane_v1_shared_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_controlplane_v1_shared_message_proto_goTypes = []interface{}{ - (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole - (*IdentityReference)(nil), // 1: controlplane.v1.IdentityReference - (*Group)(nil), // 2: controlplane.v1.Group - (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember - (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp - (*User)(nil), // 5: controlplane.v1.User + (*IdentityReference)(nil), // 0: controlplane.v1.IdentityReference } var file_controlplane_v1_shared_message_proto_depIdxs = []int32{ - 4, // 0: controlplane.v1.Group.created_at:type_name -> google.protobuf.Timestamp - 4, // 1: controlplane.v1.Group.updated_at:type_name -> google.protobuf.Timestamp - 5, // 2: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User - 2, // 3: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group - 0, // 4: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole - 4, // 5: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp - 4, // 6: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp - 7, // [7:7] is the sub-list for method output_type - 7, // [7:7] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_controlplane_v1_shared_message_proto_init() } @@ -513,49 +175,20 @@ func file_controlplane_v1_shared_message_proto_init() { return nil } } - file_controlplane_v1_shared_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Group); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_shared_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProjectMember); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } file_controlplane_v1_shared_message_proto_msgTypes[0].OneofWrappers = []interface{}{} - file_controlplane_v1_shared_message_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*ProjectMember_User)(nil), - (*ProjectMember_Group)(nil), - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_shared_message_proto_rawDesc, - NumEnums: 1, - NumMessages: 3, + NumEnums: 0, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_controlplane_v1_shared_message_proto_goTypes, DependencyIndexes: file_controlplane_v1_shared_message_proto_depIdxs, - EnumInfos: file_controlplane_v1_shared_message_proto_enumTypes, MessageInfos: file_controlplane_v1_shared_message_proto_msgTypes, }.Build() File_controlplane_v1_shared_message_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/shared_message.proto b/app/controlplane/api/controlplane/v1/shared_message.proto index 28fe60865..7be716b8b 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.proto +++ b/app/controlplane/api/controlplane/v1/shared_message.proto @@ -18,8 +18,8 @@ syntax = "proto3"; package controlplane.v1; import "buf/validate/validate.proto"; -import "google/protobuf/timestamp.proto"; import "controlplane/v1/response_messages.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; @@ -43,50 +43,3 @@ message IdentityReference { message: "either id or name must be provided, but not both." }; } - -// Group represents a collection of users with shared access to resources -message Group { - // Unique identifier for the group - string id = 1; - // Human-readable name of the group - string name = 2; - // Additional details about the group's purpose - string description = 3; - // UUID of the organization that this group belongs to - string organization_id = 4; - // Count of members in the group - int32 member_count = 5; - // Timestamp when the group was created - google.protobuf.Timestamp created_at = 6; - // Timestamp when the group was last modified - google.protobuf.Timestamp updated_at = 7; -} - -// ProjectMember represents an user or group who is a member of a project -message ProjectMember { - // Subject can be either a user or a group - oneof subject { - // The user who is a member of the project - User user = 1; - // The group who is a member of the project - Group group = 2; - } - // The role of the user in the project - ProjectMemberRole role = 3; - // Timestamp when the project membership was created - google.protobuf.Timestamp created_at = 4; - // Timestamp when the project membership was last modified - google.protobuf.Timestamp updated_at = 5; - // The ID of latest project version this member is associated with - string latest_project_version_id = 6; -} - -// ProjectMemberRole defines the roles a member can have in a project -enum ProjectMemberRole { - // Default role for a project member - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; - // Admin role for a project member - PROJECT_MEMBER_ROLE_ADMIN = 1; - // Viewer role for a project member - PROJECT_MEMBER_ROLE_VIEWER = 2; -} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts index e2eb7d645..3ef1932de 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts @@ -5,7 +5,7 @@ import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { Group, IdentityReference } from "./shared_message"; +import { IdentityReference } from "./shared_message"; export const protobufPackage = "controlplane.v1"; @@ -167,6 +167,24 @@ export interface PendingGroupInvitation { invitationId: string; } +/** Group represents a collection of users with shared access to resources */ +export interface Group { + /** Unique identifier for the group */ + id: string; + /** Human-readable name of the group */ + name: string; + /** Additional details about the group's purpose */ + description: string; + /** UUID of the organization that this group belongs to */ + organizationId: string; + /** Count of members in the group */ + memberCount: number; + /** Timestamp when the group was created */ + createdAt?: Date; + /** Timestamp when the group was last modified */ + updatedAt?: Date; +} + /** GroupMember represents a user's membership within a group with their role information */ export interface GroupMember { /** The user who is a member of the group */ @@ -1601,6 +1619,150 @@ export const PendingGroupInvitation = { }, }; +function createBaseGroup(): Group { + return { + id: "", + name: "", + description: "", + organizationId: "", + memberCount: 0, + createdAt: undefined, + updatedAt: undefined, + }; +} + +export const Group = { + encode(message: Group, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.description !== "") { + writer.uint32(26).string(message.description); + } + if (message.organizationId !== "") { + writer.uint32(34).string(message.organizationId); + } + if (message.memberCount !== 0) { + writer.uint32(40).int32(message.memberCount); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(50).fork()).ldelim(); + } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(58).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Group { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGroup(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.description = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.organizationId = reader.string(); + continue; + case 5: + if (tag !== 40) { + break; + } + + message.memberCount = reader.int32(); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 7: + if (tag !== 58) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Group { + return { + id: isSet(object.id) ? String(object.id) : "", + name: isSet(object.name) ? String(object.name) : "", + description: isSet(object.description) ? String(object.description) : "", + organizationId: isSet(object.organizationId) ? String(object.organizationId) : "", + memberCount: isSet(object.memberCount) ? Number(object.memberCount) : 0, + createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, + }; + }, + + toJSON(message: Group): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.name !== undefined && (obj.name = message.name); + message.description !== undefined && (obj.description = message.description); + message.organizationId !== undefined && (obj.organizationId = message.organizationId); + message.memberCount !== undefined && (obj.memberCount = Math.round(message.memberCount)); + message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); + return obj; + }, + + create, I>>(base?: I): Group { + return Group.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): Group { + const message = createBaseGroup(); + message.id = object.id ?? ""; + message.name = object.name ?? ""; + message.description = object.description ?? ""; + message.organizationId = object.organizationId ?? ""; + message.memberCount = object.memberCount ?? 0; + message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; + return message; + }, +}; + function createBaseGroupMember(): GroupMember { return { user: undefined, isMaintainer: false, createdAt: undefined, updatedAt: undefined }; } diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts index d7d04f376..2557c14fd 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts @@ -3,18 +3,56 @@ import { grpc } from "@improbable-eng/grpc-web"; import { BrowserHeaders } from "browser-headers"; import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; +import { Group } from "./group"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { - IdentityReference, - ProjectMember, - ProjectMemberRole, - projectMemberRoleFromJSON, - projectMemberRoleToJSON, -} from "./shared_message"; +import { IdentityReference } from "./shared_message"; export const protobufPackage = "controlplane.v1"; +/** ProjectMemberRole defines the roles a member can have in a project */ +export enum ProjectMemberRole { + /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, + /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ + PROJECT_MEMBER_ROLE_ADMIN = 1, + /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ + PROJECT_MEMBER_ROLE_VIEWER = 2, + UNRECOGNIZED = -1, +} + +export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { + switch (object) { + case 0: + case "PROJECT_MEMBER_ROLE_UNSPECIFIED": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; + case 1: + case "PROJECT_MEMBER_ROLE_ADMIN": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; + case 2: + case "PROJECT_MEMBER_ROLE_VIEWER": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; + case -1: + case "UNRECOGNIZED": + default: + return ProjectMemberRole.UNRECOGNIZED; + } +} + +export function projectMemberRoleToJSON(object: ProjectMemberRole): string { + switch (object) { + case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: + return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: + return "PROJECT_MEMBER_ROLE_ADMIN"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: + return "PROJECT_MEMBER_ROLE_VIEWER"; + case ProjectMemberRole.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + /** ProjectServiceListMembersRequest contains the information needed to list members of a project */ export interface ProjectServiceListMembersRequest { /** IdentityReference is used to specify the project by either its ID or name */ @@ -31,6 +69,26 @@ export interface ProjectServiceListMembersResponse { pagination?: OffsetPaginationResponse; } +/** ProjectMember represents an user or group who is a member of a project */ +export interface ProjectMember { + /** The user who is a member of the project */ + user?: + | User + | undefined; + /** The group who is a member of the project */ + group?: + | Group + | undefined; + /** The role of the user in the project */ + role: ProjectMemberRole; + /** Timestamp when the project membership was created */ + createdAt?: Date; + /** Timestamp when the project membership was last modified */ + updatedAt?: Date; + /** The ID of latest project version this member is associated with */ + latestProjectVersionId: string; +} + /** ProjectServiceAddMemberRequest contains the information needed to add a user to a project */ export interface ProjectServiceAddMemberRequest { /** IdentityReference is used to specify the project by either its ID or name */ @@ -276,6 +334,136 @@ export const ProjectServiceListMembersResponse = { }, }; +function createBaseProjectMember(): ProjectMember { + return { + user: undefined, + group: undefined, + role: 0, + createdAt: undefined, + updatedAt: undefined, + latestProjectVersionId: "", + }; +} + +export const ProjectMember = { + encode(message: ProjectMember, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.user !== undefined) { + User.encode(message.user, writer.uint32(10).fork()).ldelim(); + } + if (message.group !== undefined) { + Group.encode(message.group, writer.uint32(18).fork()).ldelim(); + } + if (message.role !== 0) { + writer.uint32(24).int32(message.role); + } + if (message.createdAt !== undefined) { + Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).ldelim(); + } + if (message.updatedAt !== undefined) { + Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(42).fork()).ldelim(); + } + if (message.latestProjectVersionId !== "") { + writer.uint32(50).string(message.latestProjectVersionId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ProjectMember { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseProjectMember(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.user = User.decode(reader, reader.uint32()); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.group = Group.decode(reader, reader.uint32()); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.role = reader.int32() as any; + continue; + case 4: + if (tag !== 34) { + break; + } + + message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); + continue; + case 6: + if (tag !== 50) { + break; + } + + message.latestProjectVersionId = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): ProjectMember { + return { + user: isSet(object.user) ? User.fromJSON(object.user) : undefined, + group: isSet(object.group) ? Group.fromJSON(object.group) : undefined, + role: isSet(object.role) ? projectMemberRoleFromJSON(object.role) : 0, + createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, + updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, + latestProjectVersionId: isSet(object.latestProjectVersionId) ? String(object.latestProjectVersionId) : "", + }; + }, + + toJSON(message: ProjectMember): unknown { + const obj: any = {}; + message.user !== undefined && (obj.user = message.user ? User.toJSON(message.user) : undefined); + message.group !== undefined && (obj.group = message.group ? Group.toJSON(message.group) : undefined); + message.role !== undefined && (obj.role = projectMemberRoleToJSON(message.role)); + message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); + message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); + message.latestProjectVersionId !== undefined && (obj.latestProjectVersionId = message.latestProjectVersionId); + return obj; + }, + + create, I>>(base?: I): ProjectMember { + return ProjectMember.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): ProjectMember { + const message = createBaseProjectMember(); + message.user = (object.user !== undefined && object.user !== null) ? User.fromPartial(object.user) : undefined; + message.group = (object.group !== undefined && object.group !== null) ? Group.fromPartial(object.group) : undefined; + message.role = object.role ?? 0; + message.createdAt = object.createdAt ?? undefined; + message.updatedAt = object.updatedAt ?? undefined; + message.latestProjectVersionId = object.latestProjectVersionId ?? ""; + return message; + }, +}; + function createBaseProjectServiceAddMemberRequest(): ProjectServiceAddMemberRequest { return { projectReference: undefined, memberReference: undefined, role: 0 }; } diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts index a882d6ac3..f8ccfe269 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts @@ -1,53 +1,8 @@ /* eslint-disable */ import _m0 from "protobufjs/minimal"; -import { Timestamp } from "../../google/protobuf/timestamp"; -import { User } from "./response_messages"; export const protobufPackage = "controlplane.v1"; -/** ProjectMemberRole defines the roles a member can have in a project */ -export enum ProjectMemberRole { - /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, - /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ - PROJECT_MEMBER_ROLE_ADMIN = 1, - /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ - PROJECT_MEMBER_ROLE_VIEWER = 2, - UNRECOGNIZED = -1, -} - -export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { - switch (object) { - case 0: - case "PROJECT_MEMBER_ROLE_UNSPECIFIED": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; - case 1: - case "PROJECT_MEMBER_ROLE_ADMIN": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; - case 2: - case "PROJECT_MEMBER_ROLE_VIEWER": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; - case -1: - case "UNRECOGNIZED": - default: - return ProjectMemberRole.UNRECOGNIZED; - } -} - -export function projectMemberRoleToJSON(object: ProjectMemberRole): string { - switch (object) { - case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: - return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: - return "PROJECT_MEMBER_ROLE_ADMIN"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: - return "PROJECT_MEMBER_ROLE_VIEWER"; - case ProjectMemberRole.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - /** IdentityReference represents a reference to an identity in the system. */ export interface IdentityReference { /** ID is optional, but if provided, it must be a valid UUID. */ @@ -58,44 +13,6 @@ export interface IdentityReference { name?: string | undefined; } -/** Group represents a collection of users with shared access to resources */ -export interface Group { - /** Unique identifier for the group */ - id: string; - /** Human-readable name of the group */ - name: string; - /** Additional details about the group's purpose */ - description: string; - /** UUID of the organization that this group belongs to */ - organizationId: string; - /** Count of members in the group */ - memberCount: number; - /** Timestamp when the group was created */ - createdAt?: Date; - /** Timestamp when the group was last modified */ - updatedAt?: Date; -} - -/** ProjectMember represents an user or group who is a member of a project */ -export interface ProjectMember { - /** The user who is a member of the project */ - user?: - | User - | undefined; - /** The group who is a member of the project */ - group?: - | Group - | undefined; - /** The role of the user in the project */ - role: ProjectMemberRole; - /** Timestamp when the project membership was created */ - createdAt?: Date; - /** Timestamp when the project membership was last modified */ - updatedAt?: Date; - /** The ID of latest project version this member is associated with */ - latestProjectVersionId: string; -} - function createBaseIdentityReference(): IdentityReference { return { id: undefined, name: undefined }; } @@ -167,280 +84,6 @@ export const IdentityReference = { }, }; -function createBaseGroup(): Group { - return { - id: "", - name: "", - description: "", - organizationId: "", - memberCount: 0, - createdAt: undefined, - updatedAt: undefined, - }; -} - -export const Group = { - encode(message: Group, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.id !== "") { - writer.uint32(10).string(message.id); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - if (message.description !== "") { - writer.uint32(26).string(message.description); - } - if (message.organizationId !== "") { - writer.uint32(34).string(message.organizationId); - } - if (message.memberCount !== 0) { - writer.uint32(40).int32(message.memberCount); - } - if (message.createdAt !== undefined) { - Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(50).fork()).ldelim(); - } - if (message.updatedAt !== undefined) { - Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(58).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): Group { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseGroup(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.id = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.name = reader.string(); - continue; - case 3: - if (tag !== 26) { - break; - } - - message.description = reader.string(); - continue; - case 4: - if (tag !== 34) { - break; - } - - message.organizationId = reader.string(); - continue; - case 5: - if (tag !== 40) { - break; - } - - message.memberCount = reader.int32(); - continue; - case 6: - if (tag !== 50) { - break; - } - - message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - case 7: - if (tag !== 58) { - break; - } - - message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): Group { - return { - id: isSet(object.id) ? String(object.id) : "", - name: isSet(object.name) ? String(object.name) : "", - description: isSet(object.description) ? String(object.description) : "", - organizationId: isSet(object.organizationId) ? String(object.organizationId) : "", - memberCount: isSet(object.memberCount) ? Number(object.memberCount) : 0, - createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, - updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, - }; - }, - - toJSON(message: Group): unknown { - const obj: any = {}; - message.id !== undefined && (obj.id = message.id); - message.name !== undefined && (obj.name = message.name); - message.description !== undefined && (obj.description = message.description); - message.organizationId !== undefined && (obj.organizationId = message.organizationId); - message.memberCount !== undefined && (obj.memberCount = Math.round(message.memberCount)); - message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); - message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); - return obj; - }, - - create, I>>(base?: I): Group { - return Group.fromPartial(base ?? {}); - }, - - fromPartial, I>>(object: I): Group { - const message = createBaseGroup(); - message.id = object.id ?? ""; - message.name = object.name ?? ""; - message.description = object.description ?? ""; - message.organizationId = object.organizationId ?? ""; - message.memberCount = object.memberCount ?? 0; - message.createdAt = object.createdAt ?? undefined; - message.updatedAt = object.updatedAt ?? undefined; - return message; - }, -}; - -function createBaseProjectMember(): ProjectMember { - return { - user: undefined, - group: undefined, - role: 0, - createdAt: undefined, - updatedAt: undefined, - latestProjectVersionId: "", - }; -} - -export const ProjectMember = { - encode(message: ProjectMember, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.user !== undefined) { - User.encode(message.user, writer.uint32(10).fork()).ldelim(); - } - if (message.group !== undefined) { - Group.encode(message.group, writer.uint32(18).fork()).ldelim(); - } - if (message.role !== 0) { - writer.uint32(24).int32(message.role); - } - if (message.createdAt !== undefined) { - Timestamp.encode(toTimestamp(message.createdAt), writer.uint32(34).fork()).ldelim(); - } - if (message.updatedAt !== undefined) { - Timestamp.encode(toTimestamp(message.updatedAt), writer.uint32(42).fork()).ldelim(); - } - if (message.latestProjectVersionId !== "") { - writer.uint32(50).string(message.latestProjectVersionId); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): ProjectMember { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBaseProjectMember(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.user = User.decode(reader, reader.uint32()); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.group = Group.decode(reader, reader.uint32()); - continue; - case 3: - if (tag !== 24) { - break; - } - - message.role = reader.int32() as any; - continue; - case 4: - if (tag !== 34) { - break; - } - - message.createdAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - case 5: - if (tag !== 42) { - break; - } - - message.updatedAt = fromTimestamp(Timestamp.decode(reader, reader.uint32())); - continue; - case 6: - if (tag !== 50) { - break; - } - - message.latestProjectVersionId = reader.string(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): ProjectMember { - return { - user: isSet(object.user) ? User.fromJSON(object.user) : undefined, - group: isSet(object.group) ? Group.fromJSON(object.group) : undefined, - role: isSet(object.role) ? projectMemberRoleFromJSON(object.role) : 0, - createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, - updatedAt: isSet(object.updatedAt) ? fromJsonTimestamp(object.updatedAt) : undefined, - latestProjectVersionId: isSet(object.latestProjectVersionId) ? String(object.latestProjectVersionId) : "", - }; - }, - - toJSON(message: ProjectMember): unknown { - const obj: any = {}; - message.user !== undefined && (obj.user = message.user ? User.toJSON(message.user) : undefined); - message.group !== undefined && (obj.group = message.group ? Group.toJSON(message.group) : undefined); - message.role !== undefined && (obj.role = projectMemberRoleToJSON(message.role)); - message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); - message.updatedAt !== undefined && (obj.updatedAt = message.updatedAt.toISOString()); - message.latestProjectVersionId !== undefined && (obj.latestProjectVersionId = message.latestProjectVersionId); - return obj; - }, - - create, I>>(base?: I): ProjectMember { - return ProjectMember.fromPartial(base ?? {}); - }, - - fromPartial, I>>(object: I): ProjectMember { - const message = createBaseProjectMember(); - message.user = (object.user !== undefined && object.user !== null) ? User.fromPartial(object.user) : undefined; - message.group = (object.group !== undefined && object.group !== null) ? Group.fromPartial(object.group) : undefined; - message.role = object.role ?? 0; - message.createdAt = object.createdAt ?? undefined; - message.updatedAt = object.updatedAt ?? undefined; - message.latestProjectVersionId = object.latestProjectVersionId ?? ""; - return message; - }, -}; - type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; export type DeepPartial = T extends Builtin ? T @@ -452,28 +95,6 @@ type KeysOfUnion = T extends T ? keyof T : never; export type Exact = P extends Builtin ? P : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; -function toTimestamp(date: Date): Timestamp { - const seconds = date.getTime() / 1_000; - const nanos = (date.getTime() % 1_000) * 1_000_000; - return { seconds, nanos }; -} - -function fromTimestamp(t: Timestamp): Date { - let millis = (t.seconds || 0) * 1_000; - millis += (t.nanos || 0) / 1_000_000; - return new Date(millis); -} - -function fromJsonTimestamp(o: any): Date { - if (o instanceof Date) { - return o; - } else if (typeof o === "string") { - return new Date(o); - } else { - return fromTimestamp(Timestamp.fromJSON(o)); - } -} - function isSet(value: any): boolean { return value !== null && value !== undefined; } From fcc555e47054cf1c51532796da35c8761cde08cc Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 15:47:59 +0200 Subject: [PATCH 04/11] undo more changes Signed-off-by: Javier Rodriguez --- .../api/controlplane/v1/shared_message.pb.go | 52 ++++++++----------- .../api/controlplane/v1/shared_message.proto | 2 - 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/app/controlplane/api/controlplane/v1/shared_message.pb.go b/app/controlplane/api/controlplane/v1/shared_message.pb.go index 285aef31d..8f5cedb7c 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.pb.go +++ b/app/controlplane/api/controlplane/v1/shared_message.pb.go @@ -25,7 +25,6 @@ import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - _ "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -103,33 +102,29 @@ var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, - 0x02, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd0, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, - 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xd0, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, - 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x3a, 0x9b, 0x01, 0xba, 0x48, - 0x97, 0x01, 0x1a, 0x94, 0x01, 0x0a, 0x13, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x31, 0x65, 0x69, 0x74, 0x68, - 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, - 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2c, 0x20, - 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x2e, 0x1a, 0x4a, 0x21, - 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, - 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, - 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, - 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, - 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, - 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x02, 0x0a, 0x11, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd0, 0x01, 0x01, 0x72, 0x03, + 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xd0, + 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x48, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, + 0x01, 0x3a, 0x9b, 0x01, 0xba, 0x48, 0x97, 0x01, 0x1a, 0x94, 0x01, 0x0a, 0x13, 0x69, 0x64, 0x5f, + 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x12, 0x31, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x64, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, + 0x74, 0x68, 0x2e, 0x1a, 0x4a, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, + 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, + 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -161,7 +156,6 @@ func file_controlplane_v1_shared_message_proto_init() { if File_controlplane_v1_shared_message_proto != nil { return } - file_controlplane_v1_response_messages_proto_init() if !protoimpl.UnsafeEnabled { file_controlplane_v1_shared_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IdentityReference); i { diff --git a/app/controlplane/api/controlplane/v1/shared_message.proto b/app/controlplane/api/controlplane/v1/shared_message.proto index 7be716b8b..a7df1113d 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.proto +++ b/app/controlplane/api/controlplane/v1/shared_message.proto @@ -18,8 +18,6 @@ syntax = "proto3"; package controlplane.v1; import "buf/validate/validate.proto"; -import "controlplane/v1/response_messages.proto"; -import "google/protobuf/timestamp.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; From 6f6da43b8430f0d070b88e23fa98e48487c5d411 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 15:56:17 +0200 Subject: [PATCH 05/11] correct ordering Signed-off-by: Javier Rodriguez --- app/controlplane/pkg/data/group.go | 47 ++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index 5a365ac53..d9ee48023 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -630,15 +630,12 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro } // Extract project IDs from memberships - projectIDs := make([]uuid.UUID, 0, len(memberships)) - // Create a map to store role by project ID for later use - projectRoles := make(map[uuid.UUID]authz.Role) + var projectIDs []uuid.UUID for _, m := range memberships { projectIDs = append(projectIDs, m.ResourceID) - projectRoles[m.ResourceID] = m.Role } - // Query the actual projects using the project IDs + // Query the projects entProjects, err := g.data.DB.Project.Query(). Where( project.IDIn(projectIDs...), @@ -653,21 +650,41 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro return nil, 0, fmt.Errorf("failed to fetch projects: %w", err) } - // Convert to business layer project info - projectInfos := make([]*biz.GroupProjectInfo, 0, len(entProjects)) + // Create a map of projects by ID for efficient lookup + projectsMap := make(map[uuid.UUID]*ent.Project, len(entProjects)) for _, p := range entProjects { + projectsMap[p.ID] = p + } + + // Create a map to store role by project ID + projectRoles := make(map[uuid.UUID]authz.Role, len(memberships)) + for _, m := range memberships { + projectRoles[m.ResourceID] = m.Role + } + + // Build the result following the order of memberships + bizGroup := entGroupToBiz(existingGroup) + projectInfos := make([]*biz.GroupProjectInfo, 0, len(memberships)) + + for _, m := range memberships { + pr, exists := projectsMap[m.ResourceID] + if !exists { + // Skip projects that might have been deleted but membership still exists + continue + } + projectInfo := &biz.GroupProjectInfo{ - ID: p.ID, - Name: p.Name, - Description: p.Description, - Role: projectRoles[p.ID], // Use the role we stored earlier - Group: entGroupToBiz(existingGroup), - CreatedAt: toTimePtr(p.CreatedAt), + ID: pr.ID, + Name: pr.Name, + Description: pr.Description, + Role: m.Role, + Group: bizGroup, + CreatedAt: toTimePtr(pr.CreatedAt), } // If the project has versions, include the latest version ID - if len(p.Edges.Versions) > 0 { - projectInfo.LatestVersionID = &p.Edges.Versions[0].ID + if len(pr.Edges.Versions) > 0 { + projectInfo.LatestVersionID = &pr.Edges.Versions[0].ID } projectInfos = append(projectInfos, projectInfo) From 23ded5789f4fd5b0e9282b9c5c578713429af916 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 16:17:50 +0200 Subject: [PATCH 06/11] feedback Signed-off-by: Javier Rodriguez --- .../api/controlplane/v1/group.pb.go | 244 ++++++++--------- .../api/controlplane/v1/group.proto | 2 +- .../api/controlplane/v1/project.pb.go | 254 +++++++----------- .../api/controlplane/v1/project.proto | 10 - .../api/controlplane/v1/shared_message.pb.go | 81 +++++- .../api/controlplane/v1/shared_message.proto | 11 + .../api/gen/frontend/controlplane/v1/group.ts | 25 +- .../gen/frontend/controlplane/v1/project.ts | 50 +--- .../controlplane/v1/shared_message.ts | 43 +++ ...ontrolplane.v1.ProjectInfo.jsonschema.json | 19 +- .../controlplane.v1.ProjectInfo.schema.json | 19 +- app/controlplane/internal/service/group.go | 15 +- app/controlplane/internal/service/project.go | 21 +- app/controlplane/pkg/biz/group.go | 17 +- 14 files changed, 420 insertions(+), 391 deletions(-) diff --git a/app/controlplane/api/controlplane/v1/group.pb.go b/app/controlplane/api/controlplane/v1/group.pb.go index fa90f4d79..9bf4efc7f 100644 --- a/app/controlplane/api/controlplane/v1/group.pb.go +++ b/app/controlplane/api/controlplane/v1/group.pb.go @@ -1521,7 +1521,7 @@ type ProjectInfo struct { // Description of the project Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Role of the group in the project (admin or viewer) - Role string `protobuf:"bytes,4,opt,name=role,proto3" json:"role,omitempty"` + Role ProjectMemberRole `protobuf:"varint,4,opt,name=role,proto3,enum=controlplane.v1.ProjectMemberRole" json:"role,omitempty"` // The latest version ID of the project, if available LatestVersionId *string `protobuf:"bytes,5,opt,name=latest_version_id,json=latestVersionId,proto3,oneof" json:"latest_version_id,omitempty"` // Timestamp when the project was created @@ -1581,11 +1581,11 @@ func (x *ProjectInfo) GetDescription() string { return "" } -func (x *ProjectInfo) GetRole() string { +func (x *ProjectInfo) GetRole() ProjectMemberRole { if x != nil { return x.Role } - return "" + return ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED } func (x *ProjectInfo) GetLatestVersionId() string { @@ -1861,108 +1861,110 @@ var file_controlplane_v1_group_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe9, 0x01, 0x0a, 0x0b, 0x50, 0x72, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x02, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 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, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x88, 0x01, 0x01, 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, 0x42, - 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x36, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, + 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 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, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x32, 0x86, 0x0a, 0x0a, 0x0c, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x03, 0x47, - 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x04, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x06, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, - 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, 0x0a, 0x1c, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, + 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xa5, 0x01, + 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, + 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x41, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x61, 0x69, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, - 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x0c, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2010,6 +2012,7 @@ var file_controlplane_v1_group_proto_goTypes = []interface{}{ (*OffsetPaginationResponse)(nil), // 28: controlplane.v1.OffsetPaginationResponse (*User)(nil), // 29: controlplane.v1.User (*timestamppb.Timestamp)(nil), // 30: google.protobuf.Timestamp + (ProjectMemberRole)(0), // 31: controlplane.v1.ProjectMemberRole } var file_controlplane_v1_group_proto_depIdxs = []int32{ 19, // 0: controlplane.v1.GroupServiceCreateResponse.group:type_name -> controlplane.v1.Group @@ -2043,34 +2046,35 @@ var file_controlplane_v1_group_proto_depIdxs = []int32{ 27, // 28: controlplane.v1.GroupServiceListProjectsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest 25, // 29: controlplane.v1.GroupServiceListProjectsResponse.projects:type_name -> controlplane.v1.ProjectInfo 28, // 30: controlplane.v1.GroupServiceListProjectsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 30, // 31: controlplane.v1.ProjectInfo.created_at:type_name -> google.protobuf.Timestamp - 0, // 32: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest - 2, // 33: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest - 4, // 34: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest - 6, // 35: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest - 8, // 36: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest - 11, // 37: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest - 12, // 38: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest - 14, // 39: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest - 21, // 40: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest - 16, // 41: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest - 23, // 42: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest - 1, // 43: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse - 3, // 44: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse - 5, // 45: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse - 7, // 46: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse - 9, // 47: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse - 10, // 48: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse - 13, // 49: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse - 15, // 50: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse - 22, // 51: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse - 17, // 52: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse - 24, // 53: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse - 43, // [43:54] is the sub-list for method output_type - 32, // [32:43] is the sub-list for method input_type - 32, // [32:32] is the sub-list for extension type_name - 32, // [32:32] is the sub-list for extension extendee - 0, // [0:32] is the sub-list for field type_name + 31, // 31: controlplane.v1.ProjectInfo.role:type_name -> controlplane.v1.ProjectMemberRole + 30, // 32: controlplane.v1.ProjectInfo.created_at:type_name -> google.protobuf.Timestamp + 0, // 33: controlplane.v1.GroupService.Create:input_type -> controlplane.v1.GroupServiceCreateRequest + 2, // 34: controlplane.v1.GroupService.Get:input_type -> controlplane.v1.GroupServiceGetRequest + 4, // 35: controlplane.v1.GroupService.List:input_type -> controlplane.v1.GroupServiceListRequest + 6, // 36: controlplane.v1.GroupService.Update:input_type -> controlplane.v1.GroupServiceUpdateRequest + 8, // 37: controlplane.v1.GroupService.Delete:input_type -> controlplane.v1.GroupServiceDeleteRequest + 11, // 38: controlplane.v1.GroupService.ListMembers:input_type -> controlplane.v1.GroupServiceListMembersRequest + 12, // 39: controlplane.v1.GroupService.AddMember:input_type -> controlplane.v1.GroupServiceAddMemberRequest + 14, // 40: controlplane.v1.GroupService.RemoveMember:input_type -> controlplane.v1.GroupServiceRemoveMemberRequest + 21, // 41: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:input_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusRequest + 16, // 42: controlplane.v1.GroupService.ListPendingInvitations:input_type -> controlplane.v1.GroupServiceListPendingInvitationsRequest + 23, // 43: controlplane.v1.GroupService.ListProjects:input_type -> controlplane.v1.GroupServiceListProjectsRequest + 1, // 44: controlplane.v1.GroupService.Create:output_type -> controlplane.v1.GroupServiceCreateResponse + 3, // 45: controlplane.v1.GroupService.Get:output_type -> controlplane.v1.GroupServiceGetResponse + 5, // 46: controlplane.v1.GroupService.List:output_type -> controlplane.v1.GroupServiceListResponse + 7, // 47: controlplane.v1.GroupService.Update:output_type -> controlplane.v1.GroupServiceUpdateResponse + 9, // 48: controlplane.v1.GroupService.Delete:output_type -> controlplane.v1.GroupServiceDeleteResponse + 10, // 49: controlplane.v1.GroupService.ListMembers:output_type -> controlplane.v1.GroupServiceListMembersResponse + 13, // 50: controlplane.v1.GroupService.AddMember:output_type -> controlplane.v1.GroupServiceAddMemberResponse + 15, // 51: controlplane.v1.GroupService.RemoveMember:output_type -> controlplane.v1.GroupServiceRemoveMemberResponse + 22, // 52: controlplane.v1.GroupService.UpdateMemberMaintainerStatus:output_type -> controlplane.v1.GroupServiceUpdateMemberMaintainerStatusResponse + 17, // 53: controlplane.v1.GroupService.ListPendingInvitations:output_type -> controlplane.v1.GroupServiceListPendingInvitationsResponse + 24, // 54: controlplane.v1.GroupService.ListProjects:output_type -> controlplane.v1.GroupServiceListProjectsResponse + 44, // [44:55] is the sub-list for method output_type + 33, // [33:44] is the sub-list for method input_type + 33, // [33:33] is the sub-list for extension type_name + 33, // [33:33] is the sub-list for extension extendee + 0, // [0:33] is the sub-list for field type_name } func init() { file_controlplane_v1_group_proto_init() } diff --git a/app/controlplane/api/controlplane/v1/group.proto b/app/controlplane/api/controlplane/v1/group.proto index 93d26c3e9..a0e22b7f6 100644 --- a/app/controlplane/api/controlplane/v1/group.proto +++ b/app/controlplane/api/controlplane/v1/group.proto @@ -264,7 +264,7 @@ message ProjectInfo { // Description of the project string description = 3; // Role of the group in the project (admin or viewer) - string role = 4; + ProjectMemberRole role = 4; // The latest version ID of the project, if available optional string latest_version_id = 5; // Timestamp when the project was created diff --git a/app/controlplane/api/controlplane/v1/project.pb.go b/app/controlplane/api/controlplane/v1/project.pb.go index 11de6686f..ca961d15e 100644 --- a/app/controlplane/api/controlplane/v1/project.pb.go +++ b/app/controlplane/api/controlplane/v1/project.pb.go @@ -37,59 +37,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// ProjectMemberRole defines the roles a member can have in a project -type ProjectMemberRole int32 - -const ( - // Default role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 - // Admin role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 - // Viewer role for a project member - ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 -) - -// Enum value maps for ProjectMemberRole. -var ( - ProjectMemberRole_name = map[int32]string{ - 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", - 1: "PROJECT_MEMBER_ROLE_ADMIN", - 2: "PROJECT_MEMBER_ROLE_VIEWER", - } - ProjectMemberRole_value = map[string]int32{ - "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, - "PROJECT_MEMBER_ROLE_ADMIN": 1, - "PROJECT_MEMBER_ROLE_VIEWER": 2, - } -) - -func (x ProjectMemberRole) Enum() *ProjectMemberRole { - p := new(ProjectMemberRole) - *p = x - return p -} - -func (x ProjectMemberRole) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { - return file_controlplane_v1_project_proto_enumTypes[0].Descriptor() -} - -func (ProjectMemberRole) Type() protoreflect.EnumType { - return &file_controlplane_v1_project_proto_enumTypes[0] -} - -func (x ProjectMemberRole) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ProjectMemberRole.Descriptor instead. -func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { - return file_controlplane_v1_project_proto_rawDescGZIP(), []int{0} -} - // ProjectServiceListMembersRequest contains the information needed to list members of a project type ProjectServiceListMembersRequest struct { state protoimpl.MessageState @@ -1087,61 +1034,54 @@ var file_controlplane_v1_project_proto_rawDesc = []byte{ 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x0d, - 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x2a, 0x77, 0x0a, - 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, - 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, - 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, - 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x56, 0x49, - 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x32, 0x8f, 0x05, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, + 0x0a, 0x0b, 0x5f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x32, 0x8f, 0x05, + 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x74, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, + 0x31, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x36, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, - 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x83, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, - 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, - 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x3c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1156,65 +1096,64 @@ func file_controlplane_v1_project_proto_rawDescGZIP() []byte { return file_controlplane_v1_project_proto_rawDescData } -var file_controlplane_v1_project_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_controlplane_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_controlplane_v1_project_proto_goTypes = []interface{}{ - (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole - (*ProjectServiceListMembersRequest)(nil), // 1: controlplane.v1.ProjectServiceListMembersRequest - (*ProjectServiceListMembersResponse)(nil), // 2: controlplane.v1.ProjectServiceListMembersResponse - (*ProjectMember)(nil), // 3: controlplane.v1.ProjectMember - (*ProjectServiceAddMemberRequest)(nil), // 4: controlplane.v1.ProjectServiceAddMemberRequest - (*ProjectServiceAddMemberResponse)(nil), // 5: controlplane.v1.ProjectServiceAddMemberResponse - (*ProjectServiceRemoveMemberRequest)(nil), // 6: controlplane.v1.ProjectServiceRemoveMemberRequest - (*ProjectServiceRemoveMemberResponse)(nil), // 7: controlplane.v1.ProjectServiceRemoveMemberResponse - (*ProjectMembershipReference)(nil), // 8: controlplane.v1.ProjectMembershipReference - (*ProjectServiceUpdateMemberRoleRequest)(nil), // 9: controlplane.v1.ProjectServiceUpdateMemberRoleRequest - (*ProjectServiceUpdateMemberRoleResponse)(nil), // 10: controlplane.v1.ProjectServiceUpdateMemberRoleResponse - (*ProjectServiceListPendingInvitationsRequest)(nil), // 11: controlplane.v1.ProjectServiceListPendingInvitationsRequest - (*ProjectServiceListPendingInvitationsResponse)(nil), // 12: controlplane.v1.ProjectServiceListPendingInvitationsResponse - (*PendingProjectInvitation)(nil), // 13: controlplane.v1.PendingProjectInvitation - (*IdentityReference)(nil), // 14: controlplane.v1.IdentityReference - (*OffsetPaginationRequest)(nil), // 15: controlplane.v1.OffsetPaginationRequest - (*OffsetPaginationResponse)(nil), // 16: controlplane.v1.OffsetPaginationResponse - (*User)(nil), // 17: controlplane.v1.User - (*Group)(nil), // 18: controlplane.v1.Group + (*ProjectServiceListMembersRequest)(nil), // 0: controlplane.v1.ProjectServiceListMembersRequest + (*ProjectServiceListMembersResponse)(nil), // 1: controlplane.v1.ProjectServiceListMembersResponse + (*ProjectMember)(nil), // 2: controlplane.v1.ProjectMember + (*ProjectServiceAddMemberRequest)(nil), // 3: controlplane.v1.ProjectServiceAddMemberRequest + (*ProjectServiceAddMemberResponse)(nil), // 4: controlplane.v1.ProjectServiceAddMemberResponse + (*ProjectServiceRemoveMemberRequest)(nil), // 5: controlplane.v1.ProjectServiceRemoveMemberRequest + (*ProjectServiceRemoveMemberResponse)(nil), // 6: controlplane.v1.ProjectServiceRemoveMemberResponse + (*ProjectMembershipReference)(nil), // 7: controlplane.v1.ProjectMembershipReference + (*ProjectServiceUpdateMemberRoleRequest)(nil), // 8: controlplane.v1.ProjectServiceUpdateMemberRoleRequest + (*ProjectServiceUpdateMemberRoleResponse)(nil), // 9: controlplane.v1.ProjectServiceUpdateMemberRoleResponse + (*ProjectServiceListPendingInvitationsRequest)(nil), // 10: controlplane.v1.ProjectServiceListPendingInvitationsRequest + (*ProjectServiceListPendingInvitationsResponse)(nil), // 11: controlplane.v1.ProjectServiceListPendingInvitationsResponse + (*PendingProjectInvitation)(nil), // 12: controlplane.v1.PendingProjectInvitation + (*IdentityReference)(nil), // 13: controlplane.v1.IdentityReference + (*OffsetPaginationRequest)(nil), // 14: controlplane.v1.OffsetPaginationRequest + (*OffsetPaginationResponse)(nil), // 15: controlplane.v1.OffsetPaginationResponse + (*User)(nil), // 16: controlplane.v1.User + (*Group)(nil), // 17: controlplane.v1.Group + (ProjectMemberRole)(0), // 18: controlplane.v1.ProjectMemberRole (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp } var file_controlplane_v1_project_proto_depIdxs = []int32{ - 14, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 15, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 3, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember - 16, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 17, // 4: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User - 18, // 5: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group - 0, // 6: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole + 13, // 0: controlplane.v1.ProjectServiceListMembersRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 14, // 1: controlplane.v1.ProjectServiceListMembersRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 2, // 2: controlplane.v1.ProjectServiceListMembersResponse.members:type_name -> controlplane.v1.ProjectMember + 15, // 3: controlplane.v1.ProjectServiceListMembersResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 16, // 4: controlplane.v1.ProjectMember.user:type_name -> controlplane.v1.User + 17, // 5: controlplane.v1.ProjectMember.group:type_name -> controlplane.v1.Group + 18, // 6: controlplane.v1.ProjectMember.role:type_name -> controlplane.v1.ProjectMemberRole 19, // 7: controlplane.v1.ProjectMember.created_at:type_name -> google.protobuf.Timestamp 19, // 8: controlplane.v1.ProjectMember.updated_at:type_name -> google.protobuf.Timestamp - 14, // 9: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 10: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 11: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole - 14, // 12: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 13: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 14, // 14: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference - 14, // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 8, // 16: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference - 0, // 17: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole - 14, // 18: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference - 15, // 19: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest - 13, // 20: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation - 16, // 21: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse - 17, // 22: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User + 13, // 9: controlplane.v1.ProjectServiceAddMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 7, // 10: controlplane.v1.ProjectServiceAddMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 18, // 11: controlplane.v1.ProjectServiceAddMemberRequest.role:type_name -> controlplane.v1.ProjectMemberRole + 13, // 12: controlplane.v1.ProjectServiceRemoveMemberRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 7, // 13: controlplane.v1.ProjectServiceRemoveMemberRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 13, // 14: controlplane.v1.ProjectMembershipReference.group_reference:type_name -> controlplane.v1.IdentityReference + 13, // 15: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 7, // 16: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.member_reference:type_name -> controlplane.v1.ProjectMembershipReference + 18, // 17: controlplane.v1.ProjectServiceUpdateMemberRoleRequest.new_role:type_name -> controlplane.v1.ProjectMemberRole + 13, // 18: controlplane.v1.ProjectServiceListPendingInvitationsRequest.project_reference:type_name -> controlplane.v1.IdentityReference + 14, // 19: controlplane.v1.ProjectServiceListPendingInvitationsRequest.pagination:type_name -> controlplane.v1.OffsetPaginationRequest + 12, // 20: controlplane.v1.ProjectServiceListPendingInvitationsResponse.invitations:type_name -> controlplane.v1.PendingProjectInvitation + 15, // 21: controlplane.v1.ProjectServiceListPendingInvitationsResponse.pagination:type_name -> controlplane.v1.OffsetPaginationResponse + 16, // 22: controlplane.v1.PendingProjectInvitation.invited_by:type_name -> controlplane.v1.User 19, // 23: controlplane.v1.PendingProjectInvitation.created_at:type_name -> google.protobuf.Timestamp - 1, // 24: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest - 4, // 25: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest - 6, // 26: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest - 9, // 27: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest - 11, // 28: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest - 2, // 29: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse - 5, // 30: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse - 7, // 31: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse - 10, // 32: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse - 12, // 33: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse + 0, // 24: controlplane.v1.ProjectService.ListMembers:input_type -> controlplane.v1.ProjectServiceListMembersRequest + 3, // 25: controlplane.v1.ProjectService.AddMember:input_type -> controlplane.v1.ProjectServiceAddMemberRequest + 5, // 26: controlplane.v1.ProjectService.RemoveMember:input_type -> controlplane.v1.ProjectServiceRemoveMemberRequest + 8, // 27: controlplane.v1.ProjectService.UpdateMemberRole:input_type -> controlplane.v1.ProjectServiceUpdateMemberRoleRequest + 10, // 28: controlplane.v1.ProjectService.ListPendingInvitations:input_type -> controlplane.v1.ProjectServiceListPendingInvitationsRequest + 1, // 29: controlplane.v1.ProjectService.ListMembers:output_type -> controlplane.v1.ProjectServiceListMembersResponse + 4, // 30: controlplane.v1.ProjectService.AddMember:output_type -> controlplane.v1.ProjectServiceAddMemberResponse + 6, // 31: controlplane.v1.ProjectService.RemoveMember:output_type -> controlplane.v1.ProjectServiceRemoveMemberResponse + 9, // 32: controlplane.v1.ProjectService.UpdateMemberRole:output_type -> controlplane.v1.ProjectServiceUpdateMemberRoleResponse + 11, // 33: controlplane.v1.ProjectService.ListPendingInvitations:output_type -> controlplane.v1.ProjectServiceListPendingInvitationsResponse 29, // [29:34] is the sub-list for method output_type 24, // [24:29] is the sub-list for method input_type 24, // [24:24] is the sub-list for extension type_name @@ -1403,14 +1342,13 @@ func file_controlplane_v1_project_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_project_proto_rawDesc, - NumEnums: 1, + NumEnums: 0, NumMessages: 13, NumExtensions: 0, NumServices: 1, }, GoTypes: file_controlplane_v1_project_proto_goTypes, DependencyIndexes: file_controlplane_v1_project_proto_depIdxs, - EnumInfos: file_controlplane_v1_project_proto_enumTypes, MessageInfos: file_controlplane_v1_project_proto_msgTypes, }.Build() File_controlplane_v1_project_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/project.proto b/app/controlplane/api/controlplane/v1/project.proto index 5ea87d7b6..756880981 100644 --- a/app/controlplane/api/controlplane/v1/project.proto +++ b/app/controlplane/api/controlplane/v1/project.proto @@ -110,16 +110,6 @@ message ProjectMembershipReference { } } -// ProjectMemberRole defines the roles a member can have in a project -enum ProjectMemberRole { - // Default role for a project member - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; - // Admin role for a project member - PROJECT_MEMBER_ROLE_ADMIN = 1; - // Viewer role for a project member - PROJECT_MEMBER_ROLE_VIEWER = 2; -} - // ProjectServiceUpdateMemberRoleRequest contains the information needed to update a member's role in a project message ProjectServiceUpdateMemberRoleRequest { // IdentityReference is used to specify the project by either its ID or name diff --git a/app/controlplane/api/controlplane/v1/shared_message.pb.go b/app/controlplane/api/controlplane/v1/shared_message.pb.go index 8f5cedb7c..95b4e2afc 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.pb.go +++ b/app/controlplane/api/controlplane/v1/shared_message.pb.go @@ -36,6 +36,59 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// ProjectMemberRole defines the roles a member can have in a project +type ProjectMemberRole int32 + +const ( + // Default role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED ProjectMemberRole = 0 + // Admin role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN ProjectMemberRole = 1 + // Viewer role for a project member + ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER ProjectMemberRole = 2 +) + +// Enum value maps for ProjectMemberRole. +var ( + ProjectMemberRole_name = map[int32]string{ + 0: "PROJECT_MEMBER_ROLE_UNSPECIFIED", + 1: "PROJECT_MEMBER_ROLE_ADMIN", + 2: "PROJECT_MEMBER_ROLE_VIEWER", + } + ProjectMemberRole_value = map[string]int32{ + "PROJECT_MEMBER_ROLE_UNSPECIFIED": 0, + "PROJECT_MEMBER_ROLE_ADMIN": 1, + "PROJECT_MEMBER_ROLE_VIEWER": 2, + } +) + +func (x ProjectMemberRole) Enum() *ProjectMemberRole { + p := new(ProjectMemberRole) + *p = x + return p +} + +func (x ProjectMemberRole) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProjectMemberRole) Descriptor() protoreflect.EnumDescriptor { + return file_controlplane_v1_shared_message_proto_enumTypes[0].Descriptor() +} + +func (ProjectMemberRole) Type() protoreflect.EnumType { + return &file_controlplane_v1_shared_message_proto_enumTypes[0] +} + +func (x ProjectMemberRole) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProjectMemberRole.Descriptor instead. +func (ProjectMemberRole) EnumDescriptor() ([]byte, []int) { + return file_controlplane_v1_shared_message_proto_rawDescGZIP(), []int{0} +} + // IdentityReference represents a reference to an identity in the system. type IdentityReference struct { state protoimpl.MessageState @@ -118,13 +171,20 @@ var file_controlplane_v1_shared_message_proto_rawDesc = []byte{ 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x26, 0x26, 0x20, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x42, - 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, - 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2a, + 0x77, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x4f, 0x4a, 0x45, 0x43, 0x54, 0x5f, + 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x52, 0x4f, + 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, + 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x4f, 0x4a, + 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x45, 0x4d, 0x42, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4c, 0x45, 0x5f, + 0x56, 0x49, 0x45, 0x57, 0x45, 0x52, 0x10, 0x02, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, + 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, + 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -139,9 +199,11 @@ func file_controlplane_v1_shared_message_proto_rawDescGZIP() []byte { return file_controlplane_v1_shared_message_proto_rawDescData } +var file_controlplane_v1_shared_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_controlplane_v1_shared_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_controlplane_v1_shared_message_proto_goTypes = []interface{}{ - (*IdentityReference)(nil), // 0: controlplane.v1.IdentityReference + (ProjectMemberRole)(0), // 0: controlplane.v1.ProjectMemberRole + (*IdentityReference)(nil), // 1: controlplane.v1.IdentityReference } var file_controlplane_v1_shared_message_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -176,13 +238,14 @@ func file_controlplane_v1_shared_message_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_controlplane_v1_shared_message_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_controlplane_v1_shared_message_proto_goTypes, DependencyIndexes: file_controlplane_v1_shared_message_proto_depIdxs, + EnumInfos: file_controlplane_v1_shared_message_proto_enumTypes, MessageInfos: file_controlplane_v1_shared_message_proto_msgTypes, }.Build() File_controlplane_v1_shared_message_proto = out.File diff --git a/app/controlplane/api/controlplane/v1/shared_message.proto b/app/controlplane/api/controlplane/v1/shared_message.proto index a7df1113d..5ef51062d 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.proto +++ b/app/controlplane/api/controlplane/v1/shared_message.proto @@ -41,3 +41,14 @@ message IdentityReference { message: "either id or name must be provided, but not both." }; } + + +// ProjectMemberRole defines the roles a member can have in a project +enum ProjectMemberRole { + // Default role for a project member + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0; + // Admin role for a project member + PROJECT_MEMBER_ROLE_ADMIN = 1; + // Viewer role for a project member + PROJECT_MEMBER_ROLE_VIEWER = 2; +} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts index 3ef1932de..0f1bfd1db 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/group.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/group.ts @@ -5,7 +5,12 @@ import _m0 from "protobufjs/minimal"; import { Timestamp } from "../../google/protobuf/timestamp"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { IdentityReference } from "./shared_message"; +import { + IdentityReference, + ProjectMemberRole, + projectMemberRoleFromJSON, + projectMemberRoleToJSON, +} from "./shared_message"; export const protobufPackage = "controlplane.v1"; @@ -236,7 +241,7 @@ export interface ProjectInfo { /** Description of the project */ description: string; /** Role of the group in the project (admin or viewer) */ - role: string; + role: ProjectMemberRole; /** The latest version ID of the project, if available */ latestVersionId?: | string @@ -2164,7 +2169,7 @@ export const GroupServiceListProjectsResponse = { }; function createBaseProjectInfo(): ProjectInfo { - return { id: "", name: "", description: "", role: "", latestVersionId: undefined, createdAt: undefined }; + return { id: "", name: "", description: "", role: 0, latestVersionId: undefined, createdAt: undefined }; } export const ProjectInfo = { @@ -2178,8 +2183,8 @@ export const ProjectInfo = { if (message.description !== "") { writer.uint32(26).string(message.description); } - if (message.role !== "") { - writer.uint32(34).string(message.role); + if (message.role !== 0) { + writer.uint32(32).int32(message.role); } if (message.latestVersionId !== undefined) { writer.uint32(42).string(message.latestVersionId); @@ -2219,11 +2224,11 @@ export const ProjectInfo = { message.description = reader.string(); continue; case 4: - if (tag !== 34) { + if (tag !== 32) { break; } - message.role = reader.string(); + message.role = reader.int32() as any; continue; case 5: if (tag !== 42) { @@ -2253,7 +2258,7 @@ export const ProjectInfo = { id: isSet(object.id) ? String(object.id) : "", name: isSet(object.name) ? String(object.name) : "", description: isSet(object.description) ? String(object.description) : "", - role: isSet(object.role) ? String(object.role) : "", + role: isSet(object.role) ? projectMemberRoleFromJSON(object.role) : 0, latestVersionId: isSet(object.latestVersionId) ? String(object.latestVersionId) : undefined, createdAt: isSet(object.createdAt) ? fromJsonTimestamp(object.createdAt) : undefined, }; @@ -2264,7 +2269,7 @@ export const ProjectInfo = { message.id !== undefined && (obj.id = message.id); message.name !== undefined && (obj.name = message.name); message.description !== undefined && (obj.description = message.description); - message.role !== undefined && (obj.role = message.role); + message.role !== undefined && (obj.role = projectMemberRoleToJSON(message.role)); message.latestVersionId !== undefined && (obj.latestVersionId = message.latestVersionId); message.createdAt !== undefined && (obj.createdAt = message.createdAt.toISOString()); return obj; @@ -2279,7 +2284,7 @@ export const ProjectInfo = { message.id = object.id ?? ""; message.name = object.name ?? ""; message.description = object.description ?? ""; - message.role = object.role ?? ""; + message.role = object.role ?? 0; message.latestVersionId = object.latestVersionId ?? undefined; message.createdAt = object.createdAt ?? undefined; return message; diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts index 2557c14fd..6d4f588e5 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/project.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/project.ts @@ -6,53 +6,15 @@ import { Timestamp } from "../../google/protobuf/timestamp"; import { Group } from "./group"; import { OffsetPaginationRequest, OffsetPaginationResponse } from "./pagination"; import { User } from "./response_messages"; -import { IdentityReference } from "./shared_message"; +import { + IdentityReference, + ProjectMemberRole, + projectMemberRoleFromJSON, + projectMemberRoleToJSON, +} from "./shared_message"; export const protobufPackage = "controlplane.v1"; -/** ProjectMemberRole defines the roles a member can have in a project */ -export enum ProjectMemberRole { - /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ - PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, - /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ - PROJECT_MEMBER_ROLE_ADMIN = 1, - /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ - PROJECT_MEMBER_ROLE_VIEWER = 2, - UNRECOGNIZED = -1, -} - -export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { - switch (object) { - case 0: - case "PROJECT_MEMBER_ROLE_UNSPECIFIED": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; - case 1: - case "PROJECT_MEMBER_ROLE_ADMIN": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; - case 2: - case "PROJECT_MEMBER_ROLE_VIEWER": - return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; - case -1: - case "UNRECOGNIZED": - default: - return ProjectMemberRole.UNRECOGNIZED; - } -} - -export function projectMemberRoleToJSON(object: ProjectMemberRole): string { - switch (object) { - case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: - return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: - return "PROJECT_MEMBER_ROLE_ADMIN"; - case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: - return "PROJECT_MEMBER_ROLE_VIEWER"; - case ProjectMemberRole.UNRECOGNIZED: - default: - return "UNRECOGNIZED"; - } -} - /** ProjectServiceListMembersRequest contains the information needed to list members of a project */ export interface ProjectServiceListMembersRequest { /** IdentityReference is used to specify the project by either its ID or name */ diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts index f8ccfe269..0a981073f 100644 --- a/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts +++ b/app/controlplane/api/gen/frontend/controlplane/v1/shared_message.ts @@ -3,6 +3,49 @@ import _m0 from "protobufjs/minimal"; export const protobufPackage = "controlplane.v1"; +/** ProjectMemberRole defines the roles a member can have in a project */ +export enum ProjectMemberRole { + /** PROJECT_MEMBER_ROLE_UNSPECIFIED - Default role for a project member */ + PROJECT_MEMBER_ROLE_UNSPECIFIED = 0, + /** PROJECT_MEMBER_ROLE_ADMIN - Admin role for a project member */ + PROJECT_MEMBER_ROLE_ADMIN = 1, + /** PROJECT_MEMBER_ROLE_VIEWER - Viewer role for a project member */ + PROJECT_MEMBER_ROLE_VIEWER = 2, + UNRECOGNIZED = -1, +} + +export function projectMemberRoleFromJSON(object: any): ProjectMemberRole { + switch (object) { + case 0: + case "PROJECT_MEMBER_ROLE_UNSPECIFIED": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED; + case 1: + case "PROJECT_MEMBER_ROLE_ADMIN": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN; + case 2: + case "PROJECT_MEMBER_ROLE_VIEWER": + return ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER; + case -1: + case "UNRECOGNIZED": + default: + return ProjectMemberRole.UNRECOGNIZED; + } +} + +export function projectMemberRoleToJSON(object: ProjectMemberRole): string { + switch (object) { + case ProjectMemberRole.PROJECT_MEMBER_ROLE_UNSPECIFIED: + return "PROJECT_MEMBER_ROLE_UNSPECIFIED"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_ADMIN: + return "PROJECT_MEMBER_ROLE_ADMIN"; + case ProjectMemberRole.PROJECT_MEMBER_ROLE_VIEWER: + return "PROJECT_MEMBER_ROLE_VIEWER"; + case ProjectMemberRole.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + /** IdentityReference represents a reference to an identity in the system. */ export interface IdentityReference { /** ID is optional, but if provided, it must be a valid UUID. */ diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json index 24c5a6dc3..a628c16c6 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.jsonschema.json @@ -35,8 +35,23 @@ "type": "string" }, "role": { - "description": "Role of the group in the project (admin or viewer)", - "type": "string" + "anyOf": [ + { + "enum": [ + "PROJECT_MEMBER_ROLE_UNSPECIFIED", + "PROJECT_MEMBER_ROLE_ADMIN", + "PROJECT_MEMBER_ROLE_VIEWER" + ], + "title": "Project Member Role", + "type": "string" + }, + { + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + } + ], + "description": "Role of the group in the project (admin or viewer)" } }, "title": "Project Info", diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json index a9794c412..4e6a5b529 100644 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.ProjectInfo.schema.json @@ -35,8 +35,23 @@ "type": "string" }, "role": { - "description": "Role of the group in the project (admin or viewer)", - "type": "string" + "anyOf": [ + { + "enum": [ + "PROJECT_MEMBER_ROLE_UNSPECIFIED", + "PROJECT_MEMBER_ROLE_ADMIN", + "PROJECT_MEMBER_ROLE_VIEWER" + ], + "title": "Project Member Role", + "type": "string" + }, + { + "maximum": 2147483647, + "minimum": -2147483648, + "type": "integer" + } + ], + "description": "Role of the group in the project (admin or viewer)" } }, "title": "Project Info", diff --git a/app/controlplane/internal/service/group.go b/app/controlplane/internal/service/group.go index a745030bb..b898f7913 100644 --- a/app/controlplane/internal/service/group.go +++ b/app/controlplane/internal/service/group.go @@ -486,11 +486,6 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis return nil, err } - currentUser, err := requireCurrentUser(ctx) - if err != nil { - return nil, err - } - // Parse orgID orgUUID, err := uuid.Parse(currentOrg.ID) if err != nil { @@ -503,19 +498,13 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis return nil, errors.BadRequest("invalid", fmt.Sprintf("invalid group reference: %s", err.Error())) } - // Parse requesterID (current user) - requesterUUID, err := uuid.Parse(currentUser.ID) - if err != nil { - return nil, errors.BadRequest("invalid", "invalid user ID") - } - // Initialize the options for getting projects groupOpts := &biz.ListProjectsByGroupOpts{ IdentityReference: &biz.IdentityReference{ ID: id, Name: name, }, - RequesterID: &requesterUUID, + VisibleProjectsIDs: g.visibleProjects(ctx), } // Initialize the pagination options, with default values @@ -592,7 +581,7 @@ func bizGroupProjectInfoToPb(info *biz.GroupProjectInfo) *pb.ProjectInfo { Id: info.ID.String(), Name: info.Name, Description: info.Description, - Role: string(info.Role), + Role: mapAuthzRoleToProjectMemberRole(info.Role), CreatedAt: timestamppb.New(*info.CreatedAt), } diff --git a/app/controlplane/internal/service/project.go b/app/controlplane/internal/service/project.go index 94ed6ebf3..69e085687 100644 --- a/app/controlplane/internal/service/project.go +++ b/app/controlplane/internal/service/project.go @@ -385,14 +385,7 @@ func bizProjectMembershipToPb(m *biz.ProjectMembership) *pb.ProjectMember { var role pb.ProjectMemberRole // Map the role string back to a protobuf enum - switch m.Role { - case authz.RoleProjectAdmin: - role = pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN - case authz.RoleProjectViewer: - role = pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER - default: - role = pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED - } + role = mapAuthzRoleToProjectMemberRole(m.Role) pbMember := &pb.ProjectMember{ Role: role, @@ -425,6 +418,18 @@ func bizProjectMembershipToPb(m *biz.ProjectMembership) *pb.ProjectMember { return pbMember } +// mapAuthzRoleToProjectMemberRole maps an authorization role to a ProjectMemberRole protobuf enum +func mapAuthzRoleToProjectMemberRole(role authz.Role) pb.ProjectMemberRole { + switch role { + case authz.RoleProjectAdmin: + return pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_ADMIN + case authz.RoleProjectViewer: + return pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_VIEWER + default: + return pb.ProjectMemberRole_PROJECT_MEMBER_ROLE_UNSPECIFIED + } +} + // bizOrgInvitationToPendingProjectInvitationPb converts a biz.OrgInvitation to a pb.PendingProjectInvitation protobuf message. func bizOrgInvitationToPendingProjectInvitationPb(inv *biz.OrgInvitation) *pb.PendingProjectInvitation { base := &pb.PendingProjectInvitation{ diff --git a/app/controlplane/pkg/biz/group.go b/app/controlplane/pkg/biz/group.go index 43230a0d0..a4eeb8781 100644 --- a/app/controlplane/pkg/biz/group.go +++ b/app/controlplane/pkg/biz/group.go @@ -175,9 +175,8 @@ type UpdateMemberMaintainerStatusOpts struct { type ListProjectsByGroupOpts struct { // Group reference *IdentityReference - // RequesterID is the ID of the user who is requesting to list projects. Optional. - // Used to scope down the projects to those visible to the requester. - RequesterID *uuid.UUID + // VisibleProjectsIDs is a list of project IDs that the requester can see. + VisibleProjectsIDs []uuid.UUID } type GroupUseCase struct { @@ -897,15 +896,5 @@ func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID pgOpts = paginationOpts } - var requesterMemberships []*Membership - // If requesterID is provided, list all memberships for the requester - if opts.RequesterID != nil { - var listErr error - requesterMemberships, listErr = uc.membershipUC.ListAllMembershipsForUser(ctx, *opts.RequesterID) - if listErr != nil { - return nil, 0, fmt.Errorf("failed to list memberships: %w", listErr) - } - } - - return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, getProjectsWithMembershipInOrg(orgID, requesterMemberships), pgOpts) + return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, opts.VisibleProjectsIDs, pgOpts) } From e9822dd711b9aa7dd3bb9c2150323fdb37c2ab3e Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 16:20:24 +0200 Subject: [PATCH 07/11] more feedback Signed-off-by: Javier Rodriguez --- app/controlplane/api/controlplane/v1/shared_message.proto | 1 - app/controlplane/pkg/data/group.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controlplane/api/controlplane/v1/shared_message.proto b/app/controlplane/api/controlplane/v1/shared_message.proto index 5ef51062d..8fd881bab 100644 --- a/app/controlplane/api/controlplane/v1/shared_message.proto +++ b/app/controlplane/api/controlplane/v1/shared_message.proto @@ -42,7 +42,6 @@ message IdentityReference { }; } - // ProjectMemberRole defines the roles a member can have in a project enum ProjectMemberRole { // Default role for a project member diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index d9ee48023..8ccf91367 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -604,7 +604,7 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro ) // If visibleProjectIDs is provided, filter memberships to include only those projects - if len(visibleProjectIDs) > 0 { + if visibleProjectIDs != nil { membershipQuery = membershipQuery.Where(membership.ResourceIDIn(visibleProjectIDs...)) } From 662a5b383971ffd0455590b683c4aba85d9869bc Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 16:23:25 +0200 Subject: [PATCH 08/11] modify resource Signed-off-by: Javier Rodriguez --- app/controlplane/pkg/authz/authz.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index 882a0f0fc..a62ad3cb3 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -53,6 +53,7 @@ const ( ResourceAPIToken = "api_token" ResourceProjectMembership = "project_membership" ResourceOrganizationInvitations = "organization_invitations" + ResourceGroupProjects = "group_projects" // We have for now three roles, viewer, admin and owner // The owner of an org @@ -154,6 +155,8 @@ var ( PolicyGroupAddMemberships = &Policy{ResourceGroupMembership, ActionCreate} PolicyGroupRemoveMemberships = &Policy{ResourceGroupMembership, ActionDelete} PolicyGroupUpdateMemberships = &Policy{ResourceGroupMembership, ActionUpdate} + // Group-Projects + PolicyGroupListProjects = &Policy{ResourceGroupProjects, ActionList} // API Token PolicyAPITokenList = &Policy{ResourceAPIToken, ActionList} PolicyAPITokenCreate = &Policy{ResourceAPIToken, ActionCreate} @@ -254,6 +257,9 @@ var RolesMap = map[Role][]*Policy{ PolicyGroupList, PolicyGroupRead, + // Group Projects + PolicyGroupListProjects, + // Group Memberships PolicyGroupListMemberships, @@ -394,7 +400,7 @@ var ServerOperationsMap = map[string][]*Policy{ "/controlplane.v1.GroupService/Get": {PolicyGroupRead}, // Group Memberships "/controlplane.v1.GroupService/ListMembers": {PolicyGroupListMemberships}, - "/controlplane.v1.GroupService/ListProjects": {PolicyGroupListMemberships}, + "/controlplane.v1.GroupService/ListProjects": {PolicyGroupListProjects}, // For the following endpoints, we rely on the service layer to check the permissions // That's why we let everyone access them (empty policies) "/controlplane.v1.GroupService/AddMember": {}, From 599ec690b9aae893a011694cbaf3584ac31b4a80 Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 16:28:46 +0200 Subject: [PATCH 09/11] fix linter Signed-off-by: Javier Rodriguez --- app/controlplane/pkg/data/group.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index 8ccf91367..d7b32fef8 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -630,7 +630,7 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro } // Extract project IDs from memberships - var projectIDs []uuid.UUID + projectIDs := make([]uuid.UUID, 0, len(memberships)) for _, m := range memberships { projectIDs = append(projectIDs, m.ResourceID) } From 8ba41aa997931453633538e22e160a52c9c45a2a Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 17:04:59 +0200 Subject: [PATCH 10/11] remove group from grouproject info Signed-off-by: Javier Rodriguez --- app/controlplane/pkg/biz/project.go | 2 -- app/controlplane/pkg/data/group.go | 13 ------------- 2 files changed, 15 deletions(-) diff --git a/app/controlplane/pkg/biz/project.go b/app/controlplane/pkg/biz/project.go index 91b2cbd42..d4b86b231 100644 --- a/app/controlplane/pkg/biz/project.go +++ b/app/controlplane/pkg/biz/project.go @@ -108,8 +108,6 @@ type GroupProjectInfo struct { Role authz.Role // LatestVersionID is the ID of the latest version of the project, if available LatestVersionID *uuid.UUID - // Group is the group that is a member of this project - Group *Group // CreatedAt is the timestamp when the project was created CreatedAt *time.Time } diff --git a/app/controlplane/pkg/data/group.go b/app/controlplane/pkg/data/group.go index d7b32fef8..32e745f23 100644 --- a/app/controlplane/pkg/data/group.go +++ b/app/controlplane/pkg/data/group.go @@ -583,17 +583,6 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro paginationOpts = pagination.NewDefaultOffsetPaginationOpts() } - // Check the group exists in the organization - existingGroup, err := g.data.DB.Group.Query(). - Where(group.ID(groupID), group.OrganizationIDEQ(orgID), group.DeletedAtIsNil()). - Only(ctx) - if err != nil { - if ent.IsNotFound(err) { - return nil, 0, biz.NewErrNotFound("group") - } - return nil, 0, err - } - // Get all memberships where this group is a member and the resource type is a project membershipQuery := g.data.DB.Membership.Query(). Where( @@ -663,7 +652,6 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro } // Build the result following the order of memberships - bizGroup := entGroupToBiz(existingGroup) projectInfos := make([]*biz.GroupProjectInfo, 0, len(memberships)) for _, m := range memberships { @@ -678,7 +666,6 @@ func (g GroupRepo) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID, gro Name: pr.Name, Description: pr.Description, Role: m.Role, - Group: bizGroup, CreatedAt: toTimePtr(pr.CreatedAt), } From e2ff0807dd6704af6f03b8dfde6412c0469080de Mon Sep 17 00:00:00 2001 From: Javier Rodriguez Date: Fri, 11 Jul 2025 17:45:28 +0200 Subject: [PATCH 11/11] change field name Signed-off-by: Javier Rodriguez --- app/controlplane/internal/service/group.go | 2 +- app/controlplane/pkg/biz/group.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controlplane/internal/service/group.go b/app/controlplane/internal/service/group.go index b898f7913..3294ad7ef 100644 --- a/app/controlplane/internal/service/group.go +++ b/app/controlplane/internal/service/group.go @@ -504,7 +504,7 @@ func (g *GroupService) ListProjects(ctx context.Context, req *pb.GroupServiceLis ID: id, Name: name, }, - VisibleProjectsIDs: g.visibleProjects(ctx), + FilterByProject: g.visibleProjects(ctx), } // Initialize the pagination options, with default values diff --git a/app/controlplane/pkg/biz/group.go b/app/controlplane/pkg/biz/group.go index a4eeb8781..3be207832 100644 --- a/app/controlplane/pkg/biz/group.go +++ b/app/controlplane/pkg/biz/group.go @@ -175,8 +175,8 @@ type UpdateMemberMaintainerStatusOpts struct { type ListProjectsByGroupOpts struct { // Group reference *IdentityReference - // VisibleProjectsIDs is a list of project IDs that the requester can see. - VisibleProjectsIDs []uuid.UUID + // FilterByProject is a list of project IDs to filter the results by. + FilterByProject []uuid.UUID } type GroupUseCase struct { @@ -896,5 +896,5 @@ func (uc *GroupUseCase) ListProjectsByGroup(ctx context.Context, orgID uuid.UUID pgOpts = paginationOpts } - return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, opts.VisibleProjectsIDs, pgOpts) + return uc.groupRepo.ListProjectsByGroup(ctx, orgID, resolvedGroupID, opts.FilterByProject, pgOpts) }