diff --git a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go index b1a20c91..b6239a45 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord.pb.go @@ -140,8 +140,17 @@ type AclRoot struct { EncryptedOwnerMetadata []byte `protobuf:"bytes,9,opt,name=encryptedOwnerMetadata,proto3" json:"encryptedOwnerMetadata,omitempty"` OneToOneInfo *AclOneToOneInfo `protobuf:"bytes,10,opt,name=oneToOneInfo,proto3" json:"oneToOneInfo,omitempty"` Options *AclSpaceOptions `protobuf:"bytes,11,opt,name=options,proto3" json:"options,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // parentSpaceId declares this space a child of the parent space (nested spaces); empty for top-level spaces. + // Mirrors SpaceHeader.parentSpaceId so the ACL is self-describing. + ParentSpaceId string `protobuf:"bytes,12,opt,name=parentSpaceId,proto3" json:"parentSpaceId,omitempty"` + // legalOwner is the public key of the parent space's owner at genesis. It anchors the + // signature-induction chain advanced by AclLegalOwnerUpdate; empty for top-level spaces. + LegalOwner []byte `protobuf:"bytes,13,opt,name=legalOwner,proto3" json:"legalOwner,omitempty"` + // parentAclRootId is the parent space's acl root record id — the binding scope for + // AclLegalOwnerUpdate proofs; set together with parentSpaceId/legalOwner. + ParentAclRootId string `protobuf:"bytes,14,opt,name=parentAclRootId,proto3" json:"parentAclRootId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AclRoot) Reset() { @@ -251,12 +260,39 @@ func (x *AclRoot) GetOptions() *AclSpaceOptions { return nil } +func (x *AclRoot) GetParentSpaceId() string { + if x != nil { + return x.ParentSpaceId + } + return "" +} + +func (x *AclRoot) GetLegalOwner() []byte { + if x != nil { + return x.LegalOwner + } + return nil +} + +func (x *AclRoot) GetParentAclRootId() string { + if x != nil { + return x.ParentAclRootId + } + return "" +} + // AclSpaceOptions contains space-level toggles/options type AclSpaceOptions struct { state protoimpl.MessageState `protogen:"open.v1"` DeleteRestricted bool `protobuf:"varint,1,opt,name=deleteRestricted,proto3" json:"deleteRestricted,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // editorsCanCompleteKeylessRotation lets Writers author the standalone read-key rotation + // that completes a pending keyless removal (nested spaces); off = admins/owner only + EditorsCanCompleteKeylessRotation bool `protobuf:"varint,2,opt,name=editorsCanCompleteKeylessRotation,proto3" json:"editorsCanCompleteKeylessRotation,omitempty"` + // childrenCreationDisallowed forbids registering child spaces under this space (nested spaces); + // zero value = children allowed, Admin+ may register + ChildrenCreationDisallowed bool `protobuf:"varint,3,opt,name=childrenCreationDisallowed,proto3" json:"childrenCreationDisallowed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AclSpaceOptions) Reset() { @@ -296,6 +332,20 @@ func (x *AclSpaceOptions) GetDeleteRestricted() bool { return false } +func (x *AclSpaceOptions) GetEditorsCanCompleteKeylessRotation() bool { + if x != nil { + return x.EditorsCanCompleteKeylessRotation + } + return false +} + +func (x *AclSpaceOptions) GetChildrenCreationDisallowed() bool { + if x != nil { + return x.ChildrenCreationDisallowed + } + return false +} + // AclSpaceOptionsChange changes space options (owner-only) type AclSpaceOptionsChange struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -523,8 +573,13 @@ type AclOwnershipChange struct { state protoimpl.MessageState `protogen:"open.v1"` NewOwnerIdentity []byte `protobuf:"bytes,1,opt,name=newOwnerIdentity,proto3" json:"newOwnerIdentity,omitempty"` OldOwnerPermissions AclUserPermissions `protobuf:"varint,2,opt,name=oldOwnerPermissions,proto3,enum=aclrecord.AclUserPermissions" json:"oldOwnerPermissions,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // aclRootId binds the transfer to the acl it belongs to (the acl root record id). + // Optional for backward compatibility, but REQUIRED for a record to serve as an + // AclLegalOwnerUpdate proof — without it a genuine transfer of any other space + // signed by the same key could be replayed to take over a child's governance. + AclRootId string `protobuf:"bytes,3,opt,name=aclRootId,proto3" json:"aclRootId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AclOwnershipChange) Reset() { @@ -571,6 +626,13 @@ func (x *AclOwnershipChange) GetOldOwnerPermissions() AclUserPermissions { return AclUserPermissions_None } +func (x *AclOwnershipChange) GetAclRootId() string { + if x != nil { + return x.AclRootId + } + return "" +} + // AclAccountRequestJoin contains the reference to the invite record and the data of the person who wants to join, confirmed by the private invite key type AclAccountRequestJoin struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1330,6 +1392,54 @@ func (x *AclAccountRemove) GetReadKeyChange() *AclReadKeyChange { return nil } +// AclAccountRemoveNoRotate removes accounts WITHOUT a read-key rotation. Only the legalOwner of a +// child (nested) space may author it — it is the keyless-governance removal: membership drops to +// None immediately, and the space enters a pending-rotation state until a key-holding member +// authors a standard AclReadKeyChange. Never use for ordinary removals — use AclAccountRemove. +type AclAccountRemoveNoRotate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Identities [][]byte `protobuf:"bytes,1,rep,name=identities,proto3" json:"identities,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AclAccountRemoveNoRotate) Reset() { + *x = AclAccountRemoveNoRotate{} + mi := &file_aclrecord_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AclAccountRemoveNoRotate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AclAccountRemoveNoRotate) ProtoMessage() {} + +func (x *AclAccountRemoveNoRotate) ProtoReflect() protoreflect.Message { + mi := &file_aclrecord_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AclAccountRemoveNoRotate.ProtoReflect.Descriptor instead. +func (*AclAccountRemoveNoRotate) Descriptor() ([]byte, []int) { + return file_aclrecord_proto_rawDescGZIP(), []int{20} +} + +func (x *AclAccountRemoveNoRotate) GetIdentities() [][]byte { + if x != nil { + return x.Identities + } + return nil +} + // AclAccountRequestRemove adds a request to remove an account type AclAccountRequestRemove struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1339,7 +1449,7 @@ type AclAccountRequestRemove struct { func (x *AclAccountRequestRemove) Reset() { *x = AclAccountRequestRemove{} - mi := &file_aclrecord_proto_msgTypes[20] + mi := &file_aclrecord_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1351,7 +1461,7 @@ func (x *AclAccountRequestRemove) String() string { func (*AclAccountRequestRemove) ProtoMessage() {} func (x *AclAccountRequestRemove) ProtoReflect() protoreflect.Message { - mi := &file_aclrecord_proto_msgTypes[20] + mi := &file_aclrecord_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1364,7 +1474,163 @@ func (x *AclAccountRequestRemove) ProtoReflect() protoreflect.Message { // Deprecated: Use AclAccountRequestRemove.ProtoReflect.Descriptor instead. func (*AclAccountRequestRemove) Descriptor() ([]byte, []int) { - return file_aclrecord_proto_rawDescGZIP(), []int{20} + return file_aclrecord_proto_rawDescGZIP(), []int{21} +} + +// AclChildRegister registers a child space under THIS (parent) space +type AclChildRegister struct { + state protoimpl.MessageState `protogen:"open.v1"` + ChildSpaceId string `protobuf:"bytes,1,opt,name=childSpaceId,proto3" json:"childSpaceId,omitempty"` + // childAclRootId binds the registration to a specific child ACL root record + ChildAclRootId string `protobuf:"bytes,2,opt,name=childAclRootId,proto3" json:"childAclRootId,omitempty"` + // orgPermission is the permission the parent grants ITSELF in the child (None = keyless governance only) + OrgPermission AclUserPermissions `protobuf:"varint,3,opt,name=orgPermission,proto3,enum=aclrecord.AclUserPermissions" json:"orgPermission,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AclChildRegister) Reset() { + *x = AclChildRegister{} + mi := &file_aclrecord_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AclChildRegister) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AclChildRegister) ProtoMessage() {} + +func (x *AclChildRegister) ProtoReflect() protoreflect.Message { + mi := &file_aclrecord_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AclChildRegister.ProtoReflect.Descriptor instead. +func (*AclChildRegister) Descriptor() ([]byte, []int) { + return file_aclrecord_proto_rawDescGZIP(), []int{22} +} + +func (x *AclChildRegister) GetChildSpaceId() string { + if x != nil { + return x.ChildSpaceId + } + return "" +} + +func (x *AclChildRegister) GetChildAclRootId() string { + if x != nil { + return x.ChildAclRootId + } + return "" +} + +func (x *AclChildRegister) GetOrgPermission() AclUserPermissions { + if x != nil { + return x.OrgPermission + } + return AclUserPermissions_None +} + +// AclChildRegisterRevoke de-lists a previously registered child space +type AclChildRegisterRevoke struct { + state protoimpl.MessageState `protogen:"open.v1"` + ChildSpaceId string `protobuf:"bytes,1,opt,name=childSpaceId,proto3" json:"childSpaceId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AclChildRegisterRevoke) Reset() { + *x = AclChildRegisterRevoke{} + mi := &file_aclrecord_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AclChildRegisterRevoke) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AclChildRegisterRevoke) ProtoMessage() {} + +func (x *AclChildRegisterRevoke) ProtoReflect() protoreflect.Message { + mi := &file_aclrecord_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AclChildRegisterRevoke.ProtoReflect.Descriptor instead. +func (*AclChildRegisterRevoke) Descriptor() ([]byte, []int) { + return file_aclrecord_proto_rawDescGZIP(), []int{23} +} + +func (x *AclChildRegisterRevoke) GetChildSpaceId() string { + if x != nil { + return x.ChildSpaceId + } + return "" +} + +// AclLegalOwnerUpdate advances the stored legalOwner of THIS (child) space after parent ownership transfers. +// Each entry is a raw consensus record (consensusproto.RawRecord bytes) from the PARENT acl containing exactly +// one AclOwnershipChange. Validation is signature induction: the first record must be signed by the currently +// stored legalOwner, each next by the owner the previous one named; the author of this record must be the final owner. +type AclLegalOwnerUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + OwnershipChanges [][]byte `protobuf:"bytes,1,rep,name=ownershipChanges,proto3" json:"ownershipChanges,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AclLegalOwnerUpdate) Reset() { + *x = AclLegalOwnerUpdate{} + mi := &file_aclrecord_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AclLegalOwnerUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AclLegalOwnerUpdate) ProtoMessage() {} + +func (x *AclLegalOwnerUpdate) ProtoReflect() protoreflect.Message { + mi := &file_aclrecord_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AclLegalOwnerUpdate.ProtoReflect.Descriptor instead. +func (*AclLegalOwnerUpdate) Descriptor() ([]byte, []int) { + return file_aclrecord_proto_rawDescGZIP(), []int{24} +} + +func (x *AclLegalOwnerUpdate) GetOwnershipChanges() [][]byte { + if x != nil { + return x.OwnershipChanges + } + return nil } // AclContentValue contains possible values for Acl @@ -1388,6 +1654,10 @@ type AclContentValue struct { // *AclContentValue_InviteChange // *AclContentValue_OwnershipChange // *AclContentValue_SpaceOptionsChange + // *AclContentValue_ChildRegister + // *AclContentValue_ChildRegisterRevoke + // *AclContentValue_LegalOwnerUpdate + // *AclContentValue_AccountRemoveNoRotate Value isAclContentValue_Value `protobuf_oneof:"value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1395,7 +1665,7 @@ type AclContentValue struct { func (x *AclContentValue) Reset() { *x = AclContentValue{} - mi := &file_aclrecord_proto_msgTypes[21] + mi := &file_aclrecord_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1407,7 +1677,7 @@ func (x *AclContentValue) String() string { func (*AclContentValue) ProtoMessage() {} func (x *AclContentValue) ProtoReflect() protoreflect.Message { - mi := &file_aclrecord_proto_msgTypes[21] + mi := &file_aclrecord_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1420,7 +1690,7 @@ func (x *AclContentValue) ProtoReflect() protoreflect.Message { // Deprecated: Use AclContentValue.ProtoReflect.Descriptor instead. func (*AclContentValue) Descriptor() ([]byte, []int) { - return file_aclrecord_proto_rawDescGZIP(), []int{21} + return file_aclrecord_proto_rawDescGZIP(), []int{25} } func (x *AclContentValue) GetValue() isAclContentValue_Value { @@ -1574,6 +1844,42 @@ func (x *AclContentValue) GetSpaceOptionsChange() *AclSpaceOptionsChange { return nil } +func (x *AclContentValue) GetChildRegister() *AclChildRegister { + if x != nil { + if x, ok := x.Value.(*AclContentValue_ChildRegister); ok { + return x.ChildRegister + } + } + return nil +} + +func (x *AclContentValue) GetChildRegisterRevoke() *AclChildRegisterRevoke { + if x != nil { + if x, ok := x.Value.(*AclContentValue_ChildRegisterRevoke); ok { + return x.ChildRegisterRevoke + } + } + return nil +} + +func (x *AclContentValue) GetLegalOwnerUpdate() *AclLegalOwnerUpdate { + if x != nil { + if x, ok := x.Value.(*AclContentValue_LegalOwnerUpdate); ok { + return x.LegalOwnerUpdate + } + } + return nil +} + +func (x *AclContentValue) GetAccountRemoveNoRotate() *AclAccountRemoveNoRotate { + if x != nil { + if x, ok := x.Value.(*AclContentValue_AccountRemoveNoRotate); ok { + return x.AccountRemoveNoRotate + } + } + return nil +} + type isAclContentValue_Value interface { isAclContentValue_Value() } @@ -1643,6 +1949,22 @@ type AclContentValue_SpaceOptionsChange struct { SpaceOptionsChange *AclSpaceOptionsChange `protobuf:"bytes,16,opt,name=spaceOptionsChange,proto3,oneof"` } +type AclContentValue_ChildRegister struct { + ChildRegister *AclChildRegister `protobuf:"bytes,17,opt,name=childRegister,proto3,oneof"` +} + +type AclContentValue_ChildRegisterRevoke struct { + ChildRegisterRevoke *AclChildRegisterRevoke `protobuf:"bytes,18,opt,name=childRegisterRevoke,proto3,oneof"` +} + +type AclContentValue_LegalOwnerUpdate struct { + LegalOwnerUpdate *AclLegalOwnerUpdate `protobuf:"bytes,19,opt,name=legalOwnerUpdate,proto3,oneof"` +} + +type AclContentValue_AccountRemoveNoRotate struct { + AccountRemoveNoRotate *AclAccountRemoveNoRotate `protobuf:"bytes,20,opt,name=accountRemoveNoRotate,proto3,oneof"` +} + func (*AclContentValue_Invite) isAclContentValue_Value() {} func (*AclContentValue_InviteRevoke) isAclContentValue_Value() {} @@ -1675,6 +1997,14 @@ func (*AclContentValue_OwnershipChange) isAclContentValue_Value() {} func (*AclContentValue_SpaceOptionsChange) isAclContentValue_Value() {} +func (*AclContentValue_ChildRegister) isAclContentValue_Value() {} + +func (*AclContentValue_ChildRegisterRevoke) isAclContentValue_Value() {} + +func (*AclContentValue_LegalOwnerUpdate) isAclContentValue_Value() {} + +func (*AclContentValue_AccountRemoveNoRotate) isAclContentValue_Value() {} + // AclData contains different acl content type AclData struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1685,7 +2015,7 @@ type AclData struct { func (x *AclData) Reset() { *x = AclData{} - mi := &file_aclrecord_proto_msgTypes[22] + mi := &file_aclrecord_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1697,7 +2027,7 @@ func (x *AclData) String() string { func (*AclData) ProtoMessage() {} func (x *AclData) ProtoReflect() protoreflect.Message { - mi := &file_aclrecord_proto_msgTypes[22] + mi := &file_aclrecord_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1710,7 +2040,7 @@ func (x *AclData) ProtoReflect() protoreflect.Message { // Deprecated: Use AclData.ProtoReflect.Descriptor instead. func (*AclData) Descriptor() ([]byte, []int) { - return file_aclrecord_proto_rawDescGZIP(), []int{22} + return file_aclrecord_proto_rawDescGZIP(), []int{26} } func (x *AclData) GetAclContent() []*AclContentValue { @@ -1724,7 +2054,7 @@ var File_aclrecord_proto protoreflect.FileDescriptor const file_aclrecord_proto_rawDesc = "" + "\n" + - "\x0faclrecord.proto\x12\taclrecord\"\xe7\x03\n" + + "\x0faclrecord.proto\x12\taclrecord\"\xd7\x04\n" + "\aAclRoot\x12\x1a\n" + "\bidentity\x18\x01 \x01(\fR\bidentity\x12\x1c\n" + "\tmasterKey\x18\x02 \x01(\fR\tmasterKey\x12\x18\n" + @@ -1737,9 +2067,16 @@ const file_aclrecord_proto_rawDesc = "" + "\x16encryptedOwnerMetadata\x18\t \x01(\fR\x16encryptedOwnerMetadata\x12>\n" + "\foneToOneInfo\x18\n" + " \x01(\v2\x1a.aclrecord.AclOneToOneInfoR\foneToOneInfo\x124\n" + - "\aoptions\x18\v \x01(\v2\x1a.aclrecord.AclSpaceOptionsR\aoptions\"=\n" + + "\aoptions\x18\v \x01(\v2\x1a.aclrecord.AclSpaceOptionsR\aoptions\x12$\n" + + "\rparentSpaceId\x18\f \x01(\tR\rparentSpaceId\x12\x1e\n" + + "\n" + + "legalOwner\x18\r \x01(\fR\n" + + "legalOwner\x12(\n" + + "\x0fparentAclRootId\x18\x0e \x01(\tR\x0fparentAclRootId\"\xcb\x01\n" + "\x0fAclSpaceOptions\x12*\n" + - "\x10deleteRestricted\x18\x01 \x01(\bR\x10deleteRestricted\"M\n" + + "\x10deleteRestricted\x18\x01 \x01(\bR\x10deleteRestricted\x12L\n" + + "!editorsCanCompleteKeylessRotation\x18\x02 \x01(\bR!editorsCanCompleteKeylessRotation\x12>\n" + + "\x1achildrenCreationDisallowed\x18\x03 \x01(\bR\x1achildrenCreationDisallowed\"M\n" + "\x15AclSpaceOptionsChange\x124\n" + "\aoptions\x18\x01 \x01(\v2\x1a.aclrecord.AclSpaceOptionsR\aoptions\"A\n" + "\x0fAclOneToOneInfo\x12\x14\n" + @@ -1754,10 +2091,11 @@ const file_aclrecord_proto_rawDesc = "" + "\x10encryptedReadKey\x18\x04 \x01(\fR\x10encryptedReadKey\"\x81\x01\n" + "\x16AclAccountInviteChange\x12&\n" + "\x0einviteRecordId\x18\x01 \x01(\tR\x0einviteRecordId\x12?\n" + - "\vpermissions\x18\x02 \x01(\x0e2\x1d.aclrecord.AclUserPermissionsR\vpermissions\"\x91\x01\n" + + "\vpermissions\x18\x02 \x01(\x0e2\x1d.aclrecord.AclUserPermissionsR\vpermissions\"\xaf\x01\n" + "\x12AclOwnershipChange\x12*\n" + "\x10newOwnerIdentity\x18\x01 \x01(\fR\x10newOwnerIdentity\x12O\n" + - "\x13oldOwnerPermissions\x18\x02 \x01(\x0e2\x1d.aclrecord.AclUserPermissionsR\x13oldOwnerPermissions\"\xbd\x01\n" + + "\x13oldOwnerPermissions\x18\x02 \x01(\x0e2\x1d.aclrecord.AclUserPermissionsR\x13oldOwnerPermissions\x12\x1c\n" + + "\taclRootId\x18\x03 \x01(\tR\taclRootId\"\xbd\x01\n" + "\x15AclAccountRequestJoin\x12&\n" + "\x0einviteIdentity\x18\x01 \x01(\fR\x0einviteIdentity\x12&\n" + "\x0einviteRecordId\x18\x02 \x01(\tR\x0einviteRecordId\x128\n" + @@ -1808,8 +2146,20 @@ const file_aclrecord_proto_rawDesc = "" + "\n" + "identities\x18\x01 \x03(\fR\n" + "identities\x12A\n" + - "\rreadKeyChange\x18\x02 \x01(\v2\x1b.aclrecord.AclReadKeyChangeR\rreadKeyChange\"\x19\n" + - "\x17AclAccountRequestRemove\"\xc2\t\n" + + "\rreadKeyChange\x18\x02 \x01(\v2\x1b.aclrecord.AclReadKeyChangeR\rreadKeyChange\":\n" + + "\x18AclAccountRemoveNoRotate\x12\x1e\n" + + "\n" + + "identities\x18\x01 \x03(\fR\n" + + "identities\"\x19\n" + + "\x17AclAccountRequestRemove\"\xa3\x01\n" + + "\x10AclChildRegister\x12\"\n" + + "\fchildSpaceId\x18\x01 \x01(\tR\fchildSpaceId\x12&\n" + + "\x0echildAclRootId\x18\x02 \x01(\tR\x0echildAclRootId\x12C\n" + + "\rorgPermission\x18\x03 \x01(\x0e2\x1d.aclrecord.AclUserPermissionsR\rorgPermission\"<\n" + + "\x16AclChildRegisterRevoke\x12\"\n" + + "\fchildSpaceId\x18\x01 \x01(\tR\fchildSpaceId\"A\n" + + "\x13AclLegalOwnerUpdate\x12*\n" + + "\x10ownershipChanges\x18\x01 \x03(\fR\x10ownershipChanges\"\x89\f\n" + "\x0fAclContentValue\x125\n" + "\x06invite\x18\x01 \x01(\v2\x1b.aclrecord.AclAccountInviteH\x00R\x06invite\x12G\n" + "\finviteRevoke\x18\x02 \x01(\v2!.aclrecord.AclAccountInviteRevokeH\x00R\finviteRevoke\x12D\n" + @@ -1829,7 +2179,11 @@ const file_aclrecord_proto_rawDesc = "" + "inviteJoin\x12G\n" + "\finviteChange\x18\x0e \x01(\v2!.aclrecord.AclAccountInviteChangeH\x00R\finviteChange\x12I\n" + "\x0fownershipChange\x18\x0f \x01(\v2\x1d.aclrecord.AclOwnershipChangeH\x00R\x0fownershipChange\x12R\n" + - "\x12spaceOptionsChange\x18\x10 \x01(\v2 .aclrecord.AclSpaceOptionsChangeH\x00R\x12spaceOptionsChangeB\a\n" + + "\x12spaceOptionsChange\x18\x10 \x01(\v2 .aclrecord.AclSpaceOptionsChangeH\x00R\x12spaceOptionsChange\x12C\n" + + "\rchildRegister\x18\x11 \x01(\v2\x1b.aclrecord.AclChildRegisterH\x00R\rchildRegister\x12U\n" + + "\x13childRegisterRevoke\x18\x12 \x01(\v2!.aclrecord.AclChildRegisterRevokeH\x00R\x13childRegisterRevoke\x12L\n" + + "\x10legalOwnerUpdate\x18\x13 \x01(\v2\x1e.aclrecord.AclLegalOwnerUpdateH\x00R\x10legalOwnerUpdate\x12[\n" + + "\x15accountRemoveNoRotate\x18\x14 \x01(\v2#.aclrecord.AclAccountRemoveNoRotateH\x00R\x15accountRemoveNoRotateB\a\n" + "\x05value\"E\n" + "\aAclData\x12:\n" + "\n" + @@ -1861,7 +2215,7 @@ func file_aclrecord_proto_rawDescGZIP() []byte { } var file_aclrecord_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_aclrecord_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_aclrecord_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_aclrecord_proto_goTypes = []any{ (AclInviteType)(0), // 0: aclrecord.AclInviteType (AclUserPermissions)(0), // 1: aclrecord.AclUserPermissions @@ -1885,9 +2239,13 @@ var file_aclrecord_proto_goTypes = []any{ (*AclAccountPermissionChange)(nil), // 19: aclrecord.AclAccountPermissionChange (*AclReadKeyChange)(nil), // 20: aclrecord.AclReadKeyChange (*AclAccountRemove)(nil), // 21: aclrecord.AclAccountRemove - (*AclAccountRequestRemove)(nil), // 22: aclrecord.AclAccountRequestRemove - (*AclContentValue)(nil), // 23: aclrecord.AclContentValue - (*AclData)(nil), // 24: aclrecord.AclData + (*AclAccountRemoveNoRotate)(nil), // 22: aclrecord.AclAccountRemoveNoRotate + (*AclAccountRequestRemove)(nil), // 23: aclrecord.AclAccountRequestRemove + (*AclChildRegister)(nil), // 24: aclrecord.AclChildRegister + (*AclChildRegisterRevoke)(nil), // 25: aclrecord.AclChildRegisterRevoke + (*AclLegalOwnerUpdate)(nil), // 26: aclrecord.AclLegalOwnerUpdate + (*AclContentValue)(nil), // 27: aclrecord.AclContentValue + (*AclData)(nil), // 28: aclrecord.AclData } var file_aclrecord_proto_depIdxs = []int32{ 5, // 0: aclrecord.AclRoot.oneToOneInfo:type_name -> aclrecord.AclOneToOneInfo @@ -1906,28 +2264,33 @@ var file_aclrecord_proto_depIdxs = []int32{ 14, // 13: aclrecord.AclReadKeyChange.accountKeys:type_name -> aclrecord.AclEncryptedReadKey 14, // 14: aclrecord.AclReadKeyChange.inviteKeys:type_name -> aclrecord.AclEncryptedReadKey 20, // 15: aclrecord.AclAccountRemove.readKeyChange:type_name -> aclrecord.AclReadKeyChange - 6, // 16: aclrecord.AclContentValue.invite:type_name -> aclrecord.AclAccountInvite - 13, // 17: aclrecord.AclContentValue.inviteRevoke:type_name -> aclrecord.AclAccountInviteRevoke - 9, // 18: aclrecord.AclContentValue.requestJoin:type_name -> aclrecord.AclAccountRequestJoin - 11, // 19: aclrecord.AclContentValue.requestAccept:type_name -> aclrecord.AclAccountRequestAccept - 19, // 20: aclrecord.AclContentValue.permissionChange:type_name -> aclrecord.AclAccountPermissionChange - 21, // 21: aclrecord.AclContentValue.accountRemove:type_name -> aclrecord.AclAccountRemove - 20, // 22: aclrecord.AclContentValue.readKeyChange:type_name -> aclrecord.AclReadKeyChange - 12, // 23: aclrecord.AclContentValue.requestDecline:type_name -> aclrecord.AclAccountRequestDecline - 22, // 24: aclrecord.AclContentValue.accountRequestRemove:type_name -> aclrecord.AclAccountRequestRemove - 15, // 25: aclrecord.AclContentValue.permissionChanges:type_name -> aclrecord.AclAccountPermissionChanges - 16, // 26: aclrecord.AclContentValue.accountsAdd:type_name -> aclrecord.AclAccountsAdd - 18, // 27: aclrecord.AclContentValue.requestCancel:type_name -> aclrecord.AclAccountRequestCancel - 10, // 28: aclrecord.AclContentValue.inviteJoin:type_name -> aclrecord.AclAccountInviteJoin - 7, // 29: aclrecord.AclContentValue.inviteChange:type_name -> aclrecord.AclAccountInviteChange - 8, // 30: aclrecord.AclContentValue.ownershipChange:type_name -> aclrecord.AclOwnershipChange - 4, // 31: aclrecord.AclContentValue.spaceOptionsChange:type_name -> aclrecord.AclSpaceOptionsChange - 23, // 32: aclrecord.AclData.aclContent:type_name -> aclrecord.AclContentValue - 33, // [33:33] is the sub-list for method output_type - 33, // [33:33] 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 + 1, // 16: aclrecord.AclChildRegister.orgPermission:type_name -> aclrecord.AclUserPermissions + 6, // 17: aclrecord.AclContentValue.invite:type_name -> aclrecord.AclAccountInvite + 13, // 18: aclrecord.AclContentValue.inviteRevoke:type_name -> aclrecord.AclAccountInviteRevoke + 9, // 19: aclrecord.AclContentValue.requestJoin:type_name -> aclrecord.AclAccountRequestJoin + 11, // 20: aclrecord.AclContentValue.requestAccept:type_name -> aclrecord.AclAccountRequestAccept + 19, // 21: aclrecord.AclContentValue.permissionChange:type_name -> aclrecord.AclAccountPermissionChange + 21, // 22: aclrecord.AclContentValue.accountRemove:type_name -> aclrecord.AclAccountRemove + 20, // 23: aclrecord.AclContentValue.readKeyChange:type_name -> aclrecord.AclReadKeyChange + 12, // 24: aclrecord.AclContentValue.requestDecline:type_name -> aclrecord.AclAccountRequestDecline + 23, // 25: aclrecord.AclContentValue.accountRequestRemove:type_name -> aclrecord.AclAccountRequestRemove + 15, // 26: aclrecord.AclContentValue.permissionChanges:type_name -> aclrecord.AclAccountPermissionChanges + 16, // 27: aclrecord.AclContentValue.accountsAdd:type_name -> aclrecord.AclAccountsAdd + 18, // 28: aclrecord.AclContentValue.requestCancel:type_name -> aclrecord.AclAccountRequestCancel + 10, // 29: aclrecord.AclContentValue.inviteJoin:type_name -> aclrecord.AclAccountInviteJoin + 7, // 30: aclrecord.AclContentValue.inviteChange:type_name -> aclrecord.AclAccountInviteChange + 8, // 31: aclrecord.AclContentValue.ownershipChange:type_name -> aclrecord.AclOwnershipChange + 4, // 32: aclrecord.AclContentValue.spaceOptionsChange:type_name -> aclrecord.AclSpaceOptionsChange + 24, // 33: aclrecord.AclContentValue.childRegister:type_name -> aclrecord.AclChildRegister + 25, // 34: aclrecord.AclContentValue.childRegisterRevoke:type_name -> aclrecord.AclChildRegisterRevoke + 26, // 35: aclrecord.AclContentValue.legalOwnerUpdate:type_name -> aclrecord.AclLegalOwnerUpdate + 22, // 36: aclrecord.AclContentValue.accountRemoveNoRotate:type_name -> aclrecord.AclAccountRemoveNoRotate + 27, // 37: aclrecord.AclData.aclContent:type_name -> aclrecord.AclContentValue + 38, // [38:38] is the sub-list for method output_type + 38, // [38:38] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_aclrecord_proto_init() } @@ -1935,7 +2298,7 @@ func file_aclrecord_proto_init() { if File_aclrecord_proto != nil { return } - file_aclrecord_proto_msgTypes[21].OneofWrappers = []any{ + file_aclrecord_proto_msgTypes[25].OneofWrappers = []any{ (*AclContentValue_Invite)(nil), (*AclContentValue_InviteRevoke)(nil), (*AclContentValue_RequestJoin)(nil), @@ -1952,6 +2315,10 @@ func file_aclrecord_proto_init() { (*AclContentValue_InviteChange)(nil), (*AclContentValue_OwnershipChange)(nil), (*AclContentValue_SpaceOptionsChange)(nil), + (*AclContentValue_ChildRegister)(nil), + (*AclContentValue_ChildRegisterRevoke)(nil), + (*AclContentValue_LegalOwnerUpdate)(nil), + (*AclContentValue_AccountRemoveNoRotate)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1959,7 +2326,7 @@ func file_aclrecord_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_aclrecord_proto_rawDesc), len(file_aclrecord_proto_rawDesc)), NumEnums: 2, - NumMessages: 23, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/commonspace/object/acl/aclrecordproto/aclrecord_vtproto.pb.go b/commonspace/object/acl/aclrecordproto/aclrecord_vtproto.pb.go index 0263d126..40b3ba72 100644 --- a/commonspace/object/acl/aclrecordproto/aclrecord_vtproto.pb.go +++ b/commonspace/object/acl/aclrecordproto/aclrecord_vtproto.pb.go @@ -48,6 +48,27 @@ func (m *AclRoot) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.ParentAclRootId) > 0 { + i -= len(m.ParentAclRootId) + copy(dAtA[i:], m.ParentAclRootId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentAclRootId))) + i-- + dAtA[i] = 0x72 + } + if len(m.LegalOwner) > 0 { + i -= len(m.LegalOwner) + copy(dAtA[i:], m.LegalOwner) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.LegalOwner))) + i-- + dAtA[i] = 0x6a + } + if len(m.ParentSpaceId) > 0 { + i -= len(m.ParentSpaceId) + copy(dAtA[i:], m.ParentSpaceId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentSpaceId))) + i-- + dAtA[i] = 0x62 + } if m.Options != nil { size, err := m.Options.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -162,6 +183,26 @@ func (m *AclSpaceOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.ChildrenCreationDisallowed { + i-- + if m.ChildrenCreationDisallowed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if m.EditorsCanCompleteKeylessRotation { + i-- + if m.EditorsCanCompleteKeylessRotation { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } if m.DeleteRestricted { i-- if m.DeleteRestricted { @@ -399,6 +440,13 @@ func (m *AclOwnershipChange) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.AclRootId) > 0 { + i -= len(m.AclRootId) + copy(dAtA[i:], m.AclRootId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.AclRootId))) + i-- + dAtA[i] = 0x1a + } if m.OldOwnerPermissions != 0 { i = protohelpers.EncodeVarint(dAtA, i, uint64(m.OldOwnerPermissions)) i-- @@ -1098,6 +1146,48 @@ func (m *AclAccountRemove) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AclAccountRemoveNoRotate) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AclAccountRemoveNoRotate) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclAccountRemoveNoRotate) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Identities) > 0 { + for iNdEx := len(m.Identities) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Identities[iNdEx]) + copy(dAtA[i:], m.Identities[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Identities[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *AclAccountRequestRemove) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1131,6 +1221,140 @@ func (m *AclAccountRequestRemove) MarshalToSizedBufferVT(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *AclChildRegister) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AclChildRegister) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclChildRegister) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.OrgPermission != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.OrgPermission)) + i-- + dAtA[i] = 0x18 + } + if len(m.ChildAclRootId) > 0 { + i -= len(m.ChildAclRootId) + copy(dAtA[i:], m.ChildAclRootId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ChildAclRootId))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChildSpaceId) > 0 { + i -= len(m.ChildSpaceId) + copy(dAtA[i:], m.ChildSpaceId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ChildSpaceId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AclChildRegisterRevoke) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AclChildRegisterRevoke) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclChildRegisterRevoke) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.ChildSpaceId) > 0 { + i -= len(m.ChildSpaceId) + copy(dAtA[i:], m.ChildSpaceId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ChildSpaceId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AclLegalOwnerUpdate) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AclLegalOwnerUpdate) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclLegalOwnerUpdate) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.OwnershipChanges) > 0 { + for iNdEx := len(m.OwnershipChanges) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.OwnershipChanges[iNdEx]) + copy(dAtA[i:], m.OwnershipChanges[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.OwnershipChanges[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *AclContentValue) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1479,6 +1703,90 @@ func (m *AclContentValue_SpaceOptionsChange) MarshalToSizedBufferVT(dAtA []byte) } return len(dAtA) - i, nil } +func (m *AclContentValue_ChildRegister) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclContentValue_ChildRegister) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ChildRegister != nil { + size, err := m.ChildRegister.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } + return len(dAtA) - i, nil +} +func (m *AclContentValue_ChildRegisterRevoke) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclContentValue_ChildRegisterRevoke) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ChildRegisterRevoke != nil { + size, err := m.ChildRegisterRevoke.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + return len(dAtA) - i, nil +} +func (m *AclContentValue_LegalOwnerUpdate) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclContentValue_LegalOwnerUpdate) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.LegalOwnerUpdate != nil { + size, err := m.LegalOwnerUpdate.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } + return len(dAtA) - i, nil +} +func (m *AclContentValue_AccountRemoveNoRotate) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *AclContentValue_AccountRemoveNoRotate) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + i := len(dAtA) + if m.AccountRemoveNoRotate != nil { + size, err := m.AccountRemoveNoRotate.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + } + return len(dAtA) - i, nil +} func (m *AclData) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1573,6 +1881,18 @@ func (m *AclRoot) SizeVT() (n int) { l = m.Options.SizeVT() n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.ParentSpaceId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.LegalOwner) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.ParentAclRootId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -1586,6 +1906,12 @@ func (m *AclSpaceOptions) SizeVT() (n int) { if m.DeleteRestricted { n += 2 } + if m.EditorsCanCompleteKeylessRotation { + n += 2 + } + if m.ChildrenCreationDisallowed { + n += 2 + } n += len(m.unknownFields) return n } @@ -1678,6 +2004,10 @@ func (m *AclOwnershipChange) SizeVT() (n int) { if m.OldOwnerPermissions != 0 { n += 1 + protohelpers.SizeOfVarint(uint64(m.OldOwnerPermissions)) } + l = len(m.AclRootId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -1954,14 +2284,81 @@ func (m *AclAccountRemove) SizeVT() (n int) { return n } -func (m *AclAccountRequestRemove) SizeVT() (n int) { +func (m *AclAccountRemoveNoRotate) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l - n += len(m.unknownFields) - return n + if len(m.Identities) > 0 { + for _, b := range m.Identities { + l = len(b) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *AclAccountRequestRemove) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *AclChildRegister) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChildSpaceId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.ChildAclRootId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.OrgPermission != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.OrgPermission)) + } + n += len(m.unknownFields) + return n +} + +func (m *AclChildRegisterRevoke) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChildSpaceId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *AclLegalOwnerUpdate) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.OwnershipChanges) > 0 { + for _, b := range m.OwnershipChanges { + l = len(b) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n } func (m *AclContentValue) SizeVT() (n int) { @@ -2169,6 +2566,54 @@ func (m *AclContentValue_SpaceOptionsChange) SizeVT() (n int) { } return n } +func (m *AclContentValue_ChildRegister) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChildRegister != nil { + l = m.ChildRegister.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + return n +} +func (m *AclContentValue_ChildRegisterRevoke) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChildRegisterRevoke != nil { + l = m.ChildRegisterRevoke.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + return n +} +func (m *AclContentValue_LegalOwnerUpdate) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LegalOwnerUpdate != nil { + l = m.LegalOwnerUpdate.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + return n +} +func (m *AclContentValue_AccountRemoveNoRotate) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.AccountRemoveNoRotate != nil { + l = m.AccountRemoveNoRotate.SizeVT() + n += 2 + l + protohelpers.SizeOfVarint(uint64(l)) + } + return n +} func (m *AclData) SizeVT() (n int) { if m == nil { return 0 @@ -2575,6 +3020,104 @@ func (m *AclRoot) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentSpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ParentSpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LegalOwner", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LegalOwner = append(m.LegalOwner[:0], dAtA[iNdEx:postIndex]...) + if m.LegalOwner == nil { + m.LegalOwner = []byte{} + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentAclRootId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ParentAclRootId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -2646,6 +3189,46 @@ func (m *AclSpaceOptions) UnmarshalVT(dAtA []byte) error { } } m.DeleteRestricted = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EditorsCanCompleteKeylessRotation", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EditorsCanCompleteKeylessRotation = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildrenCreationDisallowed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ChildrenCreationDisallowed = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -3213,6 +3796,38 @@ func (m *AclOwnershipChange) UnmarshalVT(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AclRootId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AclRootId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -4982,7 +5597,7 @@ func (m *AclAccountRemove) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *AclAccountRequestRemove) UnmarshalVT(dAtA []byte) error { +func (m *AclAccountRemoveNoRotate) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5005,14 +5620,397 @@ func (m *AclAccountRequestRemove) UnmarshalVT(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AclAccountRequestRemove: wiretype end group for non-group") + return fmt.Errorf("proto: AclAccountRemoveNoRotate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AclAccountRequestRemove: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AclAccountRemoveNoRotate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - default: - iNdEx = preIndex + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Identities", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Identities = append(m.Identities, make([]byte, postIndex-iNdEx)) + copy(m.Identities[len(m.Identities)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AclAccountRequestRemove) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AclAccountRequestRemove: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclAccountRequestRemove: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AclChildRegister) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AclChildRegister: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclChildRegister: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildSpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChildSpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildAclRootId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChildAclRootId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrgPermission", wireType) + } + m.OrgPermission = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrgPermission |= AclUserPermissions(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AclChildRegisterRevoke) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AclChildRegisterRevoke: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclChildRegisterRevoke: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildSpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChildSpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AclLegalOwnerUpdate) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AclLegalOwnerUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AclLegalOwnerUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OwnershipChanges", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OwnershipChanges = append(m.OwnershipChanges, make([]byte, postIndex-iNdEx)) + copy(m.OwnershipChanges[len(m.OwnershipChanges)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) if err != nil { return err @@ -5718,6 +6716,170 @@ func (m *AclContentValue) UnmarshalVT(dAtA []byte) error { m.Value = &AclContentValue_SpaceOptionsChange{SpaceOptionsChange: v} } iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildRegister", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Value.(*AclContentValue_ChildRegister); ok { + if err := oneof.ChildRegister.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &AclChildRegister{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_ChildRegister{ChildRegister: v} + } + iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChildRegisterRevoke", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Value.(*AclContentValue_ChildRegisterRevoke); ok { + if err := oneof.ChildRegisterRevoke.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &AclChildRegisterRevoke{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_ChildRegisterRevoke{ChildRegisterRevoke: v} + } + iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LegalOwnerUpdate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Value.(*AclContentValue_LegalOwnerUpdate); ok { + if err := oneof.LegalOwnerUpdate.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &AclLegalOwnerUpdate{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_LegalOwnerUpdate{LegalOwnerUpdate: v} + } + iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountRemoveNoRotate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if oneof, ok := m.Value.(*AclContentValue_AccountRemoveNoRotate); ok { + if err := oneof.AccountRemoveNoRotate.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + v := &AclAccountRemoveNoRotate{} + if err := v.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &AclContentValue_AccountRemoveNoRotate{AccountRemoveNoRotate: v} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto index a24c947b..fa3fa01b 100644 --- a/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto +++ b/commonspace/object/acl/aclrecordproto/protos/aclrecord.proto @@ -15,11 +15,26 @@ message AclRoot { bytes encryptedOwnerMetadata = 9; AclOneToOneInfo oneToOneInfo = 10; AclSpaceOptions options = 11; + // parentSpaceId declares this space a child of the parent space (nested spaces); empty for top-level spaces. + // Mirrors SpaceHeader.parentSpaceId so the ACL is self-describing. + string parentSpaceId = 12; + // legalOwner is the public key of the parent space's owner at genesis. It anchors the + // signature-induction chain advanced by AclLegalOwnerUpdate; empty for top-level spaces. + bytes legalOwner = 13; + // parentAclRootId is the parent space's acl root record id — the binding scope for + // AclLegalOwnerUpdate proofs; set together with parentSpaceId/legalOwner. + string parentAclRootId = 14; } // AclSpaceOptions contains space-level toggles/options message AclSpaceOptions { bool deleteRestricted = 1; + // editorsCanCompleteKeylessRotation lets Writers author the standalone read-key rotation + // that completes a pending keyless removal (nested spaces); off = admins/owner only + bool editorsCanCompleteKeylessRotation = 2; + // childrenCreationDisallowed forbids registering child spaces under this space (nested spaces); + // zero value = children allowed, Admin+ may register + bool childrenCreationDisallowed = 3; } // AclSpaceOptionsChange changes space options (owner-only) @@ -58,6 +73,11 @@ enum AclInviteType { message AclOwnershipChange { bytes newOwnerIdentity = 1; AclUserPermissions oldOwnerPermissions = 2; + // aclRootId binds the transfer to the acl it belongs to (the acl root record id). + // Optional for backward compatibility, but REQUIRED for a record to serve as an + // AclLegalOwnerUpdate proof — without it a genuine transfer of any other space + // signed by the same key could be replayed to take over a child's governance. + string aclRootId = 3; } // AclAccountRequestJoin contains the reference to the invite record and the data of the person who wants to join, confirmed by the private invite key @@ -152,10 +172,40 @@ message AclAccountRemove { AclReadKeyChange readKeyChange = 2; } +// AclAccountRemoveNoRotate removes accounts WITHOUT a read-key rotation. Only the legalOwner of a +// child (nested) space may author it — it is the keyless-governance removal: membership drops to +// None immediately, and the space enters a pending-rotation state until a key-holding member +// authors a standard AclReadKeyChange. Never use for ordinary removals — use AclAccountRemove. +message AclAccountRemoveNoRotate { + repeated bytes identities = 1; +} + // AclAccountRequestRemove adds a request to remove an account message AclAccountRequestRemove { } +// AclChildRegister registers a child space under THIS (parent) space +message AclChildRegister { + string childSpaceId = 1; + // childAclRootId binds the registration to a specific child ACL root record + string childAclRootId = 2; + // orgPermission is the permission the parent grants ITSELF in the child (None = keyless governance only) + AclUserPermissions orgPermission = 3; +} + +// AclChildRegisterRevoke de-lists a previously registered child space +message AclChildRegisterRevoke { + string childSpaceId = 1; +} + +// AclLegalOwnerUpdate advances the stored legalOwner of THIS (child) space after parent ownership transfers. +// Each entry is a raw consensus record (consensusproto.RawRecord bytes) from the PARENT acl containing exactly +// one AclOwnershipChange. Validation is signature induction: the first record must be signed by the currently +// stored legalOwner, each next by the owner the previous one named; the author of this record must be the final owner. +message AclLegalOwnerUpdate { + repeated bytes ownershipChanges = 1; +} + // AclContentValue contains possible values for Acl message AclContentValue { oneof value { @@ -176,6 +226,10 @@ message AclContentValue { AclAccountInviteChange inviteChange = 14; AclOwnershipChange ownershipChange = 15; AclSpaceOptionsChange spaceOptionsChange = 16; + AclChildRegister childRegister = 17; + AclChildRegisterRevoke childRegisterRevoke = 18; + AclLegalOwnerUpdate legalOwnerUpdate = 19; + AclAccountRemoveNoRotate accountRemoveNoRotate = 20; } } diff --git a/commonspace/object/acl/list/aclkeylessremove_test.go b/commonspace/object/acl/list/aclkeylessremove_test.go new file mode 100644 index 00000000..09609dfc --- /dev/null +++ b/commonspace/object/acl/list/aclkeylessremove_test.go @@ -0,0 +1,228 @@ +package list + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list/listtest" + "github.com/anyproto/any-sync/commonspace/object/acl/recordverifier" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/util/crypto" +) + +// childAclFixture is a child space acl shared by its owner and one writer, with the +// parent owner (legalOwner) holding no permissions in it +type childAclFixture struct { + legalOwnerKeys *accountdata.AccountKeys + ownerKeys *accountdata.AccountKeys + writerKeys *accountdata.AccountKeys + ownerAcl AclList + writerAcl AclList +} + +func addToAll(t *testing.T, rec *consensusproto.RawRecordWithId, acls ...AclList) { + for _, acl := range acls { + require.NoError(t, acl.AddRawRecord(rec)) + } +} + +func newChildAclFixture(t *testing.T, options *aclrecordproto.AclSpaceOptions) *childAclFixture { + legalOwnerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + ownerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + writerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + + masterKey, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + root, err := newTestAclRecordBuilder(ownerKeys).BuildRoot(RootContent{ + PrivKey: ownerKeys.SignKey, + MasterKey: masterKey, + Change: newTestReadKeyChangePayload(), + Metadata: []byte("m"), + Options: options, + ParentSpaceId: "parent.id", + LegalOwner: legalOwnerKeys.SignKey.GetPublic(), + ParentAclRootId: testParentAclRootId, + }) + require.NoError(t, err) + + storage, err := NewInMemoryStorage(root.Id, []*consensusproto.RawRecordWithId{root}) + require.NoError(t, err) + ownerAcl, err := BuildAclListWithIdentity(ownerKeys, storage, recordverifier.NewValidateFull()) + require.NoError(t, err) + writerAcl, err := BuildAclListWithIdentity(writerKeys, storage, recordverifier.NewValidateFull()) + require.NoError(t, err) + + fx := &childAclFixture{ + legalOwnerKeys: legalOwnerKeys, + ownerKeys: ownerKeys, + writerKeys: writerKeys, + ownerAcl: ownerAcl, + writerAcl: writerAcl, + } + + // the owner adds the writer directly (docs/15 direct-add path) + add, err := ownerAcl.RecordBuilder().BuildAccountsAdd(AccountsAddPayload{ + Additions: []AccountAdd{{ + Identity: writerKeys.SignKey.GetPublic(), + Permissions: AclPermissionsWriter, + Metadata: []byte("wm"), + }}, + }) + require.NoError(t, err) + addToAll(t, listtest.WrapAclRecord(add), ownerAcl, writerAcl) + return fx +} + +func (fx *childAclFixture) removeNoRotateRecord(t *testing.T, signer *accountdata.AccountKeys, targets ...crypto.PubKey) *consensusproto.RawRecordWithId { + var identities [][]byte + for _, target := range targets { + protoIdentity, err := target.Marshall() + require.NoError(t, err) + identities = append(identities, protoIdentity) + } + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_AccountRemoveNoRotate{ + AccountRemoveNoRotate: &aclrecordproto.AclAccountRemoveNoRotate{Identities: identities}, + }, + } + return buildAclRecordSignedBy(t, fx.ownerAcl.Head().Id, signer, content) +} + +func TestKeylessRemove_LegalOwnerRemovesWriter(t *testing.T) { + fx := newChildAclFixture(t, nil) + readKeyIdBefore := fx.ownerAcl.AclState().CurrentReadKeyId() + + rec := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, fx.writerKeys.SignKey.GetPublic()) + addToAll(t, rec, fx.ownerAcl, fx.writerAcl) + + st := fx.ownerAcl.AclState() + require.True(t, st.Permissions(fx.writerKeys.SignKey.GetPublic()).NoPermissions()) + require.True(t, st.HasPendingKeylessRemovals()) + require.Len(t, st.PendingKeylessRemovals(), 1) + require.True(t, st.PendingKeylessRemovals()[0].Equals(fx.writerKeys.SignKey.GetPublic())) + // no rotation happened + require.Equal(t, readKeyIdBefore, st.CurrentReadKeyId()) + + // a key-holding admin (the owner) completes the cut-off with a standard rotation + rotation, err := fx.ownerAcl.RecordBuilder().BuildReadKeyChange(newTestReadKeyChangePayload()) + require.NoError(t, err) + require.NoError(t, fx.ownerAcl.AddRawRecord(listtest.WrapAclRecord(rotation))) + + st = fx.ownerAcl.AclState() + require.False(t, st.HasPendingKeylessRemovals()) + require.NotEqual(t, readKeyIdBefore, st.CurrentReadKeyId()) +} + +func TestKeylessRemove_Rejections(t *testing.T) { + t.Run("only the legal owner may author", func(t *testing.T) { + fx := newChildAclFixture(t, nil) + stranger, err := accountdata.NewRandom() + require.NoError(t, err) + rec := fx.removeNoRotateRecord(t, stranger, fx.writerKeys.SignKey.GetPublic()) + require.ErrorIs(t, fx.ownerAcl.AddRawRecord(rec), ErrInsufficientPermissions) + + // even the child owner cannot use the keyless record — it must rotate via AclAccountRemove + rec = fx.removeNoRotateRecord(t, fx.ownerKeys, fx.writerKeys.SignKey.GetPublic()) + require.ErrorIs(t, fx.ownerAcl.AddRawRecord(rec), ErrInsufficientPermissions) + }) + + t.Run("cannot remove the child owner", func(t *testing.T) { + fx := newChildAclFixture(t, nil) + rec := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, fx.ownerKeys.SignKey.GetPublic()) + require.ErrorIs(t, fx.ownerAcl.AddRawRecord(rec), ErrInsufficientPermissions) + }) + + t.Run("unknown identity", func(t *testing.T) { + fx := newChildAclFixture(t, nil) + stranger, err := accountdata.NewRandom() + require.NoError(t, err) + rec := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, stranger.SignKey.GetPublic()) + require.ErrorIs(t, fx.ownerAcl.AddRawRecord(rec), ErrNoSuchAccount) + }) + + t.Run("empty identities", func(t *testing.T) { + fx := newChildAclFixture(t, nil) + rec := fx.removeNoRotateRecord(t, fx.legalOwnerKeys) + require.ErrorIs(t, fx.ownerAcl.AddRawRecord(rec), ErrIncorrectNumberOfAccounts) + }) + + t.Run("not a child space", func(t *testing.T) { + a := NewAclExecutor("spaceId") + require.NoError(t, a.Execute("a.init::a")) + ownerAcl := a.ActualAccounts()["a"].Acl + legalOwnerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + target, err := accountdata.NewRandom() + require.NoError(t, err) + protoIdentity, err := target.SignKey.GetPublic().Marshall() + require.NoError(t, err) + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_AccountRemoveNoRotate{ + AccountRemoveNoRotate: &aclrecordproto.AclAccountRemoveNoRotate{Identities: [][]byte{protoIdentity}}, + }, + } + rec := buildAclRecordSignedBy(t, ownerAcl.Head().Id, legalOwnerKeys, content) + require.ErrorIs(t, ownerAcl.AddRawRecord(rec), ErrNotChildSpace) + }) +} + +func TestKeylessRemove_EditorRotation(t *testing.T) { + t.Run("writer cannot rotate without the opt-in", func(t *testing.T) { + fx := newChildAclFixture(t, nil) + rec := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, fx.writerKeys.SignKey.GetPublic()) + // remove a second member so the writer remains; here remove nobody relevant: add one more writer to remove + _ = rec + // add a reader, remove it keylessly, then the writer attempts the rotation + readerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + add, err := fx.ownerAcl.RecordBuilder().BuildAccountsAdd(AccountsAddPayload{ + Additions: []AccountAdd{{ + Identity: readerKeys.SignKey.GetPublic(), + Permissions: AclPermissionsReader, + Metadata: []byte("rm"), + }}, + }) + require.NoError(t, err) + addToAll(t, listtest.WrapAclRecord(add), fx.ownerAcl, fx.writerAcl) + + remove := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, readerKeys.SignKey.GetPublic()) + addToAll(t, remove, fx.ownerAcl, fx.writerAcl) + require.True(t, fx.writerAcl.AclState().HasPendingKeylessRemovals()) + + _, err = fx.writerAcl.RecordBuilder().BuildReadKeyChange(newTestReadKeyChangePayload()) + require.ErrorIs(t, err, ErrInsufficientPermissions) + }) + + t.Run("writer rotates with the opt-in and a pending removal", func(t *testing.T) { + fx := newChildAclFixture(t, &aclrecordproto.AclSpaceOptions{EditorsCanCompleteKeylessRotation: true}) + readerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + add, err := fx.ownerAcl.RecordBuilder().BuildAccountsAdd(AccountsAddPayload{ + Additions: []AccountAdd{{ + Identity: readerKeys.SignKey.GetPublic(), + Permissions: AclPermissionsReader, + Metadata: []byte("rm"), + }}, + }) + require.NoError(t, err) + addToAll(t, listtest.WrapAclRecord(add), fx.ownerAcl, fx.writerAcl) + + // without a pending removal the writer still cannot rotate + _, err = fx.writerAcl.RecordBuilder().BuildReadKeyChange(newTestReadKeyChangePayload()) + require.ErrorIs(t, err, ErrInsufficientPermissions) + + remove := fx.removeNoRotateRecord(t, fx.legalOwnerKeys, readerKeys.SignKey.GetPublic()) + addToAll(t, remove, fx.ownerAcl, fx.writerAcl) + + rotation, err := fx.writerAcl.RecordBuilder().BuildReadKeyChange(newTestReadKeyChangePayload()) + require.NoError(t, err) + addToAll(t, listtest.WrapAclRecord(rotation), fx.ownerAcl, fx.writerAcl) + require.False(t, fx.ownerAcl.AclState().HasPendingKeylessRemovals()) + }) +} diff --git a/commonspace/object/acl/list/aclnestedspaces_test.go b/commonspace/object/acl/list/aclnestedspaces_test.go new file mode 100644 index 00000000..eb69c590 --- /dev/null +++ b/commonspace/object/acl/list/aclnestedspaces_test.go @@ -0,0 +1,447 @@ +package list + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list/listtest" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/util/crypto" +) + +// testParentAclRootId is the binding scope shared by newChildAcl roots and makeOwnershipProof proofs +const testParentAclRootId = "parent-acl-root-id" + +// newChildAcl builds a child-space acl whose root pins the given legal owner +func newChildAcl(t *testing.T, parentSpaceId string, legalOwner crypto.PubKey) (*accountdata.AccountKeys, AclList) { + keys, err := accountdata.NewRandom() + require.NoError(t, err) + masterKey, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + root, err := newTestAclRecordBuilder(keys).BuildRoot(RootContent{ + PrivKey: keys.SignKey, + MasterKey: masterKey, + Change: newTestReadKeyChangePayload(), + Metadata: []byte("m"), + ParentSpaceId: parentSpaceId, + LegalOwner: legalOwner, + ParentAclRootId: testParentAclRootId, + }) + require.NoError(t, err) + acl, err := newInMemoryAclWithRoot(keys, root) + require.NoError(t, err) + return keys, acl +} + +// buildAclRecordSignedBy assembles a raw acl record with one content value, signed by the given keys. +// Unlike the record builder it allows an author who holds no permissions in the list. +func buildAclRecordSignedBy(t *testing.T, prevId string, keys *accountdata.AccountKeys, content *aclrecordproto.AclContentValue) *consensusproto.RawRecordWithId { + data := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{content}} + marshalledData, err := data.MarshalVT() + require.NoError(t, err) + protoKey, err := keys.SignKey.GetPublic().Marshall() + require.NoError(t, err) + rec := &consensusproto.Record{ + PrevId: prevId, + Identity: protoKey, + Data: marshalledData, + Timestamp: time.Now().Unix(), + } + marshalledRec, err := rec.MarshalVT() + require.NoError(t, err) + sig, err := keys.SignKey.Sign(marshalledRec) + require.NoError(t, err) + return listtest.WrapAclRecord(&consensusproto.RawRecord{Payload: marshalledRec, Signature: sig}) +} + +// makeOwnershipProof produces raw parent-acl record bytes carrying one AclOwnershipChange signed by +// signer, bound to the parent acl root testParentAclRootId +func makeOwnershipProof(t *testing.T, signer *accountdata.AccountKeys, newOwner crypto.PubKey) []byte { + return makeOwnershipProofFor(t, signer, newOwner, testParentAclRootId) +} + +// makeOwnershipProofFor is makeOwnershipProof with an explicit binding scope (for cross-space tests) +func makeOwnershipProofFor(t *testing.T, signer *accountdata.AccountKeys, newOwner crypto.PubKey, aclRootId string) []byte { + newOwnerProto, err := newOwner.Marshall() + require.NoError(t, err) + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_OwnershipChange{ + OwnershipChange: &aclrecordproto.AclOwnershipChange{ + NewOwnerIdentity: newOwnerProto, + OldOwnerPermissions: aclrecordproto.AclUserPermissions_Admin, + AclRootId: aclRootId, + }, + }, + } + rawWithId := buildAclRecordSignedBy(t, "parent-prev", signer, content) + return rawWithId.Payload +} + +func legalOwnerUpdateContent(proofs ...[]byte) *aclrecordproto.AclContentValue { + return &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_LegalOwnerUpdate{ + LegalOwnerUpdate: &aclrecordproto.AclLegalOwnerUpdate{OwnershipChanges: proofs}, + }, + } +} + +func TestNestedSpaces_ChildRoot(t *testing.T) { + parentOwner, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + _, acl := newChildAcl(t, "parent.id", parentOwner.GetPublic()) + st := acl.AclState() + require.True(t, st.IsChildSpace()) + require.Equal(t, "parent.id", st.ParentSpaceId()) + require.True(t, st.LegalOwner().Equals(parentOwner.GetPublic())) +} + +func TestNestedSpaces_ChildRootBothOrNeither(t *testing.T) { + keys, err := accountdata.NewRandom() + require.NoError(t, err) + masterKey, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + _, err = newTestAclRecordBuilder(keys).BuildRoot(RootContent{ + PrivKey: keys.SignKey, + MasterKey: masterKey, + Change: newTestReadKeyChangePayload(), + Metadata: []byte("m"), + ParentSpaceId: "parent.id", + }) + require.ErrorIs(t, err, ErrIncorrectRoot) +} + +func TestNestedSpaces_ChildRegister(t *testing.T) { + a := NewAclExecutor("spaceId") + for _, cmd := range []string{ + "a.init::a", + "a.invite::inv", + "b.join::inv", + "a.approve::b,rw", + } { + require.NoError(t, a.Execute(cmd)) + } + ownerAcl := a.ActualAccounts()["a"].Acl + + reg, err := ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot1", + OrgPermission: AclPermissionsNone, + }) + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(reg))) + + st := ownerAcl.AclState() + registration, ok := st.ChildRegistration("child.1") + require.True(t, ok) + require.Equal(t, "childroot1", registration.ChildAclRootId) + require.False(t, registration.Revoked) + require.Len(t, st.ChildRegistrations(), 1) + + // duplicate registration is rejected at build (preflight validation) + _, err = ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot2", + }) + require.ErrorIs(t, err, ErrChildAlreadyRegistered) + + // orgPermission is reserved: any non-None value is rejected until the org + // access grant is actually implemented + for _, perm := range []AclPermissions{AclPermissionsOwner, AclPermissionsReader} { + _, err = ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.2", + ChildAclRootId: "childroot2", + OrgPermission: perm, + }) + require.ErrorIs(t, err, ErrOrgPermissionUnsupported) + } + + // revoke, then re-register + revoke, err := ownerAcl.RecordBuilder().BuildChildRegisterRevoke("child.1") + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(revoke))) + registration, ok = ownerAcl.AclState().ChildRegistration("child.1") + require.True(t, ok) + require.True(t, registration.Revoked) + + _, err = ownerAcl.RecordBuilder().BuildChildRegisterRevoke("child.1") + require.ErrorIs(t, err, ErrNoSuchChildRegistration) + + reg2, err := ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot3", + }) + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(reg2))) + registration, _ = ownerAcl.AclState().ChildRegistration("child.1") + require.Equal(t, "childroot3", registration.ChildAclRootId) + require.False(t, registration.Revoked) +} + +func TestNestedSpaces_ChildRegisterRequiresAdmin(t *testing.T) { + a := NewAclExecutor("spaceId") + for _, cmd := range []string{ + "a.init::a", + "a.invite::inv", + "b.join::inv", + "a.approve::b,rw", + } { + require.NoError(t, a.Execute(cmd)) + } + var ( + ownerAcl = a.ActualAccounts()["a"].Acl + writerKeys = a.ActualAccounts()["b"].Keys + ) + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_ChildRegister{ + ChildRegister: &aclrecordproto.AclChildRegister{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot1", + }, + }, + } + rec := buildAclRecordSignedBy(t, ownerAcl.Head().Id, writerKeys, content) + require.ErrorIs(t, ownerAcl.AddRawRecord(rec), ErrInsufficientPermissions) +} + +func TestNestedSpaces_LegalOwnerUpdate(t *testing.T) { + aliceKeys, err := accountdata.NewRandom() + require.NoError(t, err) + bobKeys, err := accountdata.NewRandom() + require.NoError(t, err) + + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + + proof := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(proof)) + require.NoError(t, childAcl.AddRawRecord(update)) + require.True(t, childAcl.AclState().LegalOwner().Equals(bobKeys.SignKey.GetPublic())) +} + +func TestNestedSpaces_LegalOwnerUpdateMultiHop(t *testing.T) { + aliceKeys, err := accountdata.NewRandom() + require.NoError(t, err) + bobKeys, err := accountdata.NewRandom() + require.NoError(t, err) + carolKeys, err := accountdata.NewRandom() + require.NoError(t, err) + + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + + proofs := [][]byte{ + makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()), + makeOwnershipProof(t, bobKeys, carolKeys.SignKey.GetPublic()), + } + update := buildAclRecordSignedBy(t, childAcl.Head().Id, carolKeys, legalOwnerUpdateContent(proofs...)) + require.NoError(t, childAcl.AddRawRecord(update)) + require.True(t, childAcl.AclState().LegalOwner().Equals(carolKeys.SignKey.GetPublic())) +} + +func TestNestedSpaces_LegalOwnerUpdateRejections(t *testing.T) { + aliceKeys, err := accountdata.NewRandom() + require.NoError(t, err) + bobKeys, err := accountdata.NewRandom() + require.NoError(t, err) + strangerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + + t.Run("author must be the final owner", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + proof := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, strangerKeys, legalOwnerUpdateContent(proof)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInsufficientPermissions) + }) + + t.Run("chain must start at the stored owner", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + proof := makeOwnershipProof(t, strangerKeys, bobKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(proof)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidLegalOwnerProof) + }) + + t.Run("cross-space proof rejected — ownership change from a DIFFERENT acl", func(t *testing.T) { + // Alice (the stored legalOwner, owner of parent P) also owns some other + // space Q and legitimately transfers Q to Mallory. Mallory lifts that + // signed record and tries to advance THIS child's legalOwner with it. + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + mallory := bobKeys // stand-in attacker + foreignProof := makeOwnershipProofFor(t, aliceKeys, mallory.SignKey.GetPublic(), "some-other-space-acl-root") + update := buildAclRecordSignedBy(t, childAcl.Head().Id, mallory, legalOwnerUpdateContent(foreignProof)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidLegalOwnerProof) + require.True(t, childAcl.AclState().LegalOwner().Equals(aliceKeys.SignKey.GetPublic()), "legalOwner unchanged") + }) + + t.Run("proof with no aclRootId binding rejected", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + unbound := makeOwnershipProofFor(t, aliceKeys, bobKeys.SignKey.GetPublic(), "") + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(unbound)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidLegalOwnerProof) + }) + + t.Run("empty proof list", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, aliceKeys, legalOwnerUpdateContent()) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidLegalOwnerProof) + }) + + t.Run("not a child space", func(t *testing.T) { + a := NewAclExecutor("spaceId") + require.NoError(t, a.Execute("a.init::a")) + ownerAcl := a.ActualAccounts()["a"].Acl + proof := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, ownerAcl.Head().Id, bobKeys, legalOwnerUpdateContent(proof)) + require.ErrorIs(t, ownerAcl.AddRawRecord(update), ErrNotChildSpace) + }) + + t.Run("consumed proof cannot be replayed after an ownership cycle", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + aliceToBob := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + bobToAlice := makeOwnershipProof(t, bobKeys, aliceKeys.SignKey.GetPublic()) + + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(aliceToBob)) + require.NoError(t, childAcl.AddRawRecord(update)) + update = buildAclRecordSignedBy(t, childAcl.Head().Id, aliceKeys, legalOwnerUpdateContent(bobToAlice)) + require.NoError(t, childAcl.AddRawRecord(update)) + require.True(t, childAcl.AclState().LegalOwner().Equals(aliceKeys.SignKey.GetPublic())) + + // bob replays the consumed alice->bob record to reclaim the child + replay := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(aliceToBob)) + require.ErrorIs(t, childAcl.AddRawRecord(replay), ErrInvalidLegalOwnerProof) + }) + + t.Run("consumed proof with mutated unsigned envelope field cannot be replayed", func(t *testing.T) { + // acceptor fields live outside the author-signed payload: re-serializing a consumed + // proof with a different acceptor field keeps the signature valid but changes the raw + // bytes, so a guard keyed on the envelope cid would treat it as a fresh proof + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + aliceToBob := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + bobToAlice := makeOwnershipProof(t, bobKeys, aliceKeys.SignKey.GetPublic()) + + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(aliceToBob)) + require.NoError(t, childAcl.AddRawRecord(update)) + update = buildAclRecordSignedBy(t, childAcl.Head().Id, aliceKeys, legalOwnerUpdateContent(bobToAlice)) + require.NoError(t, childAcl.AddRawRecord(update)) + + var raw consensusproto.RawRecord + require.NoError(t, raw.UnmarshalVT(aliceToBob)) + raw.AcceptorTimestamp++ + raw.AcceptorIdentity = []byte("mutated") + mutated, err := raw.MarshalVT() + require.NoError(t, err) + require.NotEqual(t, aliceToBob, mutated) + + replay := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(mutated)) + require.ErrorIs(t, childAcl.AddRawRecord(replay), ErrInvalidLegalOwnerProof) + require.True(t, childAcl.AclState().LegalOwner().Equals(aliceKeys.SignKey.GetPublic()), "legalOwner unchanged") + }) + + t.Run("duplicate proof within one update", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + proof := makeOwnershipProof(t, aliceKeys, aliceKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, aliceKeys, legalOwnerUpdateContent(proof, proof)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidLegalOwnerProof) + }) + + t.Run("proof with tampered signature", func(t *testing.T) { + _, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + proof := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + var raw consensusproto.RawRecord + require.NoError(t, raw.UnmarshalVT(proof)) + raw.Signature[0] ^= 0xff + tampered, err := raw.MarshalVT() + require.NoError(t, err) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(tampered)) + require.ErrorIs(t, childAcl.AddRawRecord(update), ErrInvalidSignature) + }) +} + +func TestOwnershipChange_AclRootIdBinding(t *testing.T) { + a := NewAclExecutor("spaceId") + for _, cmd := range []string{ + "a.init::a", + "a.invite::inv", + "b.join::inv", + "a.approve::b,adm", + } { + require.NoError(t, a.Execute(cmd)) + } + ownerAcl := a.ActualAccounts()["a"].Acl + ownerKeys := a.ActualAccounts()["a"].Keys + newOwnerProto, err := a.ActualAccounts()["b"].Keys.SignKey.GetPublic().Marshall() + require.NoError(t, err) + forge := func(aclRootId string) *consensusproto.RawRecordWithId { + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_OwnershipChange{ + OwnershipChange: &aclrecordproto.AclOwnershipChange{ + NewOwnerIdentity: newOwnerProto, + OldOwnerPermissions: aclrecordproto.AclUserPermissions_Admin, + AclRootId: aclRootId, + }, + }, + } + return buildAclRecordSignedBy(t, ownerAcl.Head().Id, ownerKeys, content) + } + require.ErrorIs(t, ownerAcl.AddRawRecord(forge("some-other-acl-root")), ErrIncorrectAclRootId) + // empty binding stays accepted (records predating the field), own root id is the built path + require.NoError(t, ownerAcl.AddRawRecord(forge(ownerAcl.Id()))) +} + +func TestNestedSpaces_StateCopyKeepsNestedFields(t *testing.T) { + aliceKeys, err := accountdata.NewRandom() + require.NoError(t, err) + bobKeys, err := accountdata.NewRandom() + require.NoError(t, err) + childKeys, childAcl := newChildAcl(t, "parent.id", aliceKeys.SignKey.GetPublic()) + _ = childKeys + + proof := makeOwnershipProof(t, aliceKeys, bobKeys.SignKey.GetPublic()) + update := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(proof)) + require.NoError(t, childAcl.AddRawRecord(update)) + + cp := childAcl.AclState().Copy() + require.Equal(t, "parent.id", cp.ParentSpaceId()) + require.True(t, cp.LegalOwner().Equals(bobKeys.SignKey.GetPublic())) + // the replay guard survives the copy + replay := buildAclRecordSignedBy(t, childAcl.Head().Id, bobKeys, legalOwnerUpdateContent(proof)) + rec, err := childAcl.RecordBuilder().UnmarshallWithId(replay) + require.NoError(t, err) + require.ErrorIs(t, cp.ApplyRecord(rec), ErrInvalidLegalOwnerProof) +} + +func TestNestedSpaces_ChildRegisterDisallowedByOptions(t *testing.T) { + a := NewAclExecutor("spaceId") + for _, cmd := range []string{ + "a.init::a", + "a.space_options::restrict_delete", // any options change keeps children allowed (zero value) + } { + require.NoError(t, a.Execute(cmd)) + } + ownerAcl := a.ActualAccounts()["a"].Acl + + // forbid children via options + optsChange, err := ownerAcl.RecordBuilder().BuildSpaceOptionsChange(&aclrecordproto.AclSpaceOptions{ + ChildrenCreationDisallowed: true, + }) + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(optsChange))) + + _, err = ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot1", + }) + require.ErrorIs(t, err, ErrChildrenCreationDisallowed) + + // re-allow and register + optsChange, err = ownerAcl.RecordBuilder().BuildSpaceOptionsChange(&aclrecordproto.AclSpaceOptions{}) + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(optsChange))) + reg, err := ownerAcl.RecordBuilder().BuildChildRegister(ChildRegisterPayload{ + ChildSpaceId: "child.1", + ChildAclRootId: "childroot1", + }) + require.NoError(t, err) + require.NoError(t, ownerAcl.AddRawRecord(listtest.WrapAclRecord(reg))) +} diff --git a/commonspace/object/acl/list/aclrecordbuilder.go b/commonspace/object/acl/list/aclrecordbuilder.go index b1fe51c9..ad688c27 100644 --- a/commonspace/object/acl/list/aclrecordbuilder.go +++ b/commonspace/object/acl/list/aclrecordbuilder.go @@ -20,6 +20,12 @@ type RootContent struct { Change ReadKeyChangePayload Metadata []byte Options *aclrecordproto.AclSpaceOptions + // ParentSpaceId + LegalOwner declare this space a child of another space (nested spaces); + // both must be set together, LegalOwner being the parent's owner key at creation time + ParentSpaceId string + LegalOwner crypto.PubKey + // ParentAclRootId is the parent space's acl root id — the binding scope for legalOwner proofs + ParentAclRootId string } type RequestJoinPayload struct { @@ -76,6 +82,21 @@ type OwnershipChangePayload struct { OldOwnerPermissions AclPermissions } +type ChildRegisterPayload struct { + ChildSpaceId string + ChildAclRootId string + // OrgPermission is reserved for the permission the parent grants ITSELF in the child. + // Only None (keyless governance) is accepted: nothing yet adds the org to the child + // acl or encrypts the read key to it, so any other value would be a false access claim. + OrgPermission AclPermissions +} + +// LegalOwnerUpdatePayload carries raw parent acl records (consensusproto.RawRecord bytes), each with +// exactly one AclOwnershipChange, ordered from the currently stored legal owner to the new one +type LegalOwnerUpdatePayload struct { + OwnershipChanges [][]byte +} + type BatchRequestPayload struct { Additions []AccountAdd Changes []PermissionChangePayload @@ -92,6 +113,11 @@ type AccountRemovePayload struct { Change ReadKeyChangePayload } +// AccountRemoveNoRotatePayload is the keyless-governance removal authored by a child space's legalOwner +type AccountRemoveNoRotatePayload struct { + Identities []crypto.PubKey +} + type InviteResult struct { InviteRec *consensusproto.RawRecord InviteKey crypto.PrivKey @@ -126,6 +152,10 @@ type AclRecordBuilder interface { BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) BuildAccountsAdd(payload AccountsAddPayload) (rawRecord *consensusproto.RawRecord, err error) BuildSpaceOptionsChange(options *aclrecordproto.AclSpaceOptions) (rawRecord *consensusproto.RawRecord, err error) + BuildChildRegister(payload ChildRegisterPayload) (rawRecord *consensusproto.RawRecord, err error) + BuildChildRegisterRevoke(childSpaceId string) (rawRecord *consensusproto.RawRecord, err error) + BuildLegalOwnerUpdate(payload LegalOwnerUpdatePayload) (rawRecord *consensusproto.RawRecord, err error) + BuildAccountRemoveNoRotate(payload AccountRemoveNoRotatePayload) (rawRecord *consensusproto.RawRecord, err error) } type aclRecordBuilder struct { @@ -178,7 +208,9 @@ func (a *aclRecordBuilder) BuildOwnershipChange(ownershipChange OwnershipChangeP Value: &aclrecordproto.AclContentValue_OwnershipChange{ &aclrecordproto.AclOwnershipChange{ NewOwnerIdentity: newOwnerBytes, - OldOwnerPermissions: aclrecordproto.AclUserPermissions(ownershipChange.OldOwnerPermissions)}, + OldOwnerPermissions: aclrecordproto.AclUserPermissions(ownershipChange.OldOwnerPermissions), + // bind the transfer to this acl so it can serve as a legalOwner proof in a child space + AclRootId: a.id}, }, } return a.buildRecord(content) @@ -772,8 +804,15 @@ func (a *aclRecordBuilder) BuildPermissionChange(payload PermissionChangePayload func (a *aclRecordBuilder) BuildReadKeyChange(payload ReadKeyChangePayload) (rawRecord *consensusproto.RawRecord, err error) { if !a.state.Permissions(a.state.pubKey).CanManageAccounts() { - err = ErrInsufficientPermissions - return + // mirrors ValidateReadKeyChange: a Writer may build the rotation that completes a + // pending keyless removal when the space opted in via AclSpaceOptions + opts := a.state.CurrentOptions() + editorAllowed := opts != nil && opts.EditorsCanCompleteKeylessRotation && + a.state.Permissions(a.state.pubKey).CanWrite() && a.state.HasPendingKeylessRemovals() + if !editorAllowed { + err = ErrInsufficientPermissions + return + } } rkChange, err := a.buildReadKeyChange(payload, nil) if err != nil { @@ -1113,6 +1152,18 @@ func (a *aclRecordBuilder) BuildRoot(content RootContent) (rec *consensusproto.R if content.Options != nil { aclRoot.Options = content.Options } + if content.ParentSpaceId != "" || content.LegalOwner != nil { + if content.ParentSpaceId == "" || content.LegalOwner == nil { + return nil, ErrIncorrectRoot + } + legalOwner, err := content.LegalOwner.Marshall() + if err != nil { + return nil, err + } + aclRoot.ParentSpaceId = content.ParentSpaceId + aclRoot.LegalOwner = legalOwner + aclRoot.ParentAclRootId = content.ParentAclRootId + } return marshalAclRoot(aclRoot, content.PrivKey) } @@ -1191,3 +1242,57 @@ func marshalAclRoot(aclRoot *aclrecordproto.AclRoot, key crypto.PrivKey) (rawWit } return } + +func (a *aclRecordBuilder) BuildChildRegister(payload ChildRegisterPayload) (rawRecord *consensusproto.RawRecord, err error) { + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_ChildRegister{ + ChildRegister: &aclrecordproto.AclChildRegister{ + ChildSpaceId: payload.ChildSpaceId, + ChildAclRootId: payload.ChildAclRootId, + OrgPermission: aclrecordproto.AclUserPermissions(payload.OrgPermission), + }, + }, + } + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildChildRegisterRevoke(childSpaceId string) (rawRecord *consensusproto.RawRecord, err error) { + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_ChildRegisterRevoke{ + ChildRegisterRevoke: &aclrecordproto.AclChildRegisterRevoke{ + ChildSpaceId: childSpaceId, + }, + }, + } + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildLegalOwnerUpdate(payload LegalOwnerUpdatePayload) (rawRecord *consensusproto.RawRecord, err error) { + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_LegalOwnerUpdate{ + LegalOwnerUpdate: &aclrecordproto.AclLegalOwnerUpdate{ + OwnershipChanges: payload.OwnershipChanges, + }, + }, + } + return a.buildRecord(content) +} + +func (a *aclRecordBuilder) BuildAccountRemoveNoRotate(payload AccountRemoveNoRotatePayload) (rawRecord *consensusproto.RawRecord, err error) { + var identities [][]byte + for _, identity := range payload.Identities { + protoIdentity, err := identity.Marshall() + if err != nil { + return nil, err + } + identities = append(identities, protoIdentity) + } + content := &aclrecordproto.AclContentValue{ + Value: &aclrecordproto.AclContentValue_AccountRemoveNoRotate{ + AccountRemoveNoRotate: &aclrecordproto.AclAccountRemoveNoRotate{ + Identities: identities, + }, + }, + } + return a.buildRecord(content) +} diff --git a/commonspace/object/acl/list/aclstate.go b/commonspace/object/acl/list/aclstate.go index daf22562..2748d1db 100644 --- a/commonspace/object/acl/list/aclstate.go +++ b/commonspace/object/acl/list/aclstate.go @@ -2,6 +2,7 @@ package list import ( "errors" + "strings" "go.uber.org/zap" "golang.org/x/exp/slices" @@ -39,6 +40,13 @@ var ( ErrOwnerNotFound = errors.New("owner not found") ErrAddRecordOneToOne = errors.New("adding a record to one-to-one space is forbidden") ErrEmptyAclRecordData = errors.New("acl record has neither model nor data") + ErrChildAlreadyRegistered = errors.New("child space is already registered") + ErrNoSuchChildRegistration = errors.New("no such child registration") + ErrNotChildSpace = errors.New("space is not a child space") + ErrInvalidLegalOwnerProof = errors.New("invalid legal owner ownership proof") + ErrIncorrectAclRootId = errors.New("ownership change is bound to a different acl root") + ErrOrgPermissionUnsupported = errors.New("child registration org permission is reserved and must be None") + ErrChildrenCreationDisallowed = errors.New("children creation is disallowed in this space") ) const MaxMetadataLen = 1024 @@ -95,6 +103,22 @@ type AclState struct { optionChanges []OptionChange isOneToOne bool + + // parentSpaceId + legalOwner are set from the root for child (nested) spaces + parentSpaceId string + // legalOwner is the current legal owner key: pinned at the root, advanced by AclLegalOwnerUpdate + legalOwner crypto.PubKey + // parentAclRootId is the parent space's acl root id — the binding scope every + // AclLegalOwnerUpdate proof (an ownership change from the parent) must carry + parentAclRootId string + // consumedOwnershipProofs guards AclLegalOwnerUpdate against replaying an already-consumed + // parent ownership-change record (keyed by the record cid) + consumedOwnershipProofs map[string]struct{} + // childRegistrations is a map childSpaceId -> registration for children registered under this (parent) space + childRegistrations map[string]ChildRegistration + // pendingKeylessRemovals holds identities removed via AclAccountRemoveNoRotate and not yet + // covered by a read-key rotation (keyed by identity map key); cleared on any read-key change + pendingKeylessRemovals map[string]struct{} } func newAclStateWithKeys( @@ -111,6 +135,10 @@ func newAclStateWithKeys( requestRecords: make(map[string]RequestRecord), pendingRequests: make(map[string]string), keyStore: crypto.NewKeyStorage(), + + consumedOwnershipProofs: make(map[string]struct{}), + childRegistrations: make(map[string]ChildRegistration), + pendingKeylessRemovals: make(map[string]struct{}), } st.contentValidator = newContentValidator(st.keyStore, st, verifier) err = st.applyRoot(rootRecord) @@ -129,6 +157,10 @@ func newAclState(rootRecord *AclRecord, verifier recordverifier.AcceptorVerifier requestRecords: make(map[string]RequestRecord), pendingRequests: make(map[string]string), keyStore: crypto.NewKeyStorage(), + + consumedOwnershipProofs: make(map[string]struct{}), + childRegistrations: make(map[string]ChildRegistration), + pendingKeylessRemovals: make(map[string]struct{}), } st.contentValidator = newContentValidator(st.keyStore, st, verifier) err = st.applyRoot(rootRecord) @@ -142,6 +174,12 @@ func (st *AclState) Identity() crypto.PubKey { return st.pubKey } +// Id returns the acl root record id (same value as AclList.Id()). It is the binding +// scope a child space pins as parentAclRootId for legalOwner proofs. +func (st *AclState) Id() string { + return st.id +} + func (st *AclState) Validator() ContentValidator { return st.contentValidator } @@ -348,6 +386,20 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) { return } } + if root.ParentSpaceId != "" || len(root.LegalOwner) > 0 || root.ParentAclRootId != "" { + // all-or-none: a child space must declare its parent, pin the legal owner, + // and pin the parent acl root (the binding scope for legalOwner proofs) together + if root.ParentSpaceId == "" || len(root.LegalOwner) == 0 || root.ParentAclRootId == "" { + return ErrIncorrectRoot + } + legalOwner, err := st.keyStore.PubKeyFromProto(root.LegalOwner) + if err != nil { + return err + } + st.parentSpaceId = root.ParentSpaceId + st.legalOwner = legalOwner + st.parentAclRootId = root.ParentAclRootId + } // adding an account to the list accountState := AccountState{ PubKey: record.Identity, @@ -437,6 +489,21 @@ func (st *AclState) Copy() *AclState { for k, v := range st.pendingRequests { newSt.pendingRequests[k] = v } + newSt.consumedOwnershipProofs = make(map[string]struct{}) + for k := range st.consumedOwnershipProofs { + newSt.consumedOwnershipProofs[k] = struct{}{} + } + newSt.childRegistrations = make(map[string]ChildRegistration) + for k, v := range st.childRegistrations { + newSt.childRegistrations[k] = v + } + newSt.pendingKeylessRemovals = make(map[string]struct{}) + for k := range st.pendingKeylessRemovals { + newSt.pendingKeylessRemovals[k] = struct{}{} + } + newSt.parentSpaceId = st.parentSpaceId + newSt.legalOwner = st.legalOwner + newSt.parentAclRootId = st.parentAclRootId newSt.readKeyChanges = append(newSt.readKeyChanges, st.readKeyChanges...) newSt.optionChanges = append(newSt.optionChanges, st.optionChanges...) newSt.list = st.list @@ -479,6 +546,14 @@ func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recor return st.applyPermissionChanges(ch.GetPermissionChanges(), record) case ch.GetSpaceOptionsChange() != nil: return st.applySpaceOptionsChange(ch.GetSpaceOptionsChange(), record) + case ch.GetChildRegister() != nil: + return st.applyChildRegister(ch.GetChildRegister(), record) + case ch.GetChildRegisterRevoke() != nil: + return st.applyChildRegisterRevoke(ch.GetChildRegisterRevoke(), record) + case ch.GetLegalOwnerUpdate() != nil: + return st.applyLegalOwnerUpdate(ch.GetLegalOwnerUpdate(), record) + case ch.GetAccountRemoveNoRotate() != nil: + return st.applyAccountRemoveNoRotate(ch.GetAccountRemoveNoRotate(), record) default: log.Errorf("got unexpected content type: %s", record.Id) return nil @@ -503,6 +578,63 @@ func (st *AclState) applyOwnershipChange(ch *aclrecordproto.AclOwnershipChange, return nil } +func (st *AclState) applyChildRegister(ch *aclrecordproto.AclChildRegister, record *AclRecord) (err error) { + err = st.contentValidator.ValidateChildRegister(ch, record.Identity) + if err != nil { + return err + } + if ch.ChildSpaceId == "" { + // on the non-validating (node) path an empty id would otherwise synthesize a phantom entry + return nil + } + if reg, ok := st.childRegistrations[ch.ChildSpaceId]; ok && !reg.Revoked { + // on the non-validating path a duplicate would otherwise silently overwrite the live entry + return nil + } + st.childRegistrations[ch.ChildSpaceId] = ChildRegistration{ + RecordId: record.Id, + ChildSpaceId: ch.ChildSpaceId, + ChildAclRootId: ch.ChildAclRootId, + OrgPermission: AclPermissions(ch.OrgPermission), + Author: record.Identity, + } + return nil +} + +func (st *AclState) applyChildRegisterRevoke(ch *aclrecordproto.AclChildRegisterRevoke, record *AclRecord) (err error) { + err = st.contentValidator.ValidateChildRegisterRevoke(ch, record.Identity) + if err != nil { + return err + } + reg, ok := st.childRegistrations[ch.ChildSpaceId] + if !ok { + // on the non-validating (node) path a revoke for an unknown child would + // otherwise synthesize a phantom entry with an empty ChildSpaceId + return nil + } + reg.Revoked = true + st.childRegistrations[ch.ChildSpaceId] = reg + return nil +} + +func (st *AclState) applyLegalOwnerUpdate(ch *aclrecordproto.AclLegalOwnerUpdate, record *AclRecord) (err error) { + err = st.contentValidator.ValidateLegalOwnerUpdate(ch, record.Identity) + if err != nil { + return err + } + for _, raw := range ch.OwnershipChanges { + // decode only: the validator already signature-checked the proofs when validation is + // on, and a non-validating node must not reject a coordinator-accepted record here + _, newOwner, proofId, _, err := decodeOwnershipChangeProof(st.keyStore, raw, false) + if err != nil { + return err + } + st.consumedOwnershipProofs[proofId] = struct{}{} + st.legalOwner = newOwner + } + return nil +} + func (st *AclState) applyPermissionChanges(ch *aclrecordproto.AclAccountPermissionChanges, record *AclRecord) (err error) { for _, ch := range ch.Changes { err := st.applyPermissionChange(ch, record) @@ -875,6 +1007,38 @@ func (st *AclState) applyAccountRemove(ch *aclrecordproto.AclAccountRemove, reco return st.applyReadKeyChange(ch.ReadKeyChange, record, false) } +func (st *AclState) applyAccountRemoveNoRotate(ch *aclrecordproto.AclAccountRemoveNoRotate, record *AclRecord) error { + err := st.contentValidator.ValidateAccountRemoveNoRotate(ch, record.Identity) + if err != nil { + return err + } + for _, rawIdentity := range ch.Identities { + identity, err := st.keyStore.PubKeyFromProto(rawIdentity) + if err != nil { + return err + } + idKey := mapKeyFromPubKey(identity) + accSt, exists := st.accountStates[idKey] + if !exists { + return ErrNoSuchAccount + } + accSt.Status = StatusRemoved + accSt.Permissions = AclPermissionsNone + accSt.PermissionChanges = append(accSt.PermissionChanges, PermissionChange{ + RecordId: record.Id, + Permission: AclPermissionsNone, + }) + st.accountStates[idKey] = accSt + recId, exists := st.pendingRequests[idKey] + if exists { + delete(st.pendingRequests, idKey) + delete(st.requestRecords, recId) + } + st.pendingKeylessRemovals[idKey] = struct{}{} + } + return nil +} + func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, record *AclRecord, validate bool) error { if validate { err := st.contentValidator.ValidateReadKeyChange(ch, record.Identity) @@ -883,6 +1047,8 @@ func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, reco } } st.readKeyChanges = append(st.readKeyChanges, record.Id) + // a rotation restores forward secrecy: pending keyless removals are now covered + st.pendingKeylessRemovals = make(map[string]struct{}) mkPubKey, err := st.keyStore.PubKeyFromProto(ch.MetadataPubKey) if err != nil { return err @@ -1127,3 +1293,51 @@ func closestPermissions(accountState AccountState, recordId string, isAfter func } return AclPermissionsNone } + +// LegalOwner returns the current legal owner key of a child (nested) space, nil for top-level spaces +func (st *AclState) LegalOwner() crypto.PubKey { + return st.legalOwner +} + +// ParentSpaceId returns the declared parent space id, empty for top-level spaces +func (st *AclState) ParentSpaceId() string { + return st.parentSpaceId +} + +// IsChildSpace reports whether this space declared a parent at its root +func (st *AclState) IsChildSpace() bool { + return st.legalOwner != nil +} + +// ChildRegistration returns the registration of the given child space id, if any +func (st *AclState) ChildRegistration(childSpaceId string) (reg ChildRegistration, ok bool) { + reg, ok = st.childRegistrations[childSpaceId] + return +} + +// ChildRegistrations returns all child registrations of this (parent) space, sorted by child space id +func (st *AclState) ChildRegistrations() (regs []ChildRegistration) { + for _, reg := range st.childRegistrations { + regs = append(regs, reg) + } + slices.SortFunc(regs, func(a, b ChildRegistration) int { + return strings.Compare(a.ChildSpaceId, b.ChildSpaceId) + }) + return +} + +// PendingKeylessRemovals returns the identities removed via AclAccountRemoveNoRotate that are not +// yet covered by a read-key rotation. Non-empty means a key-holding member should rotate. +func (st *AclState) PendingKeylessRemovals() (identities []crypto.PubKey) { + for idKey := range st.pendingKeylessRemovals { + if accSt, exists := st.accountStates[idKey]; exists { + identities = append(identities, accSt.PubKey) + } + } + return +} + +// HasPendingKeylessRemovals reports whether a keyless removal awaits a completing read-key rotation +func (st *AclState) HasPendingKeylessRemovals() bool { + return len(st.pendingKeylessRemovals) > 0 +} diff --git a/commonspace/object/acl/list/models.go b/commonspace/object/acl/list/models.go index 7c91235f..c6a46d9a 100644 --- a/commonspace/object/acl/list/models.go +++ b/commonspace/object/acl/list/models.go @@ -50,6 +50,16 @@ type PermissionChange struct { Permission AclPermissions } +// ChildRegistration is a child space registered in this (parent) space via AclChildRegister +type ChildRegistration struct { + RecordId string + ChildSpaceId string + ChildAclRootId string + OrgPermission AclPermissions + Author crypto.PubKey + Revoked bool +} + type OptionChange struct { RecordId string Options *aclrecordproto.AclSpaceOptions diff --git a/commonspace/object/acl/list/validator.go b/commonspace/object/acl/list/validator.go index 173b5302..3d77bbd5 100644 --- a/commonspace/object/acl/list/validator.go +++ b/commonspace/object/acl/list/validator.go @@ -5,6 +5,8 @@ import ( "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anyproto/any-sync/commonspace/object/acl/recordverifier" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" ) @@ -26,6 +28,10 @@ type ContentValidator interface { ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) ValidateSpaceOptionsChange(ch *aclrecordproto.AclSpaceOptionsChange, authorIdentity crypto.PubKey) (err error) + ValidateChildRegister(ch *aclrecordproto.AclChildRegister, authorIdentity crypto.PubKey) (err error) + ValidateChildRegisterRevoke(ch *aclrecordproto.AclChildRegisterRevoke, authorIdentity crypto.PubKey) (err error) + ValidateLegalOwnerUpdate(ch *aclrecordproto.AclLegalOwnerUpdate, authorIdentity crypto.PubKey) (err error) + ValidateAccountRemoveNoRotate(ch *aclrecordproto.AclAccountRemoveNoRotate, authorIdentity crypto.PubKey) (err error) } type contentValidator struct { @@ -62,6 +68,11 @@ func (c *contentValidator) ValidateOwnershipChange(ch *aclrecordproto.AclOwnersh if !c.aclState.Permissions(authorIdentity).IsOwner() { return ErrInsufficientPermissions } + // AclRootId binds the transfer to the acl it was accepted into so it can later serve as a + // legalOwner proof in child spaces; a record claiming a foreign acl must not be accepted + if ch.AclRootId != "" && ch.AclRootId != c.aclState.id { + return ErrIncorrectAclRootId + } identity, err := c.keyStore.PubKeyFromProto(ch.NewOwnerIdentity) if err != nil { return err @@ -206,6 +217,14 @@ func (c *contentValidator) validateAclRecordContent(ch *aclrecordproto.AclConten return c.ValidateAccountsAdd(ch.GetAccountsAdd(), authorIdentity) case ch.GetSpaceOptionsChange() != nil: return c.ValidateSpaceOptionsChange(ch.GetSpaceOptionsChange(), authorIdentity) + case ch.GetChildRegister() != nil: + return c.ValidateChildRegister(ch.GetChildRegister(), authorIdentity) + case ch.GetChildRegisterRevoke() != nil: + return c.ValidateChildRegisterRevoke(ch.GetChildRegisterRevoke(), authorIdentity) + case ch.GetLegalOwnerUpdate() != nil: + return c.ValidateLegalOwnerUpdate(ch.GetLegalOwnerUpdate(), authorIdentity) + case ch.GetAccountRemoveNoRotate() != nil: + return c.ValidateAccountRemoveNoRotate(ch.GetAccountRemoveNoRotate(), authorIdentity) default: return ErrUnexpectedContentType } @@ -487,8 +506,16 @@ func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyCh if !c.verifier.ShouldValidate() { return nil } - if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { - return ErrInsufficientPermissions + authorPerms := c.aclState.Permissions(authorIdentity) + if !authorPerms.CanManageAccounts() { + // a Writer may author the rotation that completes a pending keyless removal, + // but only when the space opted in via AclSpaceOptions + opts := c.aclState.CurrentOptions() + editorAllowed := opts != nil && opts.EditorsCanCompleteKeylessRotation && + authorPerms.CanWrite() && c.aclState.HasPendingKeylessRemovals() + if !editorAllowed { + return ErrInsufficientPermissions + } } return c.validateReadKeyChange(ch, nil) } @@ -566,3 +593,192 @@ func (c *contentValidator) validateReadKeyChange(ch *aclrecordproto.AclReadKeyCh } return } + +func (c *contentValidator) ValidateChildRegister(ch *aclrecordproto.AclChildRegister, authorIdentity crypto.PubKey) (err error) { + if !c.verifier.ShouldValidate() { + return nil + } + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + if opts := c.aclState.CurrentOptions(); opts != nil && opts.ChildrenCreationDisallowed { + return ErrChildrenCreationDisallowed + } + if ch.ChildSpaceId == "" || ch.ChildAclRootId == "" { + return ErrNoSuchChildRegistration + } + if !AclPermissions(ch.OrgPermission).NoPermissions() { + // reserved: nothing yet adds the org to the child acl or encrypts the read key to it, + // so a non-None value would record an access claim no code path can honor + return ErrOrgPermissionUnsupported + } + if reg, ok := c.aclState.childRegistrations[ch.ChildSpaceId]; ok && !reg.Revoked { + return ErrChildAlreadyRegistered + } + return nil +} + +func (c *contentValidator) ValidateChildRegisterRevoke(ch *aclrecordproto.AclChildRegisterRevoke, authorIdentity crypto.PubKey) (err error) { + if !c.verifier.ShouldValidate() { + return nil + } + if !c.aclState.Permissions(authorIdentity).CanManageAccounts() { + return ErrInsufficientPermissions + } + reg, ok := c.aclState.childRegistrations[ch.ChildSpaceId] + if !ok || reg.Revoked { + return ErrNoSuchChildRegistration + } + return nil +} + +// ValidateLegalOwnerUpdate checks the signature-induction chain: the first embedded parent +// ownership-change must be signed by the currently stored legal owner, each next one by the +// owner the previous one named, and the author of this record must be the final owner. Each +// proof must be bound to the parent acl (aclRootId == the child's pinned parentAclRootId), and +// already-consumed proof CIDs are rejected so a cycled ownership cannot be REPLAYED. +// +// This induction is self-contained (verifiable offline, e.g. by external-seat members who do +// not replicate the parent acl) but proofs are only author-signature-checked here — they are +// NOT verified to have been accepted into the parent acl. A stored legal owner could therefore +// mint a FRESH (never-accepted) ownership change to a key of its choosing. The authoritative +// guard against that is the coordinator gate (verifyKeylessGovernanceRecord), which requires an +// AclLegalOwnerUpdate to be authored by the parent's CURRENT owner; this client-side check is +// defense-in-depth. Fully closing the offline gap needs an acceptor-inclusion proof (not +// available on the ValidateFull path, whose VerifyAcceptor is a no-op). +func (c *contentValidator) ValidateLegalOwnerUpdate(ch *aclrecordproto.AclLegalOwnerUpdate, authorIdentity crypto.PubKey) (err error) { + if !c.verifier.ShouldValidate() { + return nil + } + if c.aclState.legalOwner == nil { + return ErrNotChildSpace + } + if len(ch.OwnershipChanges) == 0 { + return ErrInvalidLegalOwnerProof + } + var ( + expected = c.aclState.legalOwner + inBatch = map[string]struct{}{} + ) + for _, raw := range ch.OwnershipChanges { + author, newOwner, proofId, aclRootId, err := unmarshalOwnershipChangeProof(c.keyStore, raw) + if err != nil { + return err + } + // bind the proof to the parent space: an ownership change from any OTHER + // acl (even one signed by the same key) must not advance this child's owner + if aclRootId == "" || aclRootId != c.aclState.parentAclRootId { + return ErrInvalidLegalOwnerProof + } + if !author.Equals(expected) { + return ErrInvalidLegalOwnerProof + } + if _, consumed := c.aclState.consumedOwnershipProofs[proofId]; consumed { + return ErrInvalidLegalOwnerProof + } + if _, dup := inBatch[proofId]; dup { + return ErrInvalidLegalOwnerProof + } + inBatch[proofId] = struct{}{} + expected = newOwner + } + if !authorIdentity.Equals(expected) { + return ErrInsufficientPermissions + } + return nil +} + +// unmarshalOwnershipChangeProof decodes one embedded parent acl record (consensusproto.RawRecord bytes), +// verifies the author signature over its payload and requires it to contain exactly one AclOwnershipChange. +// Returns the record author, the new owner it names and the replay-guard key: the cid of the SIGNED +// payload, not of the whole envelope — acceptor fields sit outside the signature, so an envelope-keyed +// guard could be bypassed by re-serializing a consumed proof with a mutated acceptor field. +func unmarshalOwnershipChangeProof(keyStore crypto.KeyStorage, raw []byte) (author, newOwner crypto.PubKey, proofId, aclRootId string, err error) { + return decodeOwnershipChangeProof(keyStore, raw, true) +} + +// decodeOwnershipChangeProof is the shared decode: the validator passes verifySignature=true, the +// state-apply path passes false so a non-validating (acceptor-trust) node never does or fails +// signature-dependent work on a record its coordinator already accepted. +func decodeOwnershipChangeProof(keyStore crypto.KeyStorage, raw []byte, verifySignature bool) (author, newOwner crypto.PubKey, proofId, aclRootId string, err error) { + rawRec := &consensusproto.RawRecord{} + if err = rawRec.UnmarshalVT(raw); err != nil { + return + } + rec := &consensusproto.Record{} + if err = rec.UnmarshalVT(rawRec.Payload); err != nil { + return + } + author, err = keyStore.PubKeyFromProto(rec.Identity) + if err != nil { + return + } + if verifySignature { + var res bool + res, err = author.Verify(rawRec.Payload, rawRec.Signature) + if err != nil { + return + } + if !res { + err = ErrInvalidSignature + return + } + } + aclData := &aclrecordproto.AclData{} + if err = aclData.UnmarshalVT(rec.Data); err != nil { + return + } + if len(aclData.AclContent) != 1 || aclData.AclContent[0].GetOwnershipChange() == nil { + err = ErrInvalidLegalOwnerProof + return + } + ownershipChange := aclData.AclContent[0].GetOwnershipChange() + newOwner, err = keyStore.PubKeyFromProto(ownershipChange.NewOwnerIdentity) + if err != nil { + return + } + aclRootId = ownershipChange.AclRootId + proofId, err = cidutil.NewCidFromBytes(rawRec.Payload) + return +} + +// ValidateAccountRemoveNoRotate admits the keyless-governance removal: only the current legalOwner +// of a child (nested) space may author it, even though it holds no permissions in this acl. +func (c *contentValidator) ValidateAccountRemoveNoRotate(ch *aclrecordproto.AclAccountRemoveNoRotate, authorIdentity crypto.PubKey) (err error) { + if !c.verifier.ShouldValidate() { + return nil + } + if c.aclState.legalOwner == nil { + return ErrNotChildSpace + } + if !authorIdentity.Equals(c.aclState.legalOwner) { + return ErrInsufficientPermissions + } + if len(ch.Identities) == 0 { + return ErrIncorrectNumberOfAccounts + } + seenIdentities := map[string]struct{}{} + for _, rawIdentity := range ch.Identities { + identity, err := c.keyStore.PubKeyFromProto(rawIdentity) + if err != nil { + return err + } + if identity.Equals(authorIdentity) { + return ErrInsufficientPermissions + } + permissions := c.aclState.Permissions(identity) + if permissions.NoPermissions() { + return ErrNoSuchAccount + } + if permissions.IsOwner() { + // the legalOwner governs members, not the child's owner; deleting the space is its lever there + return ErrInsufficientPermissions + } + idKey := mapKeyFromPubKey(identity) + if _, exists := seenIdentities[idKey]; exists { + return ErrDuplicateAccounts + } + seenIdentities[idKey] = struct{}{} + } + return nil +} diff --git a/commonspace/spacepayloads/nestedspaces_test.go b/commonspace/spacepayloads/nestedspaces_test.go new file mode 100644 index 00000000..0de68449 --- /dev/null +++ b/commonspace/spacepayloads/nestedspaces_test.go @@ -0,0 +1,100 @@ +package spacepayloads + +import ( + mrand "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/object/acl/aclrecordproto" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/consensus/consensusproto" + "github.com/anyproto/any-sync/util/crypto" +) + +func newChildSpaceCreatePayload(t *testing.T, parentSpaceId string, legalOwner crypto.PubKey) SpaceCreatePayload { + acc, err := accountdata.NewRandom() + require.NoError(t, err) + master, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + metaKey, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + readKey, _ := crypto.NewRandomAES() + return SpaceCreatePayload{ + SigningKey: acc.SignKey, + SpaceType: "test.space", + ReplicationKey: mrand.Uint64(), + MasterKey: master, + ReadKey: readKey, + MetadataKey: metaKey, + Metadata: randBytes(6), + ParentSpaceId: parentSpaceId, + LegalOwner: legalOwner, + ParentAclRootId: "parent-acl-root-id", + } +} + +func TestStoragePayloadForChildSpaceCreateV1(t *testing.T) { + parentOwner, _, err := crypto.GenerateRandomEd25519KeyPair() + require.NoError(t, err) + + t.Run("child payload builds and validates", func(t *testing.T) { + pl := newChildSpaceCreatePayload(t, "parent.id", parentOwner.GetPublic()) + out, err := StoragePayloadForSpaceCreateV1(pl) + require.NoError(t, err) + require.NoError(t, ValidateSpaceStorageCreatePayload(out)) + + // header carries the parent link + var rawHeader spacesyncproto.RawSpaceHeader + require.NoError(t, rawHeader.UnmarshalVT(out.SpaceHeaderWithId.RawHeader)) + var header spacesyncproto.SpaceHeader + require.NoError(t, header.UnmarshalVT(rawHeader.SpaceHeader)) + require.Equal(t, "parent.id", header.ParentSpaceId) + + // acl root mirrors it and pins the legal owner + var rawAcl consensusproto.RawRecord + require.NoError(t, rawAcl.UnmarshalVT(out.AclWithId.Payload)) + var aclRoot aclrecordproto.AclRoot + require.NoError(t, aclRoot.UnmarshalVT(rawAcl.Payload)) + require.Equal(t, "parent.id", aclRoot.ParentSpaceId) + legalOwner, err := crypto.UnmarshalEd25519PublicKeyProto(aclRoot.LegalOwner) + require.NoError(t, err) + require.True(t, legalOwner.Equals(parentOwner.GetPublic())) + }) + + t.Run("parent link requires legal owner", func(t *testing.T) { + pl := newChildSpaceCreatePayload(t, "parent.id", nil) + _, err := StoragePayloadForSpaceCreateV1(pl) + require.ErrorIs(t, err, list.ErrIncorrectRoot) + }) + + t.Run("v0 create rejects a parent link", func(t *testing.T) { + pl := newChildSpaceCreatePayload(t, "parent.id", parentOwner.GetPublic()) + _, err := StoragePayloadForSpaceCreate(pl) + require.ErrorIs(t, err, ErrIncorrectParentLink) + }) + + t.Run("validateParentLink rejects a non-V1 header carrying a parent link", func(t *testing.T) { + legalOwner, err := parentOwner.GetPublic().Marshall() + require.NoError(t, err) + aclRoot := &aclrecordproto.AclRoot{ + ParentSpaceId: "parent.id", + LegalOwner: legalOwner, + ParentAclRootId: "parent-acl-root-id", + } + mkHeader := func(version spacesyncproto.SpaceHeaderVersion) *spacesyncproto.RawSpaceHeaderWithId { + h := &spacesyncproto.SpaceHeader{ParentSpaceId: "parent.id", Version: version} + hb, err := h.MarshalVT() + require.NoError(t, err) + raw, err := (&spacesyncproto.RawSpaceHeader{SpaceHeader: hb}).MarshalVT() + require.NoError(t, err) + return &spacesyncproto.RawSpaceHeaderWithId{RawHeader: raw} + } + // V0 child header is rejected... + require.ErrorIs(t, validateParentLink(mkHeader(spacesyncproto.SpaceHeaderVersion_SpaceHeaderVersion0), aclRoot), ErrIncorrectParentLink) + // ...V1 with the matching parent link passes + require.NoError(t, validateParentLink(mkHeader(spacesyncproto.SpaceHeaderVersion_SpaceHeaderVersion1), aclRoot)) + }) +} diff --git a/commonspace/spacepayloads/payloads.go b/commonspace/spacepayloads/payloads.go index 9517a70c..e4ebd14b 100644 --- a/commonspace/spacepayloads/payloads.go +++ b/commonspace/spacepayloads/payloads.go @@ -44,6 +44,12 @@ type SpaceCreatePayload struct { Options *aclrecordproto.AclSpaceOptions // FileProtoVersion gates the file protocol the space uses (embedded in the signed header) FileProtoVersion spacesyncproto.SpaceFileProtoVersion + // ParentSpaceId declares the space a child of another space (nested spaces); requires LegalOwner and a V1 header + ParentSpaceId string + // LegalOwner is the parent space owner key pinned into the child acl root; required with ParentSpaceId + LegalOwner crypto.PubKey + // ParentAclRootId is the parent space's acl root id — the binding scope for legalOwner proofs; required with ParentSpaceId + ParentAclRootId string } type SpaceDerivePayload struct { @@ -60,9 +66,15 @@ const ( ) var ErrIncorrectIdentity = errors.New("incorrect identity") +var ErrIncorrectParentLink = errors.New("incorrect parent space link") var ErrIncorrectOneToOnePayload = errors.New("incorrect onetoone payload") func StoragePayloadForSpaceCreate(payload SpaceCreatePayload) (storagePayload spacestorage.SpaceStorageCreatePayload, err error) { + if payload.ParentSpaceId != "" { + // nested spaces require the V1 header (the acl root with the parent link is part of the signed header) + err = ErrIncorrectParentLink + return + } // marshalling keys identity, err := payload.SigningKey.GetPublic().Marshall() if err != nil { @@ -171,6 +183,7 @@ func StoragePayloadForSpaceCreateV1(payload SpaceCreatePayload) (storagePayload ReplicationKey: payload.ReplicationKey, Seed: spaceHeaderSeed, FileprotoVersion: payload.FileProtoVersion, + ParentSpaceId: payload.ParentSpaceId, Version: spacesyncproto.SpaceHeaderVersion_SpaceHeaderVersion1, } @@ -184,8 +197,11 @@ func StoragePayloadForSpaceCreateV1(payload SpaceCreatePayload) (storagePayload MetadataKey: payload.MetadataKey, ReadKey: payload.ReadKey, }, - Metadata: payload.Metadata, - Options: payload.Options, + Metadata: payload.Metadata, + Options: payload.Options, + ParentSpaceId: payload.ParentSpaceId, + LegalOwner: payload.LegalOwner, + ParentAclRootId: payload.ParentAclRootId, }) if err != nil { return @@ -538,10 +554,13 @@ func ValidateSpaceStorageCreatePayload(payload spacestorage.SpaceStorageCreatePa if err != nil { return } - aclSpaceId, err := validateCreateSpaceAclPayload(payload.AclWithId) + aclRoot, aclSpaceId, err := parseValidateCreateSpaceAclPayload(payload.AclWithId) if err != nil { return } + if err = validateParentLink(payload.SpaceHeaderWithId, aclRoot); err != nil { + return + } aclHeadId, settingsSpaceId, err := validateCreateSpaceSettingsPayload(payload.SpaceSettingsWithId) if err != nil { return @@ -617,6 +636,11 @@ func ValidateSpaceHeader(rawHeaderWithId *spacesyncproto.RawSpaceHeaderWithId, i } func validateCreateSpaceAclPayload(rawWithId *consensusproto.RawRecordWithId) (spaceId string, err error) { + _, spaceId, err = parseValidateCreateSpaceAclPayload(rawWithId) + return +} + +func parseValidateCreateSpaceAclPayload(rawWithId *consensusproto.RawRecordWithId) (root *aclrecordproto.AclRoot, spaceId string, err error) { if !cidutil.VerifyCid(rawWithId.Payload, rawWithId.Id) { err = objecttree.ErrIncorrectCid return @@ -654,6 +678,7 @@ func validateCreateSpaceAclPayload(rawWithId *consensusproto.RawRecordWithId) (s return } spaceId = aclRoot.SpaceId + root = &aclRoot return } @@ -691,3 +716,36 @@ func validateCreateSpaceSettingsPayload(rawWithId *treechangeproto.RawTreeChange func NewSpaceId(id string, repKey uint64) string { return id + "." + strconv.FormatUint(repKey, 36) } + +// validateParentLink cross-checks the nested-spaces declaration between the signed header and the acl root: +// header.parentSpaceId and the root's parentSpaceId/legalOwner must all be set together and agree +func validateParentLink(rawHeaderWithId *spacesyncproto.RawSpaceHeaderWithId, aclRoot *aclrecordproto.AclRoot) (err error) { + isChild := aclRoot.ParentSpaceId != "" || len(aclRoot.LegalOwner) != 0 || aclRoot.ParentAclRootId != "" + if isChild && (aclRoot.ParentSpaceId == "" || len(aclRoot.LegalOwner) == 0 || aclRoot.ParentAclRootId == "") { + return ErrIncorrectParentLink + } + var rawHeader spacesyncproto.RawSpaceHeader + if err = rawHeader.UnmarshalVT(rawHeaderWithId.RawHeader); err != nil { + return + } + var header spacesyncproto.SpaceHeader + if err = header.UnmarshalVT(rawHeader.SpaceHeader); err != nil { + return + } + if header.ParentSpaceId != aclRoot.ParentSpaceId { + return ErrIncorrectParentLink + } + if isChild { + // nested spaces REQUIRE the V1 header: only V1 binds the acl root into the signed + // header (bytes.Equal(aclPayload, header.AclPayload) in ValidateSpaceHeader). Without + // it a non-V1 child could be signed against one acl root and pushed with another, + // letting an attacker pin themselves as legalOwner in the canonical acl. + if header.Version != spacesyncproto.SpaceHeaderVersion_SpaceHeaderVersion1 { + return ErrIncorrectParentLink + } + if _, err = crypto.UnmarshalEd25519PublicKeyProto(aclRoot.LegalOwner); err != nil { + return ErrIncorrectParentLink + } + } + return nil +} diff --git a/commonspace/spacesyncproto/protos/spacesync.proto b/commonspace/spacesyncproto/protos/spacesync.proto index 228fb0a5..f2fe9bb7 100644 --- a/commonspace/spacesyncproto/protos/spacesync.proto +++ b/commonspace/spacesyncproto/protos/spacesync.proto @@ -148,6 +148,9 @@ message SpaceHeader { // fileprotoVersion gates the file protocol (v2 = filenode v2 + S3-direct + networkSign) SpaceFileProtoVersion fileprotoVersion = 9; + // parentSpaceId declares this space a child of another space (nested spaces); empty for top-level spaces + string parentSpaceId = 10; + SpaceHeaderVersion version = 100; } diff --git a/commonspace/spacesyncproto/spacesync.pb.go b/commonspace/spacesyncproto/spacesync.pb.go index f18393eb..5e9d2087 100644 --- a/commonspace/spacesyncproto/spacesync.pb.go +++ b/commonspace/spacesyncproto/spacesync.pb.go @@ -1051,9 +1051,11 @@ type SpaceHeader struct { SettingPayload []byte `protobuf:"bytes,8,opt,name=settingPayload,proto3" json:"settingPayload,omitempty"` // fileprotoVersion gates the file protocol (v2 = filenode v2 + S3-direct + networkSign) FileprotoVersion SpaceFileProtoVersion `protobuf:"varint,9,opt,name=fileprotoVersion,proto3,enum=spacesync.SpaceFileProtoVersion" json:"fileprotoVersion,omitempty"` - Version SpaceHeaderVersion `protobuf:"varint,100,opt,name=version,proto3,enum=spacesync.SpaceHeaderVersion" json:"version,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // parentSpaceId declares this space a child of another space (nested spaces); empty for top-level spaces + ParentSpaceId string `protobuf:"bytes,10,opt,name=parentSpaceId,proto3" json:"parentSpaceId,omitempty"` + Version SpaceHeaderVersion `protobuf:"varint,100,opt,name=version,proto3,enum=spacesync.SpaceHeaderVersion" json:"version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SpaceHeader) Reset() { @@ -1149,6 +1151,13 @@ func (x *SpaceHeader) GetFileprotoVersion() SpaceFileProtoVersion { return SpaceFileProtoVersion_SpaceFileProtoVersionUnspecified } +func (x *SpaceHeader) GetParentSpaceId() string { + if x != nil { + return x.ParentSpaceId + } + return "" +} + func (x *SpaceHeader) GetVersion() SpaceHeaderVersion { if x != nil { return x.Version @@ -2261,7 +2270,7 @@ const file_commonspace_spacesyncproto_protos_spacesync_proto_rawDesc = "" + "aclPayload\x12\"\n" + "\faclPayloadId\x18\x03 \x01(\tR\faclPayloadId\x122\n" + "\x14spaceSettingsPayload\x18\x04 \x01(\fR\x14spaceSettingsPayload\x126\n" + - "\x16spaceSettingsPayloadId\x18\x05 \x01(\tR\x16spaceSettingsPayloadId\"\xa0\x03\n" + + "\x16spaceSettingsPayloadId\x18\x05 \x01(\tR\x16spaceSettingsPayloadId\"\xc6\x03\n" + "\vSpaceHeader\x12\x1a\n" + "\bidentity\x18\x01 \x01(\fR\bidentity\x12\x1c\n" + "\ttimestamp\x18\x02 \x01(\x03R\ttimestamp\x12\x1c\n" + @@ -2273,7 +2282,9 @@ const file_commonspace_spacesyncproto_protos_spacesync_proto_rawDesc = "" + "aclPayload\x18\a \x01(\fR\n" + "aclPayload\x12&\n" + "\x0esettingPayload\x18\b \x01(\fR\x0esettingPayload\x12L\n" + - "\x10fileprotoVersion\x18\t \x01(\x0e2 .spacesync.SpaceFileProtoVersionR\x10fileprotoVersion\x127\n" + + "\x10fileprotoVersion\x18\t \x01(\x0e2 .spacesync.SpaceFileProtoVersionR\x10fileprotoVersion\x12$\n" + + "\rparentSpaceId\x18\n" + + " \x01(\tR\rparentSpaceId\x127\n" + "\aversion\x18d \x01(\x0e2\x1d.spacesync.SpaceHeaderVersionR\aversion\"P\n" + "\x0eRawSpaceHeader\x12 \n" + "\vspaceHeader\x18\x01 \x01(\fR\vspaceHeader\x12\x1c\n" + diff --git a/commonspace/spacesyncproto/spacesync_vtproto.pb.go b/commonspace/spacesyncproto/spacesync_vtproto.pb.go index 1f1ae609..8ca44b74 100644 --- a/commonspace/spacesyncproto/spacesync_vtproto.pb.go +++ b/commonspace/spacesyncproto/spacesync_vtproto.pb.go @@ -693,6 +693,13 @@ func (m *SpaceHeader) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i-- dAtA[i] = 0xa0 } + if len(m.ParentSpaceId) > 0 { + i -= len(m.ParentSpaceId) + copy(dAtA[i:], m.ParentSpaceId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentSpaceId))) + i-- + dAtA[i] = 0x52 + } if m.FileprotoVersion != 0 { i = protohelpers.EncodeVarint(dAtA, i, uint64(m.FileprotoVersion)) i-- @@ -2005,6 +2012,10 @@ func (m *SpaceHeader) SizeVT() (n int) { if m.FileprotoVersion != 0 { n += 1 + protohelpers.SizeOfVarint(uint64(m.FileprotoVersion)) } + l = len(m.ParentSpaceId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } if m.Version != 0 { n += 2 + protohelpers.SizeOfVarint(uint64(m.Version)) } @@ -4246,6 +4257,38 @@ func (m *SpaceHeader) UnmarshalVT(dAtA []byte) error { break } } + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentSpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ParentSpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 100: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) diff --git a/coordinator/coordinatorclient/coordinatorclient.go b/coordinator/coordinatorclient/coordinatorclient.go index feaa3a2f..8d4931c2 100644 --- a/coordinator/coordinatorclient/coordinatorclient.go +++ b/coordinator/coordinatorclient/coordinatorclient.go @@ -32,6 +32,7 @@ func New() CoordinatorClient { } type CoordinatorClient interface { + ExternalCompartments(ctx context.Context) (spaceIds []string, err error) SpaceDelete(ctx context.Context, spaceId string, conf *coordinatorproto.DeletionConfirmPayloadWithSignature) (err error) AccountDelete(ctx context.Context, conf *coordinatorproto.DeletionConfirmPayloadWithSignature) (timestamp int64, err error) AccountRevertDeletion(ctx context.Context) (err error) @@ -66,6 +67,8 @@ type SpaceSignPayload struct { SpaceId string SpaceHeader []byte ForceRequest bool + // ParentAclRecordId points at the AclChildRegister record in the parent acl (nested spaces) + ParentAclRecordId string } type coordinatorClient struct { @@ -192,9 +195,10 @@ func (c *coordinatorClient) StatusCheck(ctx context.Context, spaceId string) (st func (c *coordinatorClient) SpaceSign(ctx context.Context, payload SpaceSignPayload) (receipt *coordinatorproto.SpaceReceiptWithSignature, err error) { err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error { resp, err := cl.SpaceSign(ctx, &coordinatorproto.SpaceSignRequest{ - SpaceId: payload.SpaceId, - Header: payload.SpaceHeader, - ForceRequest: payload.ForceRequest, + SpaceId: payload.SpaceId, + Header: payload.SpaceHeader, + ForceRequest: payload.ForceRequest, + ParentAclRecordId: payload.ParentAclRecordId, }) if err != nil { return rpcerr.Unwrap(err) @@ -205,6 +209,20 @@ func (c *coordinatorClient) SpaceSign(ctx context.Context, payload SpaceSignPayl return } +// ExternalCompartments lists the child (nested) spaces the calling identity holds an +// external seat in (identities that are not members of the parent space). +func (c *coordinatorClient) ExternalCompartments(ctx context.Context) (spaceIds []string, err error) { + err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error { + resp, err := cl.ExternalCompartments(ctx, &coordinatorproto.ExternalCompartmentsRequest{}) + if err != nil { + return rpcerr.Unwrap(err) + } + spaceIds = resp.SpaceIds + return nil + }) + return +} + func (c *coordinatorClient) NetworkConfiguration(ctx context.Context, currentId string) (resp *coordinatorproto.NetworkConfigurationResponse, err error) { err = c.doClient(ctx, func(cl coordinatorproto.DRPCCoordinatorClient) error { resp, err = cl.NetworkConfiguration(ctx, &coordinatorproto.NetworkConfigurationRequest{ diff --git a/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go b/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go index a6adbfd9..bdfe29e6 100644 --- a/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go +++ b/coordinator/coordinatorclient/mock_coordinatorclient/mock_coordinatorclient.go @@ -163,6 +163,21 @@ func (mr *MockCoordinatorClientMockRecorder) DeletionLog(ctx, lastRecordId, limi return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletionLog", reflect.TypeOf((*MockCoordinatorClient)(nil).DeletionLog), ctx, lastRecordId, limit) } +// ExternalCompartments mocks base method. +func (m *MockCoordinatorClient) ExternalCompartments(ctx context.Context) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExternalCompartments", ctx) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExternalCompartments indicates an expected call of ExternalCompartments. +func (mr *MockCoordinatorClientMockRecorder) ExternalCompartments(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExternalCompartments", reflect.TypeOf((*MockCoordinatorClient)(nil).ExternalCompartments), ctx) +} + // FileLimitsGet mocks base method. func (m *MockCoordinatorClient) FileLimitsGet(ctx context.Context, spaceId, identity string) (*coordinatorproto.FileLimitsGetResponse, error) { m.ctrl.T.Helper() diff --git a/coordinator/coordinatorproto/coordinator.pb.go b/coordinator/coordinatorproto/coordinator.pb.go index b844c8db..cd90fc1b 100644 --- a/coordinator/coordinatorproto/coordinator.pb.go +++ b/coordinator/coordinatorproto/coordinator.pb.go @@ -631,9 +631,12 @@ type SpaceSignRequest struct { // Deprecated: Marked as deprecated in coordinator/coordinatorproto/protos/coordinator.proto. NewIdentitySignature []byte `protobuf:"bytes,4,opt,name=newIdentitySignature,proto3" json:"newIdentitySignature,omitempty"` // ForceRequest if true, forces the creating space receipt even if the space is deleted before - ForceRequest bool `protobuf:"varint,5,opt,name=forceRequest,proto3" json:"forceRequest,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + ForceRequest bool `protobuf:"varint,5,opt,name=forceRequest,proto3" json:"forceRequest,omitempty"` + // ParentAclRecordId points at the AclChildRegister record in the parent space's acl (nested spaces); + // required when the signed header carries a parentSpaceId + ParentAclRecordId string `protobuf:"bytes,6,opt,name=parentAclRecordId,proto3" json:"parentAclRecordId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SpaceSignRequest) Reset() { @@ -703,6 +706,13 @@ func (x *SpaceSignRequest) GetForceRequest() bool { return false } +func (x *SpaceSignRequest) GetParentAclRecordId() string { + if x != nil { + return x.ParentAclRecordId + } + return "" +} + type SpaceLimits struct { state protoimpl.MessageState `protogen:"open.v1"` ReadMembers uint32 `protobuf:"varint,1,opt,name=readMembers,proto3" json:"readMembers,omitempty"` @@ -2624,8 +2634,11 @@ type AccountLimitsSetRequest struct { SpaceMembersRead uint32 `protobuf:"varint,4,opt,name=spaceMembersRead,proto3" json:"spaceMembersRead,omitempty"` SpaceMembersWrite uint32 `protobuf:"varint,5,opt,name=spaceMembersWrite,proto3" json:"spaceMembersWrite,omitempty"` SharedSpacesLimit uint32 `protobuf:"varint,6,opt,name=sharedSpacesLimit,proto3" json:"sharedSpacesLimit,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // externalSeatsLimit caps the distinct non-org identities admitted across all + // child spaces of the identity's spaces (nested spaces / paid external seats) + ExternalSeatsLimit uint32 `protobuf:"varint,7,opt,name=externalSeatsLimit,proto3" json:"externalSeatsLimit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountLimitsSetRequest) Reset() { @@ -2700,6 +2713,13 @@ func (x *AccountLimitsSetRequest) GetSharedSpacesLimit() uint32 { return 0 } +func (x *AccountLimitsSetRequest) GetExternalSeatsLimit() uint32 { + if x != nil { + return x.ExternalSeatsLimit + } + return 0 +} + type AccountLimitsSetResponse struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -2736,6 +2756,86 @@ func (*AccountLimitsSetResponse) Descriptor() ([]byte, []int) { return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{37} } +type ExternalCompartmentsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExternalCompartmentsRequest) Reset() { + *x = ExternalCompartmentsRequest{} + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExternalCompartmentsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalCompartmentsRequest) ProtoMessage() {} + +func (x *ExternalCompartmentsRequest) ProtoReflect() protoreflect.Message { + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalCompartmentsRequest.ProtoReflect.Descriptor instead. +func (*ExternalCompartmentsRequest) Descriptor() ([]byte, []int) { + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{38} +} + +type ExternalCompartmentsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SpaceIds []string `protobuf:"bytes,1,rep,name=spaceIds,proto3" json:"spaceIds,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExternalCompartmentsResponse) Reset() { + *x = ExternalCompartmentsResponse{} + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExternalCompartmentsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalCompartmentsResponse) ProtoMessage() {} + +func (x *ExternalCompartmentsResponse) ProtoReflect() protoreflect.Message { + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalCompartmentsResponse.ProtoReflect.Descriptor instead. +func (*ExternalCompartmentsResponse) Descriptor() ([]byte, []int) { + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{39} +} + +func (x *ExternalCompartmentsResponse) GetSpaceIds() []string { + if x != nil { + return x.SpaceIds + } + return nil +} + type AclEventLogRequest struct { state protoimpl.MessageState `protogen:"open.v1"` AccountIdentity string `protobuf:"bytes,1,opt,name=accountIdentity,proto3" json:"accountIdentity,omitempty"` @@ -2749,7 +2849,7 @@ type AclEventLogRequest struct { func (x *AclEventLogRequest) Reset() { *x = AclEventLogRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[38] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2761,7 +2861,7 @@ func (x *AclEventLogRequest) String() string { func (*AclEventLogRequest) ProtoMessage() {} func (x *AclEventLogRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[38] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2774,7 +2874,7 @@ func (x *AclEventLogRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AclEventLogRequest.ProtoReflect.Descriptor instead. func (*AclEventLogRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{38} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{40} } func (x *AclEventLogRequest) GetAccountIdentity() string { @@ -2810,7 +2910,7 @@ type AclEventLogResponse struct { func (x *AclEventLogResponse) Reset() { *x = AclEventLogResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[39] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2822,7 +2922,7 @@ func (x *AclEventLogResponse) String() string { func (*AclEventLogResponse) ProtoMessage() {} func (x *AclEventLogResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[39] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2835,7 +2935,7 @@ func (x *AclEventLogResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AclEventLogResponse.ProtoReflect.Descriptor instead. func (*AclEventLogResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{39} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{41} } func (x *AclEventLogResponse) GetRecords() []*AclEventLogRecord { @@ -2870,7 +2970,7 @@ type AclEventLogRecord struct { func (x *AclEventLogRecord) Reset() { *x = AclEventLogRecord{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[40] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2882,7 +2982,7 @@ func (x *AclEventLogRecord) String() string { func (*AclEventLogRecord) ProtoMessage() {} func (x *AclEventLogRecord) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[40] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2895,7 +2995,7 @@ func (x *AclEventLogRecord) ProtoReflect() protoreflect.Message { // Deprecated: Use AclEventLogRecord.ProtoReflect.Descriptor instead. func (*AclEventLogRecord) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{40} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{42} } func (x *AclEventLogRecord) GetId() string { @@ -2944,7 +3044,7 @@ type InboxMessage struct { func (x *InboxMessage) Reset() { *x = InboxMessage{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[41] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2956,7 +3056,7 @@ func (x *InboxMessage) String() string { func (*InboxMessage) ProtoMessage() {} func (x *InboxMessage) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[41] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2969,7 +3069,7 @@ func (x *InboxMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxMessage.ProtoReflect.Descriptor instead. func (*InboxMessage) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{41} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{43} } func (x *InboxMessage) GetId() string { @@ -3006,7 +3106,7 @@ type InboxPacket struct { func (x *InboxPacket) Reset() { *x = InboxPacket{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[42] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3018,7 +3118,7 @@ func (x *InboxPacket) String() string { func (*InboxPacket) ProtoMessage() {} func (x *InboxPacket) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[42] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3031,7 +3131,7 @@ func (x *InboxPacket) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxPacket.ProtoReflect.Descriptor instead. func (*InboxPacket) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{42} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{44} } func (x *InboxPacket) GetKeyType() InboxKeyType { @@ -3080,7 +3180,7 @@ type InboxPayload struct { func (x *InboxPayload) Reset() { *x = InboxPayload{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[43] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3092,7 +3192,7 @@ func (x *InboxPayload) String() string { func (*InboxPayload) ProtoMessage() {} func (x *InboxPayload) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[43] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3105,7 +3205,7 @@ func (x *InboxPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxPayload.ProtoReflect.Descriptor instead. func (*InboxPayload) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{43} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{45} } func (x *InboxPayload) GetPayloadType() InboxPayloadType { @@ -3138,7 +3238,7 @@ type InboxFetchRequest struct { func (x *InboxFetchRequest) Reset() { *x = InboxFetchRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[44] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3150,7 +3250,7 @@ func (x *InboxFetchRequest) String() string { func (*InboxFetchRequest) ProtoMessage() {} func (x *InboxFetchRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[44] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3163,7 +3263,7 @@ func (x *InboxFetchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxFetchRequest.ProtoReflect.Descriptor instead. func (*InboxFetchRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{44} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{46} } func (x *InboxFetchRequest) GetOffset() string { @@ -3183,7 +3283,7 @@ type InboxFetchResponse struct { func (x *InboxFetchResponse) Reset() { *x = InboxFetchResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[45] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3195,7 +3295,7 @@ func (x *InboxFetchResponse) String() string { func (*InboxFetchResponse) ProtoMessage() {} func (x *InboxFetchResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[45] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3208,7 +3308,7 @@ func (x *InboxFetchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxFetchResponse.ProtoReflect.Descriptor instead. func (*InboxFetchResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{45} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{47} } func (x *InboxFetchResponse) GetMessages() []*InboxMessage { @@ -3234,7 +3334,7 @@ type InboxAddMessageRequest struct { func (x *InboxAddMessageRequest) Reset() { *x = InboxAddMessageRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[46] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3246,7 +3346,7 @@ func (x *InboxAddMessageRequest) String() string { func (*InboxAddMessageRequest) ProtoMessage() {} func (x *InboxAddMessageRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[46] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3259,7 +3359,7 @@ func (x *InboxAddMessageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxAddMessageRequest.ProtoReflect.Descriptor instead. func (*InboxAddMessageRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{46} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{48} } func (x *InboxAddMessageRequest) GetMessage() *InboxMessage { @@ -3277,7 +3377,7 @@ type InboxAddMessageResponse struct { func (x *InboxAddMessageResponse) Reset() { *x = InboxAddMessageResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[47] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3289,7 +3389,7 @@ func (x *InboxAddMessageResponse) String() string { func (*InboxAddMessageResponse) ProtoMessage() {} func (x *InboxAddMessageResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[47] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3302,7 +3402,7 @@ func (x *InboxAddMessageResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InboxAddMessageResponse.ProtoReflect.Descriptor instead. func (*InboxAddMessageResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{47} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{49} } // Request to subscribe to notifications @@ -3315,7 +3415,7 @@ type NotifySubscribeRequest struct { func (x *NotifySubscribeRequest) Reset() { *x = NotifySubscribeRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[48] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3327,7 +3427,7 @@ func (x *NotifySubscribeRequest) String() string { func (*NotifySubscribeRequest) ProtoMessage() {} func (x *NotifySubscribeRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[48] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3340,7 +3440,7 @@ func (x *NotifySubscribeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NotifySubscribeRequest.ProtoReflect.Descriptor instead. func (*NotifySubscribeRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{48} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{50} } func (x *NotifySubscribeRequest) GetEventType() NotifyEventType { @@ -3360,7 +3460,7 @@ type NotifySubscribeEvent struct { func (x *NotifySubscribeEvent) Reset() { *x = NotifySubscribeEvent{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[49] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3372,7 +3472,7 @@ func (x *NotifySubscribeEvent) String() string { func (*NotifySubscribeEvent) ProtoMessage() {} func (x *NotifySubscribeEvent) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[49] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3385,7 +3485,7 @@ func (x *NotifySubscribeEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use NotifySubscribeEvent.ProtoReflect.Descriptor instead. func (*NotifySubscribeEvent) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{49} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{51} } func (x *NotifySubscribeEvent) GetEventType() NotifyEventType { @@ -3412,7 +3512,7 @@ type AclUploadInviteRequest struct { func (x *AclUploadInviteRequest) Reset() { *x = AclUploadInviteRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[50] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3424,7 +3524,7 @@ func (x *AclUploadInviteRequest) String() string { func (*AclUploadInviteRequest) ProtoMessage() {} func (x *AclUploadInviteRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[50] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3437,7 +3537,7 @@ func (x *AclUploadInviteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AclUploadInviteRequest.ProtoReflect.Descriptor instead. func (*AclUploadInviteRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{50} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{52} } func (x *AclUploadInviteRequest) GetCid() []byte { @@ -3462,7 +3562,7 @@ type AclUploadInviteResponse struct { func (x *AclUploadInviteResponse) Reset() { *x = AclUploadInviteResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[51] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3474,7 +3574,7 @@ func (x *AclUploadInviteResponse) String() string { func (*AclUploadInviteResponse) ProtoMessage() {} func (x *AclUploadInviteResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[51] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3487,7 +3587,7 @@ func (x *AclUploadInviteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AclUploadInviteResponse.ProtoReflect.Descriptor instead. func (*AclUploadInviteResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{51} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{53} } type FileLimitsGetRequest struct { @@ -3501,7 +3601,7 @@ type FileLimitsGetRequest struct { func (x *FileLimitsGetRequest) Reset() { *x = FileLimitsGetRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[52] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3513,7 +3613,7 @@ func (x *FileLimitsGetRequest) String() string { func (*FileLimitsGetRequest) ProtoMessage() {} func (x *FileLimitsGetRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[52] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3526,7 +3626,7 @@ func (x *FileLimitsGetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FileLimitsGetRequest.ProtoReflect.Descriptor instead. func (*FileLimitsGetRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{52} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{54} } func (x *FileLimitsGetRequest) GetSpaceId() string { @@ -3557,7 +3657,7 @@ type FileLimitsGetResponse struct { func (x *FileLimitsGetResponse) Reset() { *x = FileLimitsGetResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[53] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3569,7 +3669,7 @@ func (x *FileLimitsGetResponse) String() string { func (*FileLimitsGetResponse) ProtoMessage() {} func (x *FileLimitsGetResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[53] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3582,7 +3682,7 @@ func (x *FileLimitsGetResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FileLimitsGetResponse.ProtoReflect.Descriptor instead. func (*FileLimitsGetResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{53} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{55} } func (x *FileLimitsGetResponse) GetAccountLimitBytes() uint64 { @@ -3615,7 +3715,7 @@ type FileUsageReportRequest struct { func (x *FileUsageReportRequest) Reset() { *x = FileUsageReportRequest{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[54] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3627,7 +3727,7 @@ func (x *FileUsageReportRequest) String() string { func (*FileUsageReportRequest) ProtoMessage() {} func (x *FileUsageReportRequest) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[54] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3640,7 +3740,7 @@ func (x *FileUsageReportRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FileUsageReportRequest.ProtoReflect.Descriptor instead. func (*FileUsageReportRequest) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{54} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{56} } func (x *FileUsageReportRequest) GetRows() []*FileUsageRow { @@ -3664,7 +3764,7 @@ type FileUsageRow struct { func (x *FileUsageRow) Reset() { *x = FileUsageRow{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[55] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3676,7 +3776,7 @@ func (x *FileUsageRow) String() string { func (*FileUsageRow) ProtoMessage() {} func (x *FileUsageRow) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[55] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3689,7 +3789,7 @@ func (x *FileUsageRow) ProtoReflect() protoreflect.Message { // Deprecated: Use FileUsageRow.ProtoReflect.Descriptor instead. func (*FileUsageRow) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{55} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{57} } func (x *FileUsageRow) GetSpaceId() string { @@ -3728,7 +3828,7 @@ type FileUsageReportResponse struct { func (x *FileUsageReportResponse) Reset() { *x = FileUsageReportResponse{} - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[56] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3740,7 +3840,7 @@ func (x *FileUsageReportResponse) String() string { func (*FileUsageReportResponse) ProtoMessage() {} func (x *FileUsageReportResponse) ProtoReflect() protoreflect.Message { - mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[56] + mi := &file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3753,20 +3853,21 @@ func (x *FileUsageReportResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FileUsageReportResponse.ProtoReflect.Descriptor instead. func (*FileUsageReportResponse) Descriptor() ([]byte, []int) { - return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{56} + return file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP(), []int{58} } var File_coordinator_coordinatorproto_protos_coordinator_proto protoreflect.FileDescriptor const file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc = "" + "\n" + - "5coordinator/coordinatorproto/protos/coordinator.proto\x12\vcoordinator\"\xc6\x01\n" + + "5coordinator/coordinatorproto/protos/coordinator.proto\x12\vcoordinator\"\xf4\x01\n" + "\x10SpaceSignRequest\x12\x18\n" + "\aspaceId\x18\x01 \x01(\tR\aspaceId\x12\x16\n" + "\x06header\x18\x02 \x01(\fR\x06header\x12$\n" + "\voldIdentity\x18\x03 \x01(\fB\x02\x18\x01R\voldIdentity\x126\n" + "\x14newIdentitySignature\x18\x04 \x01(\fB\x02\x18\x01R\x14newIdentitySignature\x12\"\n" + - "\fforceRequest\x18\x05 \x01(\bR\fforceRequest\"S\n" + + "\fforceRequest\x18\x05 \x01(\bR\fforceRequest\x12,\n" + + "\x11parentAclRecordId\x18\x06 \x01(\tR\x11parentAclRecordId\"S\n" + "\vSpaceLimits\x12 \n" + "\vreadMembers\x18\x01 \x01(\rR\vreadMembers\x12\"\n" + "\fwriteMembers\x18\x02 \x01(\rR\fwriteMembers\"\x83\x02\n" + @@ -3877,15 +3978,19 @@ const file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc = "" + "\aspaceId\x18\x01 \x01(\tR\aspaceId\x12\x18\n" + "\aaclHead\x18\x02 \x01(\tR\aaclHead\"1\n" + "\x15AclGetRecordsResponse\x12\x18\n" + - "\arecords\x18\x01 \x03(\fR\arecords\"\x8b\x02\n" + + "\arecords\x18\x01 \x03(\fR\arecords\"\xbb\x02\n" + "\x17AccountLimitsSetRequest\x12\x1a\n" + "\bidentity\x18\x01 \x01(\tR\bidentity\x12\x16\n" + "\x06reason\x18\x02 \x01(\tR\x06reason\x124\n" + "\x15fileStorageLimitBytes\x18\x03 \x01(\x04R\x15fileStorageLimitBytes\x12*\n" + "\x10spaceMembersRead\x18\x04 \x01(\rR\x10spaceMembersRead\x12,\n" + "\x11spaceMembersWrite\x18\x05 \x01(\rR\x11spaceMembersWrite\x12,\n" + - "\x11sharedSpacesLimit\x18\x06 \x01(\rR\x11sharedSpacesLimit\"\x1a\n" + - "\x18AccountLimitsSetResponse\"n\n" + + "\x11sharedSpacesLimit\x18\x06 \x01(\rR\x11sharedSpacesLimit\x12.\n" + + "\x12externalSeatsLimit\x18\a \x01(\rR\x12externalSeatsLimit\"\x1a\n" + + "\x18AccountLimitsSetResponse\"\x1d\n" + + "\x1bExternalCompartmentsRequest\":\n" + + "\x1cExternalCompartmentsResponse\x12\x1a\n" + + "\bspaceIds\x18\x01 \x03(\tR\bspaceIds\"n\n" + "\x12AclEventLogRequest\x12(\n" + "\x0faccountIdentity\x18\x01 \x01(\tR\x0faccountIdentity\x12\x18\n" + "\aafterId\x18\x02 \x01(\tR\aafterId\x12\x14\n" + @@ -4007,7 +4112,7 @@ const file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc = "" + "\x0fNotifyEventType\x12\x14\n" + "\x10UnspecifiedEvent\x10\x00\x12\x18\n" + "\x14InboxNewMessageEvent\x10\x01\x12\x1d\n" + - "\x19NetworkConfigChangedEvent\x10\x022\xb6\x0f\n" + + "\x19NetworkConfigChangedEvent\x10\x022\xa3\x10\n" + "\vCoordinator\x12J\n" + "\tSpaceSign\x12\x1d.coordinator.SpaceSignRequest\x1a\x1e.coordinator.SpaceSignResponse\x12_\n" + "\x10SpaceStatusCheck\x12$.coordinator.SpaceStatusCheckRequest\x1a%.coordinator.SpaceStatusCheckResponse\x12k\n" + @@ -4022,7 +4127,8 @@ const file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc = "" + "\x15AccountRevertDeletion\x12).coordinator.AccountRevertDeletionRequest\x1a*.coordinator.AccountRevertDeletionResponse\x12S\n" + "\fAclAddRecord\x12 .coordinator.AclAddRecordRequest\x1a!.coordinator.AclAddRecordResponse\x12V\n" + "\rAclGetRecords\x12!.coordinator.AclGetRecordsRequest\x1a\".coordinator.AclGetRecordsResponse\x12_\n" + - "\x10AccountLimitsSet\x12$.coordinator.AccountLimitsSetRequest\x1a%.coordinator.AccountLimitsSetResponse\x12P\n" + + "\x10AccountLimitsSet\x12$.coordinator.AccountLimitsSetRequest\x1a%.coordinator.AccountLimitsSetResponse\x12k\n" + + "\x14ExternalCompartments\x12(.coordinator.ExternalCompartmentsRequest\x1a).coordinator.ExternalCompartmentsResponse\x12P\n" + "\vAclEventLog\x12\x1f.coordinator.AclEventLogRequest\x1a .coordinator.AclEventLogResponse\x12M\n" + "\n" + "InboxFetch\x12\x1e.coordinator.InboxFetchRequest\x1a\x1f.coordinator.InboxFetchResponse\x12\\\n" + @@ -4045,7 +4151,7 @@ func file_coordinator_coordinatorproto_protos_coordinator_proto_rawDescGZIP() [] } var file_coordinator_coordinatorproto_protos_coordinator_proto_enumTypes = make([]protoimpl.EnumInfo, 11) -var file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes = make([]protoimpl.MessageInfo, 57) +var file_coordinator_coordinatorproto_protos_coordinator_proto_msgTypes = make([]protoimpl.MessageInfo, 59) var file_coordinator_coordinatorproto_protos_coordinator_proto_goTypes = []any{ (ErrorCodes)(0), // 0: coordinator.ErrorCodes (SpaceStatus)(0), // 1: coordinator.SpaceStatus @@ -4096,25 +4202,27 @@ var file_coordinator_coordinatorproto_protos_coordinator_proto_goTypes = []any{ (*AclGetRecordsResponse)(nil), // 46: coordinator.AclGetRecordsResponse (*AccountLimitsSetRequest)(nil), // 47: coordinator.AccountLimitsSetRequest (*AccountLimitsSetResponse)(nil), // 48: coordinator.AccountLimitsSetResponse - (*AclEventLogRequest)(nil), // 49: coordinator.AclEventLogRequest - (*AclEventLogResponse)(nil), // 50: coordinator.AclEventLogResponse - (*AclEventLogRecord)(nil), // 51: coordinator.AclEventLogRecord - (*InboxMessage)(nil), // 52: coordinator.InboxMessage - (*InboxPacket)(nil), // 53: coordinator.InboxPacket - (*InboxPayload)(nil), // 54: coordinator.InboxPayload - (*InboxFetchRequest)(nil), // 55: coordinator.InboxFetchRequest - (*InboxFetchResponse)(nil), // 56: coordinator.InboxFetchResponse - (*InboxAddMessageRequest)(nil), // 57: coordinator.InboxAddMessageRequest - (*InboxAddMessageResponse)(nil), // 58: coordinator.InboxAddMessageResponse - (*NotifySubscribeRequest)(nil), // 59: coordinator.NotifySubscribeRequest - (*NotifySubscribeEvent)(nil), // 60: coordinator.NotifySubscribeEvent - (*AclUploadInviteRequest)(nil), // 61: coordinator.AclUploadInviteRequest - (*AclUploadInviteResponse)(nil), // 62: coordinator.AclUploadInviteResponse - (*FileLimitsGetRequest)(nil), // 63: coordinator.FileLimitsGetRequest - (*FileLimitsGetResponse)(nil), // 64: coordinator.FileLimitsGetResponse - (*FileUsageReportRequest)(nil), // 65: coordinator.FileUsageReportRequest - (*FileUsageRow)(nil), // 66: coordinator.FileUsageRow - (*FileUsageReportResponse)(nil), // 67: coordinator.FileUsageReportResponse + (*ExternalCompartmentsRequest)(nil), // 49: coordinator.ExternalCompartmentsRequest + (*ExternalCompartmentsResponse)(nil), // 50: coordinator.ExternalCompartmentsResponse + (*AclEventLogRequest)(nil), // 51: coordinator.AclEventLogRequest + (*AclEventLogResponse)(nil), // 52: coordinator.AclEventLogResponse + (*AclEventLogRecord)(nil), // 53: coordinator.AclEventLogRecord + (*InboxMessage)(nil), // 54: coordinator.InboxMessage + (*InboxPacket)(nil), // 55: coordinator.InboxPacket + (*InboxPayload)(nil), // 56: coordinator.InboxPayload + (*InboxFetchRequest)(nil), // 57: coordinator.InboxFetchRequest + (*InboxFetchResponse)(nil), // 58: coordinator.InboxFetchResponse + (*InboxAddMessageRequest)(nil), // 59: coordinator.InboxAddMessageRequest + (*InboxAddMessageResponse)(nil), // 60: coordinator.InboxAddMessageResponse + (*NotifySubscribeRequest)(nil), // 61: coordinator.NotifySubscribeRequest + (*NotifySubscribeEvent)(nil), // 62: coordinator.NotifySubscribeEvent + (*AclUploadInviteRequest)(nil), // 63: coordinator.AclUploadInviteRequest + (*AclUploadInviteResponse)(nil), // 64: coordinator.AclUploadInviteResponse + (*FileLimitsGetRequest)(nil), // 65: coordinator.FileLimitsGetRequest + (*FileLimitsGetResponse)(nil), // 66: coordinator.FileLimitsGetResponse + (*FileUsageReportRequest)(nil), // 67: coordinator.FileUsageReportRequest + (*FileUsageRow)(nil), // 68: coordinator.FileUsageRow + (*FileUsageReportResponse)(nil), // 69: coordinator.FileUsageReportResponse } var file_coordinator_coordinatorproto_protos_coordinator_proto_depIdxs = []int32{ 1, // 0: coordinator.SpaceStatusPayload.status:type_name -> coordinator.SpaceStatus @@ -4130,18 +4238,18 @@ var file_coordinator_coordinatorproto_protos_coordinator_proto_depIdxs = []int32 3, // 10: coordinator.Node.types:type_name -> coordinator.NodeType 35, // 11: coordinator.DeletionLogResponse.records:type_name -> coordinator.DeletionLogRecord 5, // 12: coordinator.DeletionLogRecord.status:type_name -> coordinator.DeletionLogRecordStatus - 51, // 13: coordinator.AclEventLogResponse.records:type_name -> coordinator.AclEventLogRecord + 53, // 13: coordinator.AclEventLogResponse.records:type_name -> coordinator.AclEventLogRecord 6, // 14: coordinator.AclEventLogRecord.type:type_name -> coordinator.AclEventLogRecordType 7, // 15: coordinator.InboxMessage.packetType:type_name -> coordinator.InboxPacketType - 53, // 16: coordinator.InboxMessage.packet:type_name -> coordinator.InboxPacket + 55, // 16: coordinator.InboxMessage.packet:type_name -> coordinator.InboxPacket 8, // 17: coordinator.InboxPacket.keyType:type_name -> coordinator.InboxKeyType - 54, // 18: coordinator.InboxPacket.payload:type_name -> coordinator.InboxPayload + 56, // 18: coordinator.InboxPacket.payload:type_name -> coordinator.InboxPayload 9, // 19: coordinator.InboxPayload.payloadType:type_name -> coordinator.InboxPayloadType - 52, // 20: coordinator.InboxFetchResponse.messages:type_name -> coordinator.InboxMessage - 52, // 21: coordinator.InboxAddMessageRequest.message:type_name -> coordinator.InboxMessage + 54, // 20: coordinator.InboxFetchResponse.messages:type_name -> coordinator.InboxMessage + 54, // 21: coordinator.InboxAddMessageRequest.message:type_name -> coordinator.InboxMessage 10, // 22: coordinator.NotifySubscribeRequest.eventType:type_name -> coordinator.NotifyEventType 10, // 23: coordinator.NotifySubscribeEvent.eventType:type_name -> coordinator.NotifyEventType - 66, // 24: coordinator.FileUsageReportRequest.rows:type_name -> coordinator.FileUsageRow + 68, // 24: coordinator.FileUsageReportRequest.rows:type_name -> coordinator.FileUsageRow 11, // 25: coordinator.Coordinator.SpaceSign:input_type -> coordinator.SpaceSignRequest 17, // 26: coordinator.Coordinator.SpaceStatusCheck:input_type -> coordinator.SpaceStatusCheckRequest 19, // 27: coordinator.Coordinator.SpaceStatusCheckMany:input_type -> coordinator.SpaceStatusCheckManyRequest @@ -4156,36 +4264,38 @@ var file_coordinator_coordinatorproto_protos_coordinator_proto_depIdxs = []int32 43, // 36: coordinator.Coordinator.AclAddRecord:input_type -> coordinator.AclAddRecordRequest 45, // 37: coordinator.Coordinator.AclGetRecords:input_type -> coordinator.AclGetRecordsRequest 47, // 38: coordinator.Coordinator.AccountLimitsSet:input_type -> coordinator.AccountLimitsSetRequest - 49, // 39: coordinator.Coordinator.AclEventLog:input_type -> coordinator.AclEventLogRequest - 55, // 40: coordinator.Coordinator.InboxFetch:input_type -> coordinator.InboxFetchRequest - 57, // 41: coordinator.Coordinator.InboxAddMessage:input_type -> coordinator.InboxAddMessageRequest - 59, // 42: coordinator.Coordinator.NotifySubscribe:input_type -> coordinator.NotifySubscribeRequest - 61, // 43: coordinator.Coordinator.AclUploadInvite:input_type -> coordinator.AclUploadInviteRequest - 63, // 44: coordinator.Coordinator.FileLimitsGet:input_type -> coordinator.FileLimitsGetRequest - 65, // 45: coordinator.Coordinator.FileUsageReport:input_type -> coordinator.FileUsageReportRequest - 14, // 46: coordinator.Coordinator.SpaceSign:output_type -> coordinator.SpaceSignResponse - 18, // 47: coordinator.Coordinator.SpaceStatusCheck:output_type -> coordinator.SpaceStatusCheckResponse - 20, // 48: coordinator.Coordinator.SpaceStatusCheckMany:output_type -> coordinator.SpaceStatusCheckManyResponse - 23, // 49: coordinator.Coordinator.SpaceStatusChange:output_type -> coordinator.SpaceStatusChangeResponse - 25, // 50: coordinator.Coordinator.SpaceMakeShareable:output_type -> coordinator.SpaceMakeShareableResponse - 27, // 51: coordinator.Coordinator.SpaceMakeUnshareable:output_type -> coordinator.SpaceMakeUnshareableResponse - 29, // 52: coordinator.Coordinator.NetworkConfiguration:output_type -> coordinator.NetworkConfigurationResponse - 34, // 53: coordinator.Coordinator.DeletionLog:output_type -> coordinator.DeletionLogResponse - 37, // 54: coordinator.Coordinator.SpaceDelete:output_type -> coordinator.SpaceDeleteResponse - 40, // 55: coordinator.Coordinator.AccountDelete:output_type -> coordinator.AccountDeleteResponse - 42, // 56: coordinator.Coordinator.AccountRevertDeletion:output_type -> coordinator.AccountRevertDeletionResponse - 44, // 57: coordinator.Coordinator.AclAddRecord:output_type -> coordinator.AclAddRecordResponse - 46, // 58: coordinator.Coordinator.AclGetRecords:output_type -> coordinator.AclGetRecordsResponse - 48, // 59: coordinator.Coordinator.AccountLimitsSet:output_type -> coordinator.AccountLimitsSetResponse - 50, // 60: coordinator.Coordinator.AclEventLog:output_type -> coordinator.AclEventLogResponse - 56, // 61: coordinator.Coordinator.InboxFetch:output_type -> coordinator.InboxFetchResponse - 58, // 62: coordinator.Coordinator.InboxAddMessage:output_type -> coordinator.InboxAddMessageResponse - 60, // 63: coordinator.Coordinator.NotifySubscribe:output_type -> coordinator.NotifySubscribeEvent - 62, // 64: coordinator.Coordinator.AclUploadInvite:output_type -> coordinator.AclUploadInviteResponse - 64, // 65: coordinator.Coordinator.FileLimitsGet:output_type -> coordinator.FileLimitsGetResponse - 67, // 66: coordinator.Coordinator.FileUsageReport:output_type -> coordinator.FileUsageReportResponse - 46, // [46:67] is the sub-list for method output_type - 25, // [25:46] is the sub-list for method input_type + 49, // 39: coordinator.Coordinator.ExternalCompartments:input_type -> coordinator.ExternalCompartmentsRequest + 51, // 40: coordinator.Coordinator.AclEventLog:input_type -> coordinator.AclEventLogRequest + 57, // 41: coordinator.Coordinator.InboxFetch:input_type -> coordinator.InboxFetchRequest + 59, // 42: coordinator.Coordinator.InboxAddMessage:input_type -> coordinator.InboxAddMessageRequest + 61, // 43: coordinator.Coordinator.NotifySubscribe:input_type -> coordinator.NotifySubscribeRequest + 63, // 44: coordinator.Coordinator.AclUploadInvite:input_type -> coordinator.AclUploadInviteRequest + 65, // 45: coordinator.Coordinator.FileLimitsGet:input_type -> coordinator.FileLimitsGetRequest + 67, // 46: coordinator.Coordinator.FileUsageReport:input_type -> coordinator.FileUsageReportRequest + 14, // 47: coordinator.Coordinator.SpaceSign:output_type -> coordinator.SpaceSignResponse + 18, // 48: coordinator.Coordinator.SpaceStatusCheck:output_type -> coordinator.SpaceStatusCheckResponse + 20, // 49: coordinator.Coordinator.SpaceStatusCheckMany:output_type -> coordinator.SpaceStatusCheckManyResponse + 23, // 50: coordinator.Coordinator.SpaceStatusChange:output_type -> coordinator.SpaceStatusChangeResponse + 25, // 51: coordinator.Coordinator.SpaceMakeShareable:output_type -> coordinator.SpaceMakeShareableResponse + 27, // 52: coordinator.Coordinator.SpaceMakeUnshareable:output_type -> coordinator.SpaceMakeUnshareableResponse + 29, // 53: coordinator.Coordinator.NetworkConfiguration:output_type -> coordinator.NetworkConfigurationResponse + 34, // 54: coordinator.Coordinator.DeletionLog:output_type -> coordinator.DeletionLogResponse + 37, // 55: coordinator.Coordinator.SpaceDelete:output_type -> coordinator.SpaceDeleteResponse + 40, // 56: coordinator.Coordinator.AccountDelete:output_type -> coordinator.AccountDeleteResponse + 42, // 57: coordinator.Coordinator.AccountRevertDeletion:output_type -> coordinator.AccountRevertDeletionResponse + 44, // 58: coordinator.Coordinator.AclAddRecord:output_type -> coordinator.AclAddRecordResponse + 46, // 59: coordinator.Coordinator.AclGetRecords:output_type -> coordinator.AclGetRecordsResponse + 48, // 60: coordinator.Coordinator.AccountLimitsSet:output_type -> coordinator.AccountLimitsSetResponse + 50, // 61: coordinator.Coordinator.ExternalCompartments:output_type -> coordinator.ExternalCompartmentsResponse + 52, // 62: coordinator.Coordinator.AclEventLog:output_type -> coordinator.AclEventLogResponse + 58, // 63: coordinator.Coordinator.InboxFetch:output_type -> coordinator.InboxFetchResponse + 60, // 64: coordinator.Coordinator.InboxAddMessage:output_type -> coordinator.InboxAddMessageResponse + 62, // 65: coordinator.Coordinator.NotifySubscribe:output_type -> coordinator.NotifySubscribeEvent + 64, // 66: coordinator.Coordinator.AclUploadInvite:output_type -> coordinator.AclUploadInviteResponse + 66, // 67: coordinator.Coordinator.FileLimitsGet:output_type -> coordinator.FileLimitsGetResponse + 69, // 68: coordinator.Coordinator.FileUsageReport:output_type -> coordinator.FileUsageReportResponse + 47, // [47:69] is the sub-list for method output_type + 25, // [25:47] is the sub-list for method input_type 25, // [25:25] is the sub-list for extension type_name 25, // [25:25] is the sub-list for extension extendee 0, // [0:25] is the sub-list for field type_name @@ -4202,7 +4312,7 @@ func file_coordinator_coordinatorproto_protos_coordinator_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc), len(file_coordinator_coordinatorproto_protos_coordinator_proto_rawDesc)), NumEnums: 11, - NumMessages: 57, + NumMessages: 59, NumExtensions: 0, NumServices: 1, }, diff --git a/coordinator/coordinatorproto/coordinator_drpc.pb.go b/coordinator/coordinatorproto/coordinator_drpc.pb.go index 3916a2cf..a64c3df9 100644 --- a/coordinator/coordinatorproto/coordinator_drpc.pb.go +++ b/coordinator/coordinatorproto/coordinator_drpc.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.34 +// protoc-gen-go-drpc version: v1.0.0 // source: coordinator/coordinatorproto/protos/coordinator.proto package coordinatorproto @@ -47,6 +47,7 @@ type DRPCCoordinatorClient interface { AclAddRecord(ctx context.Context, in *AclAddRecordRequest) (*AclAddRecordResponse, error) AclGetRecords(ctx context.Context, in *AclGetRecordsRequest) (*AclGetRecordsResponse, error) AccountLimitsSet(ctx context.Context, in *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error) + ExternalCompartments(ctx context.Context, in *ExternalCompartmentsRequest) (*ExternalCompartmentsResponse, error) AclEventLog(ctx context.Context, in *AclEventLogRequest) (*AclEventLogResponse, error) InboxFetch(ctx context.Context, in *InboxFetchRequest) (*InboxFetchResponse, error) InboxAddMessage(ctx context.Context, in *InboxAddMessageRequest) (*InboxAddMessageResponse, error) @@ -192,6 +193,15 @@ func (c *drpcCoordinatorClient) AccountLimitsSet(ctx context.Context, in *Accoun return out, nil } +func (c *drpcCoordinatorClient) ExternalCompartments(ctx context.Context, in *ExternalCompartmentsRequest) (*ExternalCompartmentsResponse, error) { + out := new(ExternalCompartmentsResponse) + err := c.cc.Invoke(ctx, "/coordinator.Coordinator/ExternalCompartments", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + func (c *drpcCoordinatorClient) AclEventLog(ctx context.Context, in *AclEventLogRequest) (*AclEventLogResponse, error) { out := new(AclEventLogResponse) err := c.cc.Invoke(ctx, "/coordinator.Coordinator/AclEventLog", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, in, out) @@ -301,6 +311,7 @@ type DRPCCoordinatorServer interface { AclAddRecord(context.Context, *AclAddRecordRequest) (*AclAddRecordResponse, error) AclGetRecords(context.Context, *AclGetRecordsRequest) (*AclGetRecordsResponse, error) AccountLimitsSet(context.Context, *AccountLimitsSetRequest) (*AccountLimitsSetResponse, error) + ExternalCompartments(context.Context, *ExternalCompartmentsRequest) (*ExternalCompartmentsResponse, error) AclEventLog(context.Context, *AclEventLogRequest) (*AclEventLogResponse, error) InboxFetch(context.Context, *InboxFetchRequest) (*InboxFetchResponse, error) InboxAddMessage(context.Context, *InboxAddMessageRequest) (*InboxAddMessageResponse, error) @@ -368,6 +379,10 @@ func (s *DRPCCoordinatorUnimplementedServer) AccountLimitsSet(context.Context, * return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } +func (s *DRPCCoordinatorUnimplementedServer) ExternalCompartments(context.Context, *ExternalCompartmentsRequest) (*ExternalCompartmentsResponse, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + func (s *DRPCCoordinatorUnimplementedServer) AclEventLog(context.Context, *AclEventLogRequest) (*AclEventLogResponse, error) { return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) } @@ -398,7 +413,7 @@ func (s *DRPCCoordinatorUnimplementedServer) FileUsageReport(context.Context, *F type DRPCCoordinatorDescription struct{} -func (DRPCCoordinatorDescription) NumMethods() int { return 21 } +func (DRPCCoordinatorDescription) NumMethods() int { return 22 } func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { switch n { @@ -529,6 +544,15 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec ) }, DRPCCoordinatorServer.AccountLimitsSet, true case 14: + return "/coordinator.Coordinator/ExternalCompartments", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCCoordinatorServer). + ExternalCompartments( + ctx, + in1.(*ExternalCompartmentsRequest), + ) + }, DRPCCoordinatorServer.ExternalCompartments, true + case 15: return "/coordinator.Coordinator/AclEventLog", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -537,7 +561,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec in1.(*AclEventLogRequest), ) }, DRPCCoordinatorServer.AclEventLog, true - case 15: + case 16: return "/coordinator.Coordinator/InboxFetch", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -546,7 +570,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec in1.(*InboxFetchRequest), ) }, DRPCCoordinatorServer.InboxFetch, true - case 16: + case 17: return "/coordinator.Coordinator/InboxAddMessage", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -555,7 +579,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec in1.(*InboxAddMessageRequest), ) }, DRPCCoordinatorServer.InboxAddMessage, true - case 17: + case 18: return "/coordinator.Coordinator/NotifySubscribe", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return nil, srv.(DRPCCoordinatorServer). @@ -564,7 +588,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec &drpcCoordinator_NotifySubscribeStream{in2.(drpc.Stream)}, ) }, DRPCCoordinatorServer.NotifySubscribe, true - case 18: + case 19: return "/coordinator.Coordinator/AclUploadInvite", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -573,7 +597,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec in1.(*AclUploadInviteRequest), ) }, DRPCCoordinatorServer.AclUploadInvite, true - case 19: + case 20: return "/coordinator.Coordinator/FileLimitsGet", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -582,7 +606,7 @@ func (DRPCCoordinatorDescription) Method(n int) (string, drpc.Encoding, drpc.Rec in1.(*FileLimitsGetRequest), ) }, DRPCCoordinatorServer.FileLimitsGet, true - case 20: + case 21: return "/coordinator.Coordinator/FileUsageReport", drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}, func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { return srv.(DRPCCoordinatorServer). @@ -609,6 +633,10 @@ type drpcCoordinator_SpaceSignStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceSignStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceSignStream) SendAndClose(m *SpaceSignResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -625,6 +653,10 @@ type drpcCoordinator_SpaceStatusCheckStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceStatusCheckStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceStatusCheckStream) SendAndClose(m *SpaceStatusCheckResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -641,6 +673,10 @@ type drpcCoordinator_SpaceStatusCheckManyStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceStatusCheckManyStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceStatusCheckManyStream) SendAndClose(m *SpaceStatusCheckManyResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -657,6 +693,10 @@ type drpcCoordinator_SpaceStatusChangeStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceStatusChangeStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceStatusChangeStream) SendAndClose(m *SpaceStatusChangeResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -673,6 +713,10 @@ type drpcCoordinator_SpaceMakeShareableStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceMakeShareableStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceMakeShareableStream) SendAndClose(m *SpaceMakeShareableResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -689,6 +733,10 @@ type drpcCoordinator_SpaceMakeUnshareableStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceMakeUnshareableStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceMakeUnshareableStream) SendAndClose(m *SpaceMakeUnshareableResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -705,6 +753,10 @@ type drpcCoordinator_NetworkConfigurationStream struct { drpc.Stream } +func (x *drpcCoordinator_NetworkConfigurationStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_NetworkConfigurationStream) SendAndClose(m *NetworkConfigurationResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -721,6 +773,10 @@ type drpcCoordinator_DeletionLogStream struct { drpc.Stream } +func (x *drpcCoordinator_DeletionLogStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_DeletionLogStream) SendAndClose(m *DeletionLogResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -737,6 +793,10 @@ type drpcCoordinator_SpaceDeleteStream struct { drpc.Stream } +func (x *drpcCoordinator_SpaceDeleteStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_SpaceDeleteStream) SendAndClose(m *SpaceDeleteResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -753,6 +813,10 @@ type drpcCoordinator_AccountDeleteStream struct { drpc.Stream } +func (x *drpcCoordinator_AccountDeleteStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AccountDeleteStream) SendAndClose(m *AccountDeleteResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -769,6 +833,10 @@ type drpcCoordinator_AccountRevertDeletionStream struct { drpc.Stream } +func (x *drpcCoordinator_AccountRevertDeletionStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AccountRevertDeletionStream) SendAndClose(m *AccountRevertDeletionResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -785,6 +853,10 @@ type drpcCoordinator_AclAddRecordStream struct { drpc.Stream } +func (x *drpcCoordinator_AclAddRecordStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AclAddRecordStream) SendAndClose(m *AclAddRecordResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -801,6 +873,10 @@ type drpcCoordinator_AclGetRecordsStream struct { drpc.Stream } +func (x *drpcCoordinator_AclGetRecordsStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AclGetRecordsStream) SendAndClose(m *AclGetRecordsResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -817,6 +893,10 @@ type drpcCoordinator_AccountLimitsSetStream struct { drpc.Stream } +func (x *drpcCoordinator_AccountLimitsSetStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AccountLimitsSetStream) SendAndClose(m *AccountLimitsSetResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -824,6 +904,26 @@ func (x *drpcCoordinator_AccountLimitsSetStream) SendAndClose(m *AccountLimitsSe return x.CloseSend() } +type DRPCCoordinator_ExternalCompartmentsStream interface { + drpc.Stream + SendAndClose(*ExternalCompartmentsResponse) error +} + +type drpcCoordinator_ExternalCompartmentsStream struct { + drpc.Stream +} + +func (x *drpcCoordinator_ExternalCompartmentsStream) GetStream() drpc.Stream { + return x.Stream +} + +func (x *drpcCoordinator_ExternalCompartmentsStream) SendAndClose(m *ExternalCompartmentsResponse) error { + if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { + return err + } + return x.CloseSend() +} + type DRPCCoordinator_AclEventLogStream interface { drpc.Stream SendAndClose(*AclEventLogResponse) error @@ -833,6 +933,10 @@ type drpcCoordinator_AclEventLogStream struct { drpc.Stream } +func (x *drpcCoordinator_AclEventLogStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AclEventLogStream) SendAndClose(m *AclEventLogResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -849,6 +953,10 @@ type drpcCoordinator_InboxFetchStream struct { drpc.Stream } +func (x *drpcCoordinator_InboxFetchStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_InboxFetchStream) SendAndClose(m *InboxFetchResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -865,6 +973,10 @@ type drpcCoordinator_InboxAddMessageStream struct { drpc.Stream } +func (x *drpcCoordinator_InboxAddMessageStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_InboxAddMessageStream) SendAndClose(m *InboxAddMessageResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -881,6 +993,10 @@ type drpcCoordinator_NotifySubscribeStream struct { drpc.Stream } +func (x *drpcCoordinator_NotifySubscribeStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_NotifySubscribeStream) Send(m *NotifySubscribeEvent) error { return x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}) } @@ -894,6 +1010,10 @@ type drpcCoordinator_AclUploadInviteStream struct { drpc.Stream } +func (x *drpcCoordinator_AclUploadInviteStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_AclUploadInviteStream) SendAndClose(m *AclUploadInviteResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -910,6 +1030,10 @@ type drpcCoordinator_FileLimitsGetStream struct { drpc.Stream } +func (x *drpcCoordinator_FileLimitsGetStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_FileLimitsGetStream) SendAndClose(m *FileLimitsGetResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err @@ -926,6 +1050,10 @@ type drpcCoordinator_FileUsageReportStream struct { drpc.Stream } +func (x *drpcCoordinator_FileUsageReportStream) GetStream() drpc.Stream { + return x.Stream +} + func (x *drpcCoordinator_FileUsageReportStream) SendAndClose(m *FileUsageReportResponse) error { if err := x.MsgSend(m, drpcEncoding_File_coordinator_coordinatorproto_protos_coordinator_proto{}); err != nil { return err diff --git a/coordinator/coordinatorproto/coordinator_vtproto.pb.go b/coordinator/coordinatorproto/coordinator_vtproto.pb.go index d227c945..59f08dc9 100644 --- a/coordinator/coordinatorproto/coordinator_vtproto.pb.go +++ b/coordinator/coordinatorproto/coordinator_vtproto.pb.go @@ -48,6 +48,13 @@ func (m *SpaceSignRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.ParentAclRecordId) > 0 { + i -= len(m.ParentAclRecordId) + copy(dAtA[i:], m.ParentAclRecordId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ParentAclRecordId))) + i-- + dAtA[i] = 0x32 + } if m.ForceRequest { i-- if m.ForceRequest { @@ -1814,6 +1821,11 @@ func (m *AccountLimitsSetRequest) MarshalToSizedBufferVT(dAtA []byte) (int, erro i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.ExternalSeatsLimit != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.ExternalSeatsLimit)) + i-- + dAtA[i] = 0x38 + } if m.SharedSpacesLimit != 0 { i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SharedSpacesLimit)) i-- @@ -1884,6 +1896,81 @@ func (m *AccountLimitsSetResponse) MarshalToSizedBufferVT(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *ExternalCompartmentsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExternalCompartmentsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ExternalCompartmentsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *ExternalCompartmentsResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExternalCompartmentsResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ExternalCompartmentsResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.SpaceIds) > 0 { + for iNdEx := len(m.SpaceIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SpaceIds[iNdEx]) + copy(dAtA[i:], m.SpaceIds[iNdEx]) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.SpaceIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *AclEventLogRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -2818,6 +2905,10 @@ func (m *SpaceSignRequest) SizeVT() (n int) { if m.ForceRequest { n += 2 } + l = len(m.ParentAclRecordId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -3490,6 +3581,9 @@ func (m *AccountLimitsSetRequest) SizeVT() (n int) { if m.SharedSpacesLimit != 0 { n += 1 + protohelpers.SizeOfVarint(uint64(m.SharedSpacesLimit)) } + if m.ExternalSeatsLimit != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.ExternalSeatsLimit)) + } n += len(m.unknownFields) return n } @@ -3504,6 +3598,32 @@ func (m *AccountLimitsSetResponse) SizeVT() (n int) { return n } +func (m *ExternalCompartmentsRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *ExternalCompartmentsResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.SpaceIds) > 0 { + for _, s := range m.SpaceIds { + l = len(s) + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + func (m *AclEventLogRequest) SizeVT() (n int) { if m == nil { return 0 @@ -4027,6 +4147,38 @@ func (m *SpaceSignRequest) UnmarshalVT(dAtA []byte) error { } } m.ForceRequest = bool(v != 0) + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentAclRecordId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ParentAclRecordId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -8213,6 +8365,25 @@ func (m *AccountLimitsSetRequest) UnmarshalVT(dAtA []byte) error { break } } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalSeatsLimit", wireType) + } + m.ExternalSeatsLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExternalSeatsLimit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -8286,6 +8457,140 @@ func (m *AccountLimitsSetResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *ExternalCompartmentsRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExternalCompartmentsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExternalCompartmentsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExternalCompartmentsResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExternalCompartmentsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExternalCompartmentsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceIds = append(m.SpaceIds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *AclEventLogRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/coordinator/coordinatorproto/protos/coordinator.proto b/coordinator/coordinatorproto/protos/coordinator.proto index 2b0bff0a..79447493 100644 --- a/coordinator/coordinatorproto/protos/coordinator.proto +++ b/coordinator/coordinatorproto/protos/coordinator.proto @@ -44,6 +44,11 @@ service Coordinator { // AccountLimitsSet sets limits to the account. Can be used only by a network config member rpc AccountLimitsSet(AccountLimitsSetRequest) returns (AccountLimitsSetResponse); + // ExternalCompartments lists the child (nested) spaces the CALLING identity was admitted + // to as an external seat — the discovery surface for identities that are not members of + // the parent space and therefore cannot read its registrations + rpc ExternalCompartments(ExternalCompartmentsRequest) returns (ExternalCompartmentsResponse); + // EventLog gets the latest event log records rpc AclEventLog(AclEventLogRequest) returns (AclEventLogResponse); @@ -77,6 +82,9 @@ message SpaceSignRequest { bytes newIdentitySignature = 4 [deprecated = true]; // ForceRequest if true, forces the creating space receipt even if the space is deleted before bool forceRequest = 5; + // ParentAclRecordId points at the AclChildRegister record in the parent space's acl (nested spaces); + // required when the signed header carries a parentSpaceId + string parentAclRecordId = 6; } enum ErrorCodes { @@ -394,10 +402,19 @@ message AccountLimitsSetRequest { uint32 spaceMembersRead = 4; uint32 spaceMembersWrite = 5; uint32 sharedSpacesLimit = 6; + // externalSeatsLimit caps the distinct non-org identities admitted across all + // child spaces of the identity's spaces (nested spaces / paid external seats) + uint32 externalSeatsLimit = 7; } message AccountLimitsSetResponse {} +message ExternalCompartmentsRequest {} + +message ExternalCompartmentsResponse { + repeated string spaceIds = 1; +} + message AclEventLogRequest { string accountIdentity = 1; // AfterId is the last known logId to request records after this id. If it is empty will be returned a list from the beginning.