From 7e449e32612fd4b6ebb4ca935c14a528c592ece2 Mon Sep 17 00:00:00 2001 From: Alex McGrath Date: Tue, 27 Feb 2024 16:54:21 -0800 Subject: [PATCH] check if user is in specified sub-accesslists --- .../teleport/accesslist/v1/accesslist.pb.go | 524 ++++++++++++------ .../teleport/accesslist/v1/accesslist.proto | 17 +- api/types/accesslist/accesslist.go | 22 + api/types/accesslist/convert/v1/accesslist.go | 39 +- .../teleport/accesslist/v1/accesslist_pb.ts | 114 +++- lib/auth/userloginstate/generator.go | 2 +- lib/modules/modules.go | 1 + lib/services/access_list.go | 73 ++- lib/services/access_list_test.go | 47 +- lib/services/access_request.go | 14 +- 10 files changed, 660 insertions(+), 193 deletions(-) diff --git a/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go b/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go index 2fadd87697a91..098bf6ea8b03a 100644 --- a/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go +++ b/api/gen/proto/go/teleport/accesslist/v1/accesslist.pb.go @@ -309,9 +309,12 @@ type AccessListSpec struct { Title string `protobuf:"bytes,8,opt,name=title,proto3" json:"title,omitempty"` // owner_grants describes the access granted by owners to this access list. OwnerGrants *AccessListGrants `protobuf:"bytes,11,opt,name=owner_grants,json=ownerGrants,proto3" json:"owner_grants,omitempty"` - // sub_access_lists is a list of access list ids that user + // member_access_lists is a list of access lists that user // membership should be fetched from - SubAccessLists []string `protobuf:"bytes,12,rep,name=sub_access_lists,json=subAccessLists,proto3" json:"sub_access_lists,omitempty"` + MemberAccessLists []*ParentAccessList `protobuf:"bytes,12,rep,name=member_access_lists,json=memberAccessLists,proto3" json:"member_access_lists,omitempty"` + // owner_access_lists is a list of access lists that owner + // membership should be fetched from + OwnerAccessLists []*ParentAccessList `protobuf:"bytes,13,rep,name=owner_access_lists,json=ownerAccessLists,proto3" json:"owner_access_lists,omitempty"` } func (x *AccessListSpec) Reset() { @@ -402,13 +405,79 @@ func (x *AccessListSpec) GetOwnerGrants() *AccessListGrants { return nil } -func (x *AccessListSpec) GetSubAccessLists() []string { +func (x *AccessListSpec) GetMemberAccessLists() []*ParentAccessList { + if x != nil { + return x.MemberAccessLists + } + return nil +} + +func (x *AccessListSpec) GetOwnerAccessLists() []*ParentAccessList { if x != nil { - return x.SubAccessLists + return x.OwnerAccessLists } return nil } +// ParentAccessList contains information about access lists included +// as parents in an access list +type ParentAccessList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the id of the parent access list + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // title is the title of the parent access list + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` +} + +func (x *ParentAccessList) Reset() { + *x = ParentAccessList{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ParentAccessList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ParentAccessList) ProtoMessage() {} + +func (x *ParentAccessList) ProtoReflect() protoreflect.Message { + mi := &file_teleport_accesslist_v1_accesslist_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 ParentAccessList.ProtoReflect.Descriptor instead. +func (*ParentAccessList) Descriptor() ([]byte, []int) { + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{2} +} + +func (x *ParentAccessList) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ParentAccessList) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + // AccessListOwner is an owner of an access list. type AccessListOwner struct { state protoimpl.MessageState @@ -428,7 +497,7 @@ type AccessListOwner struct { func (x *AccessListOwner) Reset() { *x = AccessListOwner{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[2] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -441,7 +510,7 @@ func (x *AccessListOwner) String() string { func (*AccessListOwner) ProtoMessage() {} func (x *AccessListOwner) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[2] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -454,7 +523,7 @@ func (x *AccessListOwner) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessListOwner.ProtoReflect.Descriptor instead. func (*AccessListOwner) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{2} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{3} } func (x *AccessListOwner) GetName() string { @@ -495,7 +564,7 @@ type AccessListAudit struct { func (x *AccessListAudit) Reset() { *x = AccessListAudit{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -508,7 +577,7 @@ func (x *AccessListAudit) String() string { func (*AccessListAudit) ProtoMessage() {} func (x *AccessListAudit) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[3] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -521,7 +590,7 @@ func (x *AccessListAudit) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessListAudit.ProtoReflect.Descriptor instead. func (*AccessListAudit) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{3} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{4} } func (x *AccessListAudit) GetNextAuditDate() *timestamppb.Timestamp { @@ -563,7 +632,7 @@ type Recurrence struct { func (x *Recurrence) Reset() { *x = Recurrence{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +645,7 @@ func (x *Recurrence) String() string { func (*Recurrence) ProtoMessage() {} func (x *Recurrence) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[4] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +658,7 @@ func (x *Recurrence) ProtoReflect() protoreflect.Message { // Deprecated: Use Recurrence.ProtoReflect.Descriptor instead. func (*Recurrence) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{4} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{5} } func (x *Recurrence) GetFrequency() ReviewFrequency { @@ -621,7 +690,7 @@ type Notifications struct { func (x *Notifications) Reset() { *x = Notifications{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -634,7 +703,7 @@ func (x *Notifications) String() string { func (*Notifications) ProtoMessage() {} func (x *Notifications) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[5] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -647,7 +716,7 @@ func (x *Notifications) ProtoReflect() protoreflect.Message { // Deprecated: Use Notifications.ProtoReflect.Descriptor instead. func (*Notifications) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{5} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{6} } func (x *Notifications) GetStart() *durationpb.Duration { @@ -674,7 +743,7 @@ type AccessListRequires struct { func (x *AccessListRequires) Reset() { *x = AccessListRequires{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -687,7 +756,7 @@ func (x *AccessListRequires) String() string { func (*AccessListRequires) ProtoMessage() {} func (x *AccessListRequires) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[6] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -700,7 +769,7 @@ func (x *AccessListRequires) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessListRequires.ProtoReflect.Descriptor instead. func (*AccessListRequires) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{6} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{7} } func (x *AccessListRequires) GetRoles() []string { @@ -735,7 +804,7 @@ type AccessListGrants struct { func (x *AccessListGrants) Reset() { *x = AccessListGrants{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[7] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -748,7 +817,7 @@ func (x *AccessListGrants) String() string { func (*AccessListGrants) ProtoMessage() {} func (x *AccessListGrants) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[7] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -761,7 +830,7 @@ func (x *AccessListGrants) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessListGrants.ProtoReflect.Descriptor instead. func (*AccessListGrants) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{7} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{8} } func (x *AccessListGrants) GetRoles() []string { @@ -793,7 +862,7 @@ type Member struct { func (x *Member) Reset() { *x = Member{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[8] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -806,7 +875,7 @@ func (x *Member) String() string { func (*Member) ProtoMessage() {} func (x *Member) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[8] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -819,7 +888,7 @@ func (x *Member) ProtoReflect() protoreflect.Message { // Deprecated: Use Member.ProtoReflect.Descriptor instead. func (*Member) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{8} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{9} } func (x *Member) GetHeader() *v1.ResourceHeader { @@ -862,7 +931,7 @@ type MemberSpec struct { func (x *MemberSpec) Reset() { *x = MemberSpec{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -875,7 +944,7 @@ func (x *MemberSpec) String() string { func (*MemberSpec) ProtoMessage() {} func (x *MemberSpec) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[9] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -888,7 +957,7 @@ func (x *MemberSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use MemberSpec.ProtoReflect.Descriptor instead. func (*MemberSpec) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{9} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{10} } func (x *MemberSpec) GetAccessList() string { @@ -955,7 +1024,7 @@ type Review struct { func (x *Review) Reset() { *x = Review{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -968,7 +1037,7 @@ func (x *Review) String() string { func (*Review) ProtoMessage() {} func (x *Review) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[10] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -981,7 +1050,7 @@ func (x *Review) ProtoReflect() protoreflect.Message { // Deprecated: Use Review.ProtoReflect.Descriptor instead. func (*Review) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{10} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{11} } func (x *Review) GetHeader() *v1.ResourceHeader { @@ -1020,7 +1089,7 @@ type ReviewSpec struct { func (x *ReviewSpec) Reset() { *x = ReviewSpec{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1033,7 +1102,7 @@ func (x *ReviewSpec) String() string { func (*ReviewSpec) ProtoMessage() {} func (x *ReviewSpec) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[11] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1046,7 +1115,7 @@ func (x *ReviewSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ReviewSpec.ProtoReflect.Descriptor instead. func (*ReviewSpec) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{11} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{12} } func (x *ReviewSpec) GetAccessList() string { @@ -1106,7 +1175,7 @@ type ReviewChanges struct { func (x *ReviewChanges) Reset() { *x = ReviewChanges{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1119,7 +1188,7 @@ func (x *ReviewChanges) String() string { func (*ReviewChanges) ProtoMessage() {} func (x *ReviewChanges) ProtoReflect() protoreflect.Message { - mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[12] + mi := &file_teleport_accesslist_v1_accesslist_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1132,7 +1201,7 @@ func (x *ReviewChanges) ProtoReflect() protoreflect.Message { // Deprecated: Use ReviewChanges.ProtoReflect.Descriptor instead. func (*ReviewChanges) Descriptor() ([]byte, []int) { - return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{12} + return file_teleport_accesslist_v1_accesslist_proto_rawDescGZIP(), []int{13} } func (x *ReviewChanges) GetMembershipRequirementsChanged() *AccessListRequires { @@ -1236,6 +1305,7 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, +<<<<<<< HEAD <<<<<<< HEAD 0x63, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, @@ -1452,6 +1522,9 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ======= 0x63, 0x22, 0x86, 0x05, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, +======= + 0x63, 0x22, 0x8e, 0x06, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) 0x53, 0x70, 0x65, 0x63, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x06, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, @@ -1488,134 +1561,141 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x0b, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x07, 0x10, - 0x08, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x0f, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 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, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x11, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, - 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, - 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, - 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x0f, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, - 0x42, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x02, 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, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, - 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x73, 0x12, 0x58, 0x0a, 0x13, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x9f, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, - 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x64, - 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x0a, 0x64, 0x61, 0x79, - 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x40, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x5c, 0x0a, 0x12, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, - 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, - 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, - 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, - 0x69, 0x74, 0x73, 0x22, 0x7c, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3a, 0x0a, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x11, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x12, 0x56, 0x0a, 0x12, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x22, 0xd5, 0x02, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 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, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x73, 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, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, - 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, - 0x42, 0x79, 0x12, 0x55, 0x0a, 0x11, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, + 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x10, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x10, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x22, 0x9e, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x77, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 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, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x11, 0x69, 0x6e, + 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x61, 0x75, + 0x64, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 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, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x72, 0x65, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, + 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4b, 0x0a, + 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, + 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x9f, 0x01, 0x0a, 0x0a, + 0x52, 0x65, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, - 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, - 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, 0x7c, 0x0a, 0x06, 0x52, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, + 0x68, 0x52, 0x0a, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x40, 0x0a, + 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, + 0x5c, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, + 0x72, 0x61, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x72, 0x61, 0x69, 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x22, 0x5a, 0x0a, + 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x69, + 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x69, 0x74, 0x73, 0x22, 0x7c, 0x0a, 0x06, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, - 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xdf, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xd5, 0x02, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, - 0x64, 0x61, 0x74, 0x65, 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, 0x0a, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, - 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x90, 0x03, 0x0a, 0x0d, 0x52, 0x65, - 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x72, 0x0a, 0x1f, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, - 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x18, 0x72, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x6a, + 0x6f, 0x69, 0x6e, 0x65, 0x64, 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, 0x06, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x12, + 0x34, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 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, 0x07, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, 0x79, 0x12, 0x55, 0x0a, 0x11, 0x69, 0x6e, 0x65, 0x6c, + 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x65, + 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x69, + 0x6e, 0x65, 0x6c, 0x69, 0x67, 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x22, + 0x7c, 0x0a, 0x06, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xdf, 0x01, + 0x0a, 0x0a, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x74, 0x65, 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, 0x0a, 0x72, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x3f, + 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, + 0x90, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x12, 0x72, 0x0a, 0x1f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x5f, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x52, 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x63, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x66, 0x0a, 0x1b, 0x72, - 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, - 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x52, 0x1d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, + 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x61, + 0x0a, 0x18, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, +<<<<<<< HEAD 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x52, 0x17, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, @@ -1661,6 +1741,58 @@ var file_teleport_accesslist_v1_accesslist_proto_rawDesc = []byte{ 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, >>>>>>> 8ec5e2d68d (make grpc) +======= + 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x16, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x12, 0x66, 0x0a, 0x1b, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x64, 0x61, 0x79, 0x5f, + 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, + 0x52, 0x17, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, + 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, + 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x2a, 0xb6, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x46, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, + 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x56, 0x49, + 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4f, 0x4e, 0x45, + 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x56, 0x49, + 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x54, 0x48, 0x52, + 0x45, 0x45, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x53, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x52, + 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, 0x5f, + 0x53, 0x49, 0x58, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x53, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, + 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x59, + 0x5f, 0x4f, 0x4e, 0x45, 0x5f, 0x59, 0x45, 0x41, 0x52, 0x10, 0x0c, 0x2a, 0x97, 0x01, 0x0a, 0x10, + 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x44, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, + 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, + 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, + 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x46, 0x49, 0x52, + 0x53, 0x54, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x44, + 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x46, 0x49, 0x46, 0x54, + 0x45, 0x45, 0x4e, 0x54, 0x48, 0x10, 0x0f, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x56, 0x49, 0x45, + 0x57, 0x5f, 0x44, 0x41, 0x59, 0x5f, 0x4f, 0x46, 0x5f, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x5f, 0x4c, + 0x41, 0x53, 0x54, 0x10, 0x1f, 0x2a, 0xc6, 0x01, 0x0a, 0x10, 0x49, 0x6e, 0x65, 0x6c, 0x69, 0x67, + 0x69, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d, 0x49, 0x4e, + 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, + 0x1a, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x24, 0x0a, + 0x20, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x58, 0x49, 0x53, + 0x54, 0x10, 0x02, 0x12, 0x2a, 0x0a, 0x26, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, + 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x53, 0x10, 0x03, 0x12, + 0x1d, 0x0a, 0x19, 0x49, 0x4e, 0x45, 0x4c, 0x49, 0x47, 0x49, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x42, 0x58, + 0x5a, 0x56, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) } var ( @@ -1683,6 +1815,7 @@ var file_teleport_accesslist_v1_accesslist_proto_goTypes = []interface{}{ (IneligibleStatus)(0), // 2: teleport.accesslist.v1.IneligibleStatus (*AccessList)(nil), // 3: teleport.accesslist.v1.AccessList (*AccessListSpec)(nil), // 4: teleport.accesslist.v1.AccessListSpec +<<<<<<< HEAD (*AccessListOwner)(nil), // 5: teleport.accesslist.v1.AccessListOwner (*AccessListAudit)(nil), // 6: teleport.accesslist.v1.AccessListAudit (*Recurrence)(nil), // 7: teleport.accesslist.v1.Recurrence @@ -1695,6 +1828,20 @@ var file_teleport_accesslist_v1_accesslist_proto_goTypes = []interface{}{ (*ReviewSpec)(nil), // 14: teleport.accesslist.v1.ReviewSpec (*ReviewChanges)(nil), // 15: teleport.accesslist.v1.ReviewChanges (*AccessListStatus)(nil), // 16: teleport.accesslist.v1.AccessListStatus +======= + (*ParentAccessList)(nil), // 5: teleport.accesslist.v1.ParentAccessList + (*AccessListOwner)(nil), // 6: teleport.accesslist.v1.AccessListOwner + (*AccessListAudit)(nil), // 7: teleport.accesslist.v1.AccessListAudit + (*Recurrence)(nil), // 8: teleport.accesslist.v1.Recurrence + (*Notifications)(nil), // 9: teleport.accesslist.v1.Notifications + (*AccessListRequires)(nil), // 10: teleport.accesslist.v1.AccessListRequires + (*AccessListGrants)(nil), // 11: teleport.accesslist.v1.AccessListGrants + (*Member)(nil), // 12: teleport.accesslist.v1.Member + (*MemberSpec)(nil), // 13: teleport.accesslist.v1.MemberSpec + (*Review)(nil), // 14: teleport.accesslist.v1.Review + (*ReviewSpec)(nil), // 15: teleport.accesslist.v1.ReviewSpec + (*ReviewChanges)(nil), // 16: teleport.accesslist.v1.ReviewChanges +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) (*v1.ResourceHeader)(nil), // 17: teleport.header.v1.ResourceHeader (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp (*durationpb.Duration)(nil), // 19: google.protobuf.Duration @@ -1703,6 +1850,7 @@ var file_teleport_accesslist_v1_accesslist_proto_goTypes = []interface{}{ var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{ 17, // 0: teleport.accesslist.v1.AccessList.header:type_name -> teleport.header.v1.ResourceHeader 4, // 1: teleport.accesslist.v1.AccessList.spec:type_name -> teleport.accesslist.v1.AccessListSpec +<<<<<<< HEAD 16, // 2: teleport.accesslist.v1.AccessList.status:type_name -> teleport.accesslist.v1.AccessListStatus 5, // 3: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner 6, // 4: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit @@ -1736,6 +1884,42 @@ var file_teleport_accesslist_v1_accesslist_proto_depIdxs = []int32{ 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 +======= + 6, // 2: teleport.accesslist.v1.AccessListSpec.owners:type_name -> teleport.accesslist.v1.AccessListOwner + 7, // 3: teleport.accesslist.v1.AccessListSpec.audit:type_name -> teleport.accesslist.v1.AccessListAudit + 10, // 4: teleport.accesslist.v1.AccessListSpec.membership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 10, // 5: teleport.accesslist.v1.AccessListSpec.ownership_requires:type_name -> teleport.accesslist.v1.AccessListRequires + 11, // 6: teleport.accesslist.v1.AccessListSpec.grants:type_name -> teleport.accesslist.v1.AccessListGrants + 11, // 7: teleport.accesslist.v1.AccessListSpec.owner_grants:type_name -> teleport.accesslist.v1.AccessListGrants + 5, // 8: teleport.accesslist.v1.AccessListSpec.member_access_lists:type_name -> teleport.accesslist.v1.ParentAccessList + 5, // 9: teleport.accesslist.v1.AccessListSpec.owner_access_lists:type_name -> teleport.accesslist.v1.ParentAccessList + 2, // 10: teleport.accesslist.v1.AccessListOwner.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus + 18, // 11: teleport.accesslist.v1.AccessListAudit.next_audit_date:type_name -> google.protobuf.Timestamp + 8, // 12: teleport.accesslist.v1.AccessListAudit.recurrence:type_name -> teleport.accesslist.v1.Recurrence + 9, // 13: teleport.accesslist.v1.AccessListAudit.notifications:type_name -> teleport.accesslist.v1.Notifications + 0, // 14: teleport.accesslist.v1.Recurrence.frequency:type_name -> teleport.accesslist.v1.ReviewFrequency + 1, // 15: teleport.accesslist.v1.Recurrence.day_of_month:type_name -> teleport.accesslist.v1.ReviewDayOfMonth + 19, // 16: teleport.accesslist.v1.Notifications.start:type_name -> google.protobuf.Duration + 20, // 17: teleport.accesslist.v1.AccessListRequires.traits:type_name -> teleport.trait.v1.Trait + 20, // 18: teleport.accesslist.v1.AccessListGrants.traits:type_name -> teleport.trait.v1.Trait + 17, // 19: teleport.accesslist.v1.Member.header:type_name -> teleport.header.v1.ResourceHeader + 13, // 20: teleport.accesslist.v1.Member.spec:type_name -> teleport.accesslist.v1.MemberSpec + 18, // 21: teleport.accesslist.v1.MemberSpec.joined:type_name -> google.protobuf.Timestamp + 18, // 22: teleport.accesslist.v1.MemberSpec.expires:type_name -> google.protobuf.Timestamp + 2, // 23: teleport.accesslist.v1.MemberSpec.ineligible_status:type_name -> teleport.accesslist.v1.IneligibleStatus + 17, // 24: teleport.accesslist.v1.Review.header:type_name -> teleport.header.v1.ResourceHeader + 15, // 25: teleport.accesslist.v1.Review.spec:type_name -> teleport.accesslist.v1.ReviewSpec + 18, // 26: teleport.accesslist.v1.ReviewSpec.review_date:type_name -> google.protobuf.Timestamp + 16, // 27: teleport.accesslist.v1.ReviewSpec.changes:type_name -> teleport.accesslist.v1.ReviewChanges + 10, // 28: teleport.accesslist.v1.ReviewChanges.membership_requirements_changed:type_name -> teleport.accesslist.v1.AccessListRequires + 0, // 29: teleport.accesslist.v1.ReviewChanges.review_frequency_changed:type_name -> teleport.accesslist.v1.ReviewFrequency + 1, // 30: teleport.accesslist.v1.ReviewChanges.review_day_of_month_changed:type_name -> teleport.accesslist.v1.ReviewDayOfMonth + 31, // [31:31] is the sub-list for method output_type + 31, // [31:31] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) } func init() { file_teleport_accesslist_v1_accesslist_proto_init() } @@ -1769,7 +1953,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessListOwner); i { + switch v := v.(*ParentAccessList); i { case 0: return &v.state case 1: @@ -1781,7 +1965,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessListAudit); i { + switch v := v.(*AccessListOwner); i { case 0: return &v.state case 1: @@ -1793,7 +1977,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Recurrence); i { + switch v := v.(*AccessListAudit); i { case 0: return &v.state case 1: @@ -1805,7 +1989,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Notifications); i { + switch v := v.(*Recurrence); i { case 0: return &v.state case 1: @@ -1817,7 +2001,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessListRequires); i { + switch v := v.(*Notifications); i { case 0: return &v.state case 1: @@ -1829,7 +2013,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessListGrants); i { + switch v := v.(*AccessListRequires); i { case 0: return &v.state case 1: @@ -1841,7 +2025,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Member); i { + switch v := v.(*AccessListGrants); i { case 0: return &v.state case 1: @@ -1853,7 +2037,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MemberSpec); i { + switch v := v.(*Member); i { case 0: return &v.state case 1: @@ -1865,7 +2049,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Review); i { + switch v := v.(*MemberSpec); i { case 0: return &v.state case 1: @@ -1877,7 +2061,7 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReviewSpec); i { + switch v := v.(*Review); i { case 0: return &v.state case 1: @@ -1889,6 +2073,18 @@ func file_teleport_accesslist_v1_accesslist_proto_init() { } } file_teleport_accesslist_v1_accesslist_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReviewSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_accesslist_v1_accesslist_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReviewChanges); i { case 0: return &v.state diff --git a/api/proto/teleport/accesslist/v1/accesslist.proto b/api/proto/teleport/accesslist/v1/accesslist.proto index 7eb25ff5f73fc..bfe9bc4b935c2 100644 --- a/api/proto/teleport/accesslist/v1/accesslist.proto +++ b/api/proto/teleport/accesslist/v1/accesslist.proto @@ -72,9 +72,22 @@ message AccessListSpec { // owner_grants describes the access granted by owners to this access list. AccessListGrants owner_grants = 11; - // sub_access_lists is a list of access list ids that user + // member_access_lists is a list of access lists that user // membership should be fetched from - repeated string sub_access_lists = 12; + repeated ParentAccessList member_access_lists = 12; + + // owner_access_lists is a list of access lists that owner + // membership should be fetched from + repeated ParentAccessList owner_access_lists = 13; +} + +// ParentAccessList contains information about access lists included +// as parents in an access list +message ParentAccessList { + // name is the id of the parent access list + string name = 1; + // title is the title of the parent access list + string title = 2; } // AccessListOwner is an owner of an access list. diff --git a/api/types/accesslist/accesslist.go b/api/types/accesslist/accesslist.go index b9f42f553e1e4..497642ca22b90 100644 --- a/api/types/accesslist/accesslist.go +++ b/api/types/accesslist/accesslist.go @@ -155,6 +155,14 @@ type Spec struct { // OwnerGrants describes the access granted by ownership of this access list. OwnerGrants Grants `json:"owner_grants" yaml:"owner_grants"` + + // MemberAccessLists is a list of AccessList ids that user membership + // should be fetched from + MemberAccessLists []ParentAccessList `json:"member_access_lists" yaml:"access_lists"` + + // OwnerAccessLists is a list of AccessLists that owner membership + // should be fetched from + OwnerAccessLists []ParentAccessList `json:"owner_access_lists" yaml:"access_lists"` } // Owner is an owner of an access list. @@ -227,6 +235,11 @@ type Status struct { MemberCount *uint32 } +type ParentAccessList struct { + Name string `json:"name" yaml:"name"` + Title string `json:"title" yaml:"title"` +} + // NewAccessList will create a new access list. func NewAccessList(metadata header.Metadata, spec Spec) (*AccessList, error) { accessList := &AccessList{ @@ -309,6 +322,15 @@ func (a *AccessList) CheckAndSetDefaults() error { } a.Spec.Owners = deduplicatedOwners + for _, memberACL := range append(a.Spec.MemberAccessLists, a.Spec.OwnerAccessLists...) { + if memberACL.Name == "" { + return trace.BadParameter("member access list name is missing") + } + if memberACL.Title == "" { + return trace.BadParameter("member access list title is missing") + } + } + return nil } diff --git a/api/types/accesslist/convert/v1/accesslist.go b/api/types/accesslist/convert/v1/accesslist.go index fb0d00c8a090f..6627564171765 100644 --- a/api/types/accesslist/convert/v1/accesslist.go +++ b/api/types/accesslist/convert/v1/accesslist.go @@ -92,13 +92,28 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl if msg.Spec.Audit.NextAuditDate != nil { nextAuditDate = msg.Spec.Audit.NextAuditDate.AsTime() } - var memberCount *uint32 if msg.Status != nil && msg.Status.MemberCount != nil { memberCount = new(uint32) *memberCount = *msg.Status.MemberCount } + var parentMemberAccessLists []accesslist.ParentAccessList + for _, al := range msg.Spec.MemberAccessLists { + parentMemberAccessLists = append(parentMemberAccessLists, accesslist.ParentAccessList{ + Name: al.Name, + Title: al.Title, + }) + } + + var parentOwnerAccessLists []accesslist.ParentAccessList + for _, al := range msg.Spec.OwnerAccessLists { + parentOwnerAccessLists = append(parentOwnerAccessLists, accesslist.ParentAccessList{ + Name: al.Name, + Title: al.Title, + }) + } + accessList, err := accesslist.NewAccessList(headerv1.FromMetadataProto(msg.Header.Metadata), accesslist.Spec{ Title: msg.Spec.Title, Description: msg.Spec.Description, @@ -120,7 +135,9 @@ func FromProto(msg *accesslistv1.AccessList, opts ...AccessListOption) (*accessl Roles: msg.Spec.Grants.Roles, Traits: traitv1.FromProto(msg.Spec.Grants.Traits), }, - OwnerGrants: ownerGrants, + OwnerGrants: ownerGrants, + OwnerAccessLists: parentOwnerAccessLists, + MemberAccessLists: parentMemberAccessLists, }) if err != nil { return nil, trace.Wrap(err) @@ -177,6 +194,20 @@ func ToProto(accessList *accesslist.AccessList) *accesslistv1.AccessList { memberCount = new(uint32) *memberCount = *accessList.Status.MemberCount } + var parentMemberAccessLists []*accesslistv1.ParentAccessList + for _, al := range accessList.Spec.MemberAccessLists { + parentMemberAccessLists = append(parentMemberAccessLists, &accesslistv1.ParentAccessList{ + Name: al.Name, + Title: al.Title, + }) + } + var parentOwnerAccessLists []*accesslistv1.ParentAccessList + for _, al := range accessList.Spec.OwnerAccessLists { + parentOwnerAccessLists = append(parentOwnerAccessLists, &accesslistv1.ParentAccessList{ + Name: al.Name, + Title: al.Title, + }) + } return &accesslistv1.AccessList{ Header: headerv1.ToResourceHeaderProto(accessList.ResourceHeader), @@ -206,7 +237,9 @@ func ToProto(accessList *accesslist.AccessList) *accesslistv1.AccessList { Roles: accessList.Spec.Grants.Roles, Traits: traitv1.ToProto(accessList.Spec.Grants.Traits), }, - OwnerGrants: ownerGrants, + OwnerGrants: ownerGrants, + MemberAccessLists: parentMemberAccessLists, + OwnerAccessLists: parentOwnerAccessLists, }, Status: &accesslistv1.AccessListStatus{ MemberCount: memberCount, diff --git a/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts b/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts index fe5602d85c8f6..b05566fe0cf9a 100644 --- a/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts +++ b/gen/proto/ts/teleport/accesslist/v1/accesslist_pb.ts @@ -119,12 +119,39 @@ export interface AccessListSpec { */ ownerGrants?: AccessListGrants; /** - * sub_access_lists is a list of access list ids that user + * member_access_lists is a list of access lists that user * membership should be fetched from * - * @generated from protobuf field: repeated string sub_access_lists = 12; + * @generated from protobuf field: repeated teleport.accesslist.v1.ParentAccessList member_access_lists = 12; */ - subAccessLists: string[]; + memberAccessLists: ParentAccessList[]; + /** + * owner_access_lists is a list of access lists that owner + * membership should be fetched from + * + * @generated from protobuf field: repeated teleport.accesslist.v1.ParentAccessList owner_access_lists = 13; + */ + ownerAccessLists: ParentAccessList[]; +} +/** + * ParentAccessList contains information about access lists included + * as parents in an access list + * + * @generated from protobuf message teleport.accesslist.v1.ParentAccessList + */ +export interface ParentAccessList { + /** + * name is the id of the parent access list + * + * @generated from protobuf field: string name = 1; + */ + name: string; + /** + * title is the title of the parent access list + * + * @generated from protobuf field: string title = 2; + */ + title: string; } /** * AccessListOwner is an owner of an access list. @@ -599,8 +626,13 @@ class AccessListSpec$Type extends MessageType { { no: 9, name: "membership", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 10, name: "ownership", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 11, name: "owner_grants", kind: "message", T: () => AccessListGrants }, +<<<<<<< HEAD { no: 12, name: "sub_access_lists", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } >>>>>>> 8ec5e2d68d (make grpc) +======= + { no: 12, name: "member_access_lists", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ParentAccessList }, + { no: 13, name: "owner_access_lists", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => ParentAccessList } +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) ]); } create(value?: PartialMessage): AccessListSpec { @@ -612,8 +644,13 @@ class AccessListSpec$Type extends MessageType { ======= message.membership = ""; message.ownership = ""; +<<<<<<< HEAD message.subAccessLists = []; >>>>>>> 8ec5e2d68d (make grpc) +======= + message.memberAccessLists = []; + message.ownerAccessLists = []; +>>>>>>> fa58f2a9cd (check if user is in specified sub-accesslists) if (value !== undefined) reflectionMergePartial(this, message, value); return message; @@ -647,8 +684,11 @@ class AccessListSpec$Type extends MessageType { case /* teleport.accesslist.v1.AccessListGrants owner_grants */ 11: message.ownerGrants = AccessListGrants.internalBinaryRead(reader, reader.uint32(), options, message.ownerGrants); break; - case /* repeated string sub_access_lists */ 12: - message.subAccessLists.push(reader.string()); + case /* repeated teleport.accesslist.v1.ParentAccessList member_access_lists */ 12: + message.memberAccessLists.push(ParentAccessList.internalBinaryRead(reader, reader.uint32(), options)); + break; + case /* repeated teleport.accesslist.v1.ParentAccessList owner_access_lists */ 13: + message.ownerAccessLists.push(ParentAccessList.internalBinaryRead(reader, reader.uint32(), options)); break; default: let u = options.readUnknownField; @@ -686,9 +726,12 @@ class AccessListSpec$Type extends MessageType { /* teleport.accesslist.v1.AccessListGrants owner_grants = 11; */ if (message.ownerGrants) AccessListGrants.internalBinaryWrite(message.ownerGrants, writer.tag(11, WireType.LengthDelimited).fork(), options).join(); - /* repeated string sub_access_lists = 12; */ - for (let i = 0; i < message.subAccessLists.length; i++) - writer.tag(12, WireType.LengthDelimited).string(message.subAccessLists[i]); + /* repeated teleport.accesslist.v1.ParentAccessList member_access_lists = 12; */ + for (let i = 0; i < message.memberAccessLists.length; i++) + ParentAccessList.internalBinaryWrite(message.memberAccessLists[i], writer.tag(12, WireType.LengthDelimited).fork(), options).join(); + /* repeated teleport.accesslist.v1.ParentAccessList owner_access_lists = 13; */ + for (let i = 0; i < message.ownerAccessLists.length; i++) + ParentAccessList.internalBinaryWrite(message.ownerAccessLists[i], writer.tag(13, WireType.LengthDelimited).fork(), options).join(); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -700,6 +743,61 @@ class AccessListSpec$Type extends MessageType { */ export const AccessListSpec = new AccessListSpec$Type(); // @generated message type with reflection information, may provide speed optimized methods +class ParentAccessList$Type extends MessageType { + constructor() { + super("teleport.accesslist.v1.ParentAccessList", [ + { no: 1, name: "name", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "title", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ParentAccessList { + const message = globalThis.Object.create((this.messagePrototype!)); + message.name = ""; + message.title = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ParentAccessList): ParentAccessList { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string name */ 1: + message.name = reader.string(); + break; + case /* string title */ 2: + message.title = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ParentAccessList, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string name = 1; */ + if (message.name !== "") + writer.tag(1, WireType.LengthDelimited).string(message.name); + /* string title = 2; */ + if (message.title !== "") + writer.tag(2, WireType.LengthDelimited).string(message.title); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.accesslist.v1.ParentAccessList + */ +export const ParentAccessList = new ParentAccessList$Type(); +// @generated message type with reflection information, may provide speed optimized methods class AccessListOwner$Type extends MessageType { constructor() { super("teleport.accesslist.v1.AccessListOwner", [ diff --git a/lib/auth/userloginstate/generator.go b/lib/auth/userloginstate/generator.go index 818e5a95d5d67..5d7595183a369 100644 --- a/lib/auth/userloginstate/generator.go +++ b/lib/auth/userloginstate/generator.go @@ -116,7 +116,7 @@ func NewGenerator(config GeneratorConfig) (*Generator, error) { accessLists: config.AccessLists, access: config.Access, usageEvents: config.UsageEvents, - memberChecker: services.NewAccessListMembershipChecker(config.Clock, config.AccessLists, config.Access), + memberChecker: services.NewAccessListMembershipChecker(config.Clock, config.AccessLists, config.AccessLists, config.Access), clock: config.Clock, }, nil } diff --git a/lib/modules/modules.go b/lib/modules/modules.go index d2d7fd3438893..589bf30228f3a 100644 --- a/lib/modules/modules.go +++ b/lib/modules/modules.go @@ -253,6 +253,7 @@ func (f Features) IsTeam() bool { type AccessResourcesGetter interface { ListAccessLists(context.Context, int, string) ([]*accesslist.AccessList, string, error) ListResources(ctx context.Context, req proto.ListResourcesRequest) (*types.ListResourcesResponse, error) + GetAccessList(context.Context, string) (*accesslist.AccessList, error) ListAccessListMembers(ctx context.Context, accessList string, pageSize int, pageToken string) (members []*accesslist.AccessListMember, nextToken string, err error) GetAccessListMember(ctx context.Context, accessList string, memberName string) (*accesslist.AccessListMember, error) diff --git a/lib/services/access_list.go b/lib/services/access_list.go index 2d71ae4b98903..c52412e3ec709 100644 --- a/lib/services/access_list.go +++ b/lib/services/access_list.go @@ -137,6 +137,12 @@ func (ImplicitAccessListError) Error() string { return "requested AccessList does not have explicit member list" } +// AccessListGetter defines an interface that can retrieve an access list. +type AccessListGetter interface { + // GetAccessList returns the specified access list resource. + GetAccessList(context.Context, string) (*accesslist.AccessList, error) +} + // AccessListMemberGetter defines an interface that can retrieve access list members. type AccessListMemberGetter interface { // GetAccessListMember returns the specified access list member resource. @@ -251,20 +257,38 @@ func IsAccessListOwner(identity tlsca.Identity, accessList *accesslist.AccessLis // AccessListMembershipChecker will check if users are members of an access list and // makes sure the user is not locked and meets membership requirements. type AccessListMembershipChecker struct { - members AccessListMemberGetter - locks LockGetter - clock clockwork.Clock + members AccessListMemberGetter + accessList AccessListGetter + locks LockGetter + clock clockwork.Clock } // NewAccessListMembershipChecker will create a new access list membership checker. -func NewAccessListMembershipChecker(clock clockwork.Clock, members AccessListMemberGetter, locks LockGetter) *AccessListMembershipChecker { +func NewAccessListMembershipChecker(clock clockwork.Clock, members AccessListMemberGetter, accessLists AccessListGetter, locks LockGetter) *AccessListMembershipChecker { return &AccessListMembershipChecker{ - members: members, - locks: locks, - clock: clock, + accessList: accessLists, + members: members, + locks: locks, + clock: clock, } } +func (a AccessListMembershipChecker) validAccessListMember(username string, member *accesslist.AccessListMember, err error) error { + if trace.IsNotFound(err) { + // The member has not been found, so we know they're not a member of this list. + return trace.NotFound("user %s is not a member of the access list", username) + } else if err != nil { + // Some other error has occurred + return trace.Wrap(err) + } + + expires := member.Spec.Expires + if !expires.IsZero() && !a.clock.Now().Before(expires) { + return trace.AccessDenied("user %s's membership has expired in the access list", username) + } + return nil +} + // IsAccessListMember will return true if the user is a member for the current list. func (a AccessListMembershipChecker) IsAccessListMember(ctx context.Context, identity tlsca.Identity, accessList *accesslist.AccessList) error { username := identity.Username @@ -297,6 +321,32 @@ func (a AccessListMembershipChecker) IsAccessListMember(ctx context.Context, ide return trace.AccessDenied("user %s's membership has expired in the access list", username) } + // check if a user is a member of any sub access lists + // + // todo(lxea)?: properly build and recurse the access list graph + var fromSubAccessList bool + for _, pal := range accessList.Spec.MemberAccessLists { + member, err := a.members.GetAccessListMember(ctx, pal.Name, username) + if err := a.validAccessListMember(username, member, err); err != nil { + return trace.Wrap(err) + } + subAccessList, err := a.accessList.GetAccessList(ctx, pal.Name) + if err != nil { + return trace.Wrap(err) + } + if !UserMeetsRequirements(identity, subAccessList.Spec.MembershipRequires) { + return trace.AccessDenied("user %s is a member, but does not have the roles or traits required to be a member of this list", username) + } + fromSubAccessList = true + } + + if accessList.HasExplicitMembership() && !fromSubAccessList { + member, err := a.members.GetAccessListMember(ctx, accessList.GetName(), username) + if err := a.validAccessListMember(username, member, err); err != nil { + return trace.Wrap(err) + } + } + if !UserMeetsRequirements(identity, accessList.Spec.MembershipRequires) { return trace.AccessDenied("user %s is a member, but does not have the roles or traits required to be a member of this list", username) } @@ -305,13 +355,14 @@ func (a AccessListMembershipChecker) IsAccessListMember(ctx context.Context, ide } // TODO(mdwn): Remove this in favor of using the access list membership checker. -func IsAccessListMember(ctx context.Context, identity tlsca.Identity, clock clockwork.Clock, accessList *accesslist.AccessList, members AccessListMemberGetter) error { +func IsAccessListMember(ctx context.Context, identity tlsca.Identity, clock clockwork.Clock, accessList *accesslist.AccessList, accessListGetter AccessListGetter, members AccessListMemberGetter) error { // See if the member getter also implements lock getter. If so, use it. Otherwise, nil is fine. lockGetter, _ := members.(LockGetter) return AccessListMembershipChecker{ - members: members, - locks: lockGetter, - clock: clock, + accessList: accessListGetter, + members: members, + locks: lockGetter, + clock: clock, }.IsAccessListMember(ctx, identity, accessList) } diff --git a/lib/services/access_list_test.go b/lib/services/access_list_test.go index 2b4acc5521054..35ffad873df6f 100644 --- a/lib/services/access_list_test.go +++ b/lib/services/access_list_test.go @@ -269,6 +269,12 @@ func TestIsAccessListOwner(t *testing.T) { type testMembersAndLockGetter struct { members map[string]map[string]*accesslist.AccessListMember locks map[string]types.Lock + lists map[string]*accesslist.AccessList +} + +// GetAccessList implements AccessListGetter. +func (t *testMembersAndLockGetter) GetAccessList(_ context.Context, name string) (*accesslist.AccessList, error) { + return t.lists[name], nil } // ListAccessListMembers returns a paginated list of all access list members. @@ -335,12 +341,29 @@ func requireAccessDenied(t require.TestingT, err error, i ...interface{}) { } func TestIsAccessListMemberChecker(t *testing.T) { + childAccessList, err := accesslist.NewAccessList(header.Metadata{ + Name: "child", + }, accesslist.Spec{ + Title: "hello", + + Grants: accesslist.Grants{ + Roles: []string{"grole1", "grole2"}, + Traits: map[string][]string{ + "gtrait1": {"gvalue1", "gvalue2"}, + "gtrait2": {"gvalue3", "gvalue4"}, + }, + }, + }) + require.NoError(t, err) + tests := []struct { name string identity tlsca.Identity memberCtx context.Context currentTime time.Time locks map[string]types.Lock + subAccessLists map[string]accesslist.AccessList + subAccessList *accesslist.AccessList errAssertionFunc require.ErrorAssertionFunc }{ { @@ -467,6 +490,21 @@ func TestIsAccessListMemberChecker(t *testing.T) { currentTime: time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC), errAssertionFunc: requireAccessDenied, }, + { + name: "is member via recursive access list", + identity: tlsca.Identity{ + Username: member1, + Groups: []string{"mrole1", "mrole2"}, + Traits: map[string][]string{ + "mtrait1": {"mvalue1", "mvalue2"}, + "mtrait2": {"mvalue3", "mvalue4"}, + }, + }, + membership: accesslist.InclusionExplicit, + currentTime: time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC), + errAssertionFunc: require.NoError, + subAccessList: childAccessList, + }, } for _, test := range tests { @@ -479,6 +517,10 @@ func TestIsAccessListMemberChecker(t *testing.T) { accessList := newAccessList(t) members := newAccessListMembers(t) + // if test.subAccessLists != nil { + // accessList.Spec.SubAccessLists = []string{test.subAccessList.GetName()} + // } + memberMap := map[string]map[string]*accesslist.AccessListMember{} for _, member := range members { accessListName := member.Spec.AccessList @@ -487,9 +529,10 @@ func TestIsAccessListMemberChecker(t *testing.T) { } memberMap[accessListName][member.Spec.Name] = member } - getter := &testMembersAndLockGetter{members: memberMap, locks: test.locks} - checker := NewAccessListMembershipChecker(clockwork.NewFakeClockAt(test.currentTime), getter, getter) + getter := &testMembersAndLockGetter{members: memberMap, locks: test.locks, lists: nil} + + checker := NewAccessListMembershipChecker(clockwork.NewFakeClockAt(test.currentTime), getter, getter, getter) test.errAssertionFunc(t, checker.IsAccessListMember(ctx, test.identity, accessList)) }) } diff --git a/lib/services/access_request.go b/lib/services/access_request.go index 5ae13c5081c8a..328ad3ae8b4c4 100644 --- a/lib/services/access_request.go +++ b/lib/services/access_request.go @@ -1624,13 +1624,23 @@ Outer: // SystemAnnotations calculates the system annotations for a pending // access request. func (m *RequestValidator) SystemAnnotations() map[string][]string { + roles, _ := FetchRoles(m.userState.GetRoles(), m.getter, m.userState.GetTraits()) annotations := make(map[string][]string) + for k, va := range m.Annotations.Allow { var filtered []string + outer: for _, v := range va { - if !slices.Contains(m.Annotations.Deny[k], v) { - filtered = append(filtered, v) + for _, role := range roles { + if !slices.Contains(role.GetAccessRequestConditions(types.Allow).Annotations[k], v) { + continue outer + } } + if slices.Contains(m.Annotations.Deny[k], v) { + continue + } + filtered = append(filtered, v) + } if len(filtered) == 0 { continue