Fixes to acls

This commit is contained in:
mcrakhman 2022-09-26 12:03:20 +02:00
parent 58812a568f
commit d77d8dbdd1
No known key found for this signature in database
GPG Key ID: DED12CFEF5B8396B
11 changed files with 401 additions and 515 deletions

View File

@ -236,6 +236,8 @@ type ACLRoot struct {
SpaceId string `protobuf:"bytes,3,opt,name=spaceId,proto3" json:"spaceId,omitempty"` SpaceId string `protobuf:"bytes,3,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
EncryptedReadKey []byte `protobuf:"bytes,4,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"` EncryptedReadKey []byte `protobuf:"bytes,4,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
DerivationScheme string `protobuf:"bytes,5,opt,name=derivationScheme,proto3" json:"derivationScheme,omitempty"` DerivationScheme string `protobuf:"bytes,5,opt,name=derivationScheme,proto3" json:"derivationScheme,omitempty"`
CurrentReadKeyHash uint64 `protobuf:"varint,6,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"`
Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
} }
func (m *ACLRoot) Reset() { *m = ACLRoot{} } func (m *ACLRoot) Reset() { *m = ACLRoot{} }
@ -306,6 +308,20 @@ func (m *ACLRoot) GetDerivationScheme() string {
return "" return ""
} }
func (m *ACLRoot) GetCurrentReadKeyHash() uint64 {
if m != nil {
return m.CurrentReadKeyHash
}
return 0
}
func (m *ACLRoot) GetTimestamp() int64 {
if m != nil {
return m.Timestamp
}
return 0
}
type ACLContentValue struct { type ACLContentValue struct {
// Types that are valid to be assigned to Value: // Types that are valid to be assigned to Value:
// *ACLContentValue_UserAdd // *ACLContentValue_UserAdd
@ -537,9 +553,7 @@ func (m *ACLState) GetInvites() map[string]*ACLUserInvite {
type ACLUserState struct { type ACLUserState struct {
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
EncryptedReadKeys [][]byte `protobuf:"bytes,3,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"` Permissions ACLUserPermissions `protobuf:"varint,3,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"`
Permissions ACLUserPermissions `protobuf:"varint,4,opt,name=permissions,proto3,enum=aclrecord.ACLUserPermissions" json:"permissions,omitempty"`
IsConfirmed bool `protobuf:"varint,5,opt,name=isConfirmed,proto3" json:"isConfirmed,omitempty"`
} }
func (m *ACLUserState) Reset() { *m = ACLUserState{} } func (m *ACLUserState) Reset() { *m = ACLUserState{} }
@ -589,13 +603,6 @@ func (m *ACLUserState) GetEncryptionKey() []byte {
return nil return nil
} }
func (m *ACLUserState) GetEncryptedReadKeys() [][]byte {
if m != nil {
return m.EncryptedReadKeys
}
return nil
}
func (m *ACLUserState) GetPermissions() ACLUserPermissions { func (m *ACLUserState) GetPermissions() ACLUserPermissions {
if m != nil { if m != nil {
return m.Permissions return m.Permissions
@ -603,13 +610,6 @@ func (m *ACLUserState) GetPermissions() ACLUserPermissions {
return ACLUserPermissions_Admin return ACLUserPermissions_Admin
} }
func (m *ACLUserState) GetIsConfirmed() bool {
if m != nil {
return m.IsConfirmed
}
return false
}
type ACLUserAdd struct { type ACLUserAdd struct {
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"` EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
@ -1018,61 +1018,61 @@ func init() {
} }
var fileDescriptor_14abe0d1b4206d54 = []byte{ var fileDescriptor_14abe0d1b4206d54 = []byte{
// 862 bytes of a gzipped FileDescriptorProto // 859 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0x23, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
0x10, 0x76, 0x8f, 0x9d, 0x38, 0x53, 0xe3, 0xdd, 0x78, 0x5b, 0x90, 0x1d, 0x45, 0x8b, 0x65, 0x8d, 0x14, 0xdf, 0x59, 0x3b, 0x71, 0xf6, 0xd9, 0x6d, 0xdc, 0x11, 0xa4, 0xab, 0xa8, 0x58, 0xd6, 0x8a,
0x38, 0x58, 0x2b, 0xf0, 0x82, 0x41, 0x5a, 0x94, 0x03, 0xc8, 0x6b, 0x76, 0x65, 0x93, 0x1c, 0x56, 0x83, 0x55, 0x81, 0x0b, 0x06, 0xa9, 0x28, 0x07, 0x90, 0x6b, 0x5a, 0xd9, 0x24, 0x87, 0x6a, 0x02,
0x1d, 0x60, 0x11, 0xb7, 0xde, 0x99, 0x26, 0x69, 0xad, 0x3d, 0x33, 0xea, 0x6e, 0x1b, 0xf9, 0xc8, 0x14, 0x71, 0x9b, 0xee, 0x8e, 0x92, 0x51, 0xed, 0xdd, 0xd5, 0xec, 0xd8, 0xc8, 0x47, 0xce, 0x5c,
0x1b, 0xf0, 0x0a, 0x3c, 0x08, 0x27, 0x2e, 0x1c, 0x73, 0x41, 0xe2, 0x08, 0xc9, 0x0b, 0x70, 0xe7, 0xe0, 0x23, 0xf0, 0x41, 0x38, 0x71, 0xe1, 0xd8, 0x0b, 0x12, 0x47, 0x94, 0x7c, 0x01, 0xee, 0x5c,
0x82, 0xba, 0xe7, 0xdf, 0xe3, 0x58, 0x42, 0x8a, 0x90, 0x38, 0x24, 0x9e, 0xaa, 0xfa, 0xaa, 0xfc, 0xd0, 0xcc, 0xfe, 0xdf, 0xb5, 0x2d, 0x2a, 0x59, 0x3d, 0x24, 0xde, 0xf7, 0xde, 0xef, 0x3d, 0xff,
0xd5, 0xd7, 0x35, 0xd5, 0x86, 0xf7, 0xe3, 0x37, 0x17, 0x4f, 0xa8, 0x3f, 0xd7, 0x7f, 0x82, 0xf9, 0xe6, 0xf7, 0xde, 0xbc, 0x35, 0x7c, 0x18, 0xbe, 0xba, 0x7a, 0x44, 0xdd, 0xb9, 0xfa, 0x13, 0xcc,
0x91, 0x08, 0x62, 0x11, 0xa9, 0xe8, 0x89, 0xf9, 0x2f, 0x0b, 0xef, 0xd0, 0x38, 0xb0, 0x9d, 0x3b, 0x0d, 0x84, 0x17, 0x8a, 0x40, 0x06, 0x8f, 0xf4, 0xff, 0x28, 0xf7, 0x0e, 0xb5, 0x03, 0x5b, 0x99,
0xbc, 0x17, 0xd0, 0x21, 0xf4, 0xfb, 0xf1, 0xe4, 0x8c, 0x18, 0x1b, 0xbb, 0xd0, 0x8e, 0xe9, 0x7a, 0xc3, 0x79, 0x06, 0x1d, 0x42, 0x7f, 0x18, 0x4f, 0x2e, 0x88, 0xb6, 0xb1, 0x0d, 0xad, 0x90, 0xae,
0x1e, 0xd1, 0xc0, 0x45, 0x7d, 0x34, 0xe8, 0x90, 0xcc, 0xc4, 0x8f, 0xc0, 0x96, 0xfc, 0x22, 0xa4, 0xe7, 0x01, 0xf5, 0x6c, 0xd4, 0x47, 0x83, 0x0e, 0x49, 0x4d, 0xfc, 0x00, 0xac, 0x88, 0x5f, 0xf9,
0x6a, 0x29, 0x98, 0x6b, 0x99, 0x58, 0xe1, 0xf0, 0x3e, 0x05, 0x5c, 0xae, 0xf3, 0x8a, 0xab, 0xcb, 0x54, 0x2e, 0x05, 0xb3, 0x4d, 0x1d, 0xcb, 0x1d, 0xce, 0xe7, 0x80, 0x8b, 0x75, 0x5e, 0x70, 0x79,
0xd9, 0xae, 0x6a, 0xf7, 0xc1, 0xe2, 0x81, 0x29, 0x63, 0x13, 0x8b, 0x07, 0xde, 0x4f, 0x08, 0xec, 0x3d, 0xdb, 0x55, 0xed, 0x2e, 0x98, 0xdc, 0xd3, 0x65, 0x2c, 0x62, 0x72, 0xcf, 0xf9, 0x15, 0x81,
0x82, 0xc5, 0x11, 0xec, 0xc7, 0x82, 0xad, 0x66, 0x49, 0x9a, 0x4d, 0x52, 0x0b, 0x1f, 0xc3, 0x01, 0x95, 0xb3, 0x38, 0x81, 0xc3, 0x50, 0xb0, 0xd5, 0x2c, 0x4e, 0xb3, 0x48, 0x62, 0xe1, 0x53, 0x38,
0x0f, 0x58, 0xa8, 0xb8, 0x5a, 0xa7, 0x14, 0x72, 0x1b, 0x63, 0x68, 0x05, 0x54, 0x51, 0xb7, 0x69, 0xe2, 0x1e, 0xf3, 0x25, 0x97, 0xeb, 0x84, 0x42, 0x66, 0x63, 0x0c, 0x4d, 0x8f, 0x4a, 0x6a, 0x37,
0xfc, 0xe6, 0x19, 0x0f, 0x01, 0xfb, 0x4b, 0x21, 0x58, 0xa8, 0x08, 0xa3, 0xc1, 0x29, 0x5b, 0x4f, 0xb4, 0x5f, 0x3f, 0xe3, 0x21, 0x60, 0x77, 0x29, 0x04, 0xf3, 0x25, 0x61, 0xd4, 0x3b, 0x67, 0xeb,
0xa9, 0xbc, 0x74, 0x5b, 0x7d, 0x34, 0x68, 0x91, 0x2d, 0x11, 0xdd, 0xa3, 0xe2, 0x0b, 0x26, 0x15, 0x29, 0x8d, 0xae, 0xed, 0x66, 0x1f, 0x0d, 0x9a, 0x64, 0x43, 0x44, 0x9d, 0x51, 0xf2, 0x05, 0x8b,
0x5d, 0xc4, 0xee, 0x5e, 0x1f, 0x0d, 0x9a, 0xa4, 0x70, 0x78, 0x3f, 0x23, 0x68, 0x6b, 0x8e, 0x51, 0x24, 0x5d, 0x84, 0xf6, 0x41, 0x1f, 0x0d, 0x1a, 0x24, 0x77, 0x38, 0x3f, 0x99, 0xd0, 0x52, 0x1c,
0xa4, 0x2a, 0x4c, 0xd0, 0x06, 0x93, 0x77, 0xe1, 0x1e, 0x0b, 0x7d, 0xb1, 0x8e, 0x15, 0x8f, 0xc2, 0x83, 0x40, 0x96, 0x98, 0xa0, 0x0a, 0x93, 0xf7, 0xe1, 0x0e, 0xf3, 0x5d, 0xb1, 0x0e, 0x25, 0x0f,
0x53, 0x96, 0x51, 0xad, 0x3a, 0xb5, 0x36, 0x32, 0xa6, 0x3e, 0x9b, 0x05, 0x86, 0xb2, 0x4d, 0x32, 0xfc, 0x73, 0x96, 0x52, 0x2d, 0x3b, 0x95, 0x36, 0x51, 0x48, 0x5d, 0x36, 0xf3, 0x34, 0x65, 0x8b,
0x13, 0x3f, 0x86, 0x6e, 0x0a, 0x65, 0x41, 0xca, 0xce, 0x70, 0xee, 0x90, 0x9a, 0x5f, 0x63, 0x03, 0xa4, 0x26, 0x7e, 0x08, 0xdd, 0x04, 0xca, 0xbc, 0x84, 0x9d, 0xe6, 0xdc, 0x21, 0x35, 0xbf, 0xc2,
0x26, 0xf8, 0x8a, 0xea, 0xb2, 0xe7, 0xfe, 0x25, 0x5b, 0x30, 0x43, 0xdc, 0x26, 0x35, 0xbf, 0xf7, 0x7a, 0x4c, 0xf0, 0x15, 0x55, 0x65, 0x2f, 0xdd, 0x6b, 0xb6, 0x60, 0x9a, 0xb8, 0x45, 0x6a, 0xfe,
0x9b, 0x05, 0x87, 0xe3, 0xc9, 0xd9, 0x24, 0x0a, 0x15, 0x0b, 0xd5, 0xd7, 0x74, 0xbe, 0x64, 0xf8, 0x2d, 0x6a, 0x1c, 0xfe, 0x3f, 0x35, 0x5a, 0x55, 0x35, 0xfe, 0x34, 0xe1, 0x78, 0x3c, 0xb9, 0x98,
0x43, 0x68, 0x2f, 0x25, 0x13, 0xe3, 0x20, 0x91, 0xda, 0x19, 0xbd, 0x3d, 0x2c, 0xa6, 0x65, 0x3c, 0x04, 0xbe, 0x64, 0xbe, 0xfc, 0x96, 0xce, 0x97, 0x0c, 0x7f, 0x0c, 0xad, 0x65, 0xc4, 0xc4, 0xd8,
0x39, 0xfb, 0x2a, 0x09, 0x4e, 0x1b, 0x24, 0xc3, 0xe1, 0x13, 0x00, 0xfd, 0x48, 0xd8, 0x22, 0x5a, 0x8b, 0x1b, 0xd7, 0x1e, 0xbd, 0x3b, 0xcc, 0x67, 0x6f, 0x3c, 0xb9, 0xf8, 0x26, 0x0e, 0x4e, 0x0d,
0x25, 0x93, 0xe0, 0x8c, 0xdc, 0x7a, 0x56, 0x12, 0x9f, 0x36, 0x48, 0x09, 0x8d, 0xbf, 0x81, 0xb7, 0x92, 0xe2, 0xf0, 0x19, 0x80, 0x7a, 0x24, 0x6c, 0x11, 0xac, 0xe2, 0xb9, 0x6a, 0x8f, 0xec, 0x7a,
0xb4, 0xf5, 0x92, 0x89, 0x05, 0x97, 0x92, 0x47, 0xe1, 0xe4, 0x92, 0x86, 0x17, 0xcc, 0x28, 0xe0, 0x56, 0x1c, 0x9f, 0x1a, 0xa4, 0x80, 0xc6, 0xdf, 0xc1, 0x3b, 0xca, 0x7a, 0xce, 0xc4, 0x82, 0x47,
0x8c, 0xbc, 0x7a, 0x95, 0x4d, 0xe4, 0xb4, 0x41, 0xb6, 0x56, 0xc8, 0x58, 0xcd, 0xc2, 0x15, 0x57, 0x11, 0x0f, 0xfc, 0xc9, 0x35, 0xf5, 0xaf, 0x98, 0xd6, 0xb3, 0x3d, 0x72, 0xea, 0x55, 0xaa, 0xc8,
0xcc, 0xc8, 0xb5, 0x95, 0x55, 0x12, 0xcf, 0x58, 0x25, 0x16, 0xfe, 0x18, 0x0e, 0xb4, 0xf5, 0x45, 0xa9, 0x41, 0x36, 0x56, 0x48, 0x59, 0xcd, 0xfc, 0x15, 0x97, 0x4c, 0x8b, 0xbf, 0x91, 0x55, 0x1c,
0xc4, 0x43, 0x23, 0x9e, 0x33, 0x3a, 0xaa, 0x67, 0xea, 0xe8, 0xb4, 0x41, 0x72, 0xe4, 0xb3, 0x36, 0x4f, 0x59, 0xc5, 0x16, 0xfe, 0x14, 0x8e, 0x94, 0xf5, 0x55, 0xc0, 0x7d, 0xdd, 0x8a, 0xf6, 0xe8,
0xec, 0xad, 0xb4, 0x86, 0xde, 0x73, 0x33, 0x16, 0x9f, 0xeb, 0x81, 0x3b, 0x01, 0xa0, 0xfe, 0x3c, 0xa4, 0x9e, 0xa9, 0xa2, 0x53, 0x83, 0x64, 0xc8, 0x27, 0x2d, 0x38, 0x58, 0x29, 0x0d, 0x9d, 0xa7,
0x55, 0xd8, 0x45, 0xfd, 0xe6, 0xc0, 0x19, 0x1d, 0x57, 0x6b, 0x95, 0xe5, 0x27, 0x25, 0xb4, 0xf7, 0x7a, 0xc8, 0xbe, 0x54, 0xe3, 0x7b, 0x06, 0x40, 0xdd, 0x79, 0xa2, 0xb0, 0x8d, 0xfa, 0x8d, 0x41,
0x37, 0x82, 0x83, 0xf1, 0xe4, 0xec, 0x5c, 0x51, 0xc5, 0xf4, 0x0c, 0x89, 0x62, 0x30, 0x99, 0x34, 0x7b, 0x74, 0x5a, 0xae, 0x55, 0x94, 0x9f, 0x14, 0xd0, 0xce, 0xbf, 0x08, 0x8e, 0xc6, 0x93, 0x8b,
0xb5, 0x5a, 0xa4, 0xea, 0xc4, 0x4f, 0x93, 0xa6, 0x4d, 0x8a, 0x74, 0x2d, 0xf3, 0x75, 0x0f, 0xeb, 0x4b, 0x49, 0x25, 0x53, 0x13, 0x29, 0xf2, 0xc6, 0xb2, 0x48, 0xd7, 0x6a, 0x92, 0xb2, 0x13, 0x3f,
0xd4, 0x4d, 0x9c, 0x94, 0xa0, 0xf8, 0x04, 0xda, 0xdc, 0xf4, 0x2e, 0xdd, 0xa6, 0xc9, 0xea, 0x57, 0x8e, 0x0f, 0xad, 0x53, 0x22, 0xdb, 0xd4, 0x5f, 0x77, 0xbf, 0x4e, 0x5d, 0xc7, 0x49, 0x01, 0x8a,
0xb3, 0x0c, 0x6c, 0x98, 0xc8, 0x23, 0x9f, 0x87, 0x4a, 0xac, 0x49, 0x96, 0x70, 0xfc, 0x25, 0x74, 0xcf, 0xa0, 0xc5, 0xf5, 0xd9, 0x23, 0xbb, 0xa1, 0xb3, 0xfa, 0xe5, 0x2c, 0x0d, 0x1b, 0xc6, 0xf2,
0xca, 0x01, 0xdc, 0x85, 0xe6, 0x1b, 0xb6, 0x4e, 0xdf, 0x54, 0xfd, 0x88, 0x87, 0xa9, 0x32, 0xb7, 0x44, 0x4f, 0x7d, 0x29, 0xd6, 0x24, 0x4d, 0x38, 0xfd, 0x1a, 0x3a, 0xc5, 0x00, 0xee, 0x42, 0xe3,
0x0f, 0x47, 0x52, 0x80, 0x24, 0xb0, 0x13, 0xeb, 0x13, 0xe4, 0xfd, 0x89, 0xa0, 0x53, 0xa6, 0x7b, 0x15, 0x5b, 0x27, 0xf7, 0x5e, 0x3d, 0xe2, 0x61, 0xa2, 0xcc, 0xf6, 0xe1, 0x88, 0x0b, 0x90, 0x18,
0x07, 0x6f, 0xd8, 0x7b, 0xf0, 0x60, 0xf3, 0x7d, 0x49, 0xda, 0xed, 0x90, 0x7a, 0x00, 0x7f, 0x06, 0x76, 0x66, 0x7e, 0x86, 0x9c, 0x5f, 0x10, 0x74, 0x8a, 0x74, 0xf7, 0x70, 0x5f, 0xbf, 0x80, 0x76,
0x4e, 0x9c, 0x0f, 0x95, 0x34, 0x13, 0x74, 0x7f, 0xf4, 0xce, 0xae, 0x89, 0x94, 0xa4, 0x9c, 0x81, 0x98, 0x8d, 0x49, 0xa4, 0x67, 0xec, 0xee, 0xe8, 0xbd, 0x5d, 0x33, 0x16, 0x91, 0x62, 0x86, 0xf3,
0xfb, 0xe0, 0x70, 0x39, 0x89, 0xc2, 0xef, 0xb8, 0x58, 0xb0, 0xc0, 0x0c, 0xd2, 0x01, 0x29, 0xbb, 0x1b, 0x02, 0xc8, 0xef, 0xc0, 0x1e, 0x18, 0x7d, 0x00, 0xf7, 0xaa, 0xfb, 0x20, 0x6e, 0x40, 0x87,
0xf4, 0x02, 0x81, 0xe2, 0x9d, 0xfa, 0xdf, 0x75, 0xe8, 0xfd, 0x85, 0xe0, 0x5e, 0xe5, 0x00, 0xf1, 0xd4, 0x03, 0x55, 0xfe, 0xcd, 0x37, 0xe6, 0xff, 0x0f, 0x82, 0x3b, 0x25, 0xc1, 0xf1, 0x00, 0x8e,
0x00, 0x0e, 0xa9, 0xef, 0xb3, 0x58, 0xbd, 0x5c, 0xbe, 0x9e, 0x73, 0xff, 0x94, 0x65, 0x9d, 0x6c, 0xa9, 0xeb, 0xb2, 0x50, 0x3e, 0x5f, 0xbe, 0x9c, 0x73, 0xf7, 0x9c, 0xa5, 0x27, 0xa9, 0xba, 0x0b,
0xba, 0x4b, 0x4b, 0xad, 0x80, 0x5a, 0x95, 0xa5, 0x56, 0x60, 0xff, 0xe3, 0x83, 0xd3, 0xe7, 0x60, 0x2b, 0x2d, 0x87, 0x9a, 0xa5, 0x95, 0x96, 0x63, 0xdf, 0xee, 0xb1, 0x74, 0x1f, 0xf4, 0x71, 0x66,
0xda, 0x99, 0x05, 0xe9, 0xee, 0xcc, 0x6d, 0xef, 0x17, 0x04, 0x4e, 0x69, 0x01, 0xdc, 0xc1, 0x99, 0x5e, 0xb2, 0x39, 0x33, 0xdb, 0xf9, 0x1d, 0x41, 0xbb, 0x70, 0x61, 0xf7, 0xd0, 0xb3, 0x4c, 0xb2,
0xe5, 0x92, 0x9d, 0xe7, 0xb7, 0x69, 0xb3, 0x2c, 0x59, 0xee, 0xae, 0xf0, 0x6a, 0x55, 0x79, 0x6d, 0xcb, 0xec, 0x5d, 0xda, 0x28, 0x4a, 0x96, 0xb9, 0x4b, 0xbc, 0x9a, 0x65, 0x5e, 0x9b, 0x25, 0x3a,
0x97, 0x68, 0xef, 0x16, 0x89, 0x3c, 0x99, 0x9f, 0x5b, 0xba, 0x87, 0x77, 0xb5, 0xf1, 0x02, 0x0e, 0xd8, 0x22, 0x91, 0x13, 0x65, 0x7d, 0x4b, 0xf6, 0xe6, 0xae, 0x63, 0x3c, 0x83, 0xe3, 0x64, 0x2b,
0xd3, 0x2d, 0x43, 0x58, 0x3c, 0xa7, 0x7e, 0xbe, 0x23, 0x1e, 0x55, 0x35, 0x25, 0x15, 0x10, 0xd9, 0x10, 0x16, 0xce, 0xa9, 0x9b, 0xdd, 0xe9, 0x07, 0x65, 0x4d, 0x49, 0x09, 0x44, 0xaa, 0x49, 0xce,
0x4c, 0xf2, 0x7e, 0x40, 0xf0, 0xa0, 0x06, 0xbb, 0x03, 0x01, 0xb7, 0x5d, 0x8f, 0xcd, 0xed, 0xd7, 0x8f, 0x08, 0xee, 0xd5, 0x60, 0x7b, 0x10, 0x70, 0xd3, 0xcb, 0xb1, 0xb1, 0xf9, 0xe5, 0xe8, 0xac,
0xa3, 0xb7, 0x82, 0x87, 0xb7, 0x5c, 0x24, 0x3b, 0x89, 0x6c, 0x8c, 0x94, 0xf5, 0x6f, 0x47, 0xea, 0xe0, 0xfe, 0x96, 0xc5, 0xbf, 0x93, 0x48, 0x65, 0xa4, 0xcc, 0x37, 0x1d, 0xa9, 0x87, 0x8f, 0x01,
0xf1, 0x53, 0xc0, 0x75, 0x08, 0xb6, 0x61, 0x6f, 0x1c, 0x2c, 0x78, 0xd8, 0x6d, 0x60, 0x80, 0xfd, 0xd7, 0x21, 0xd8, 0x82, 0x83, 0xb1, 0xb7, 0xe0, 0x7e, 0xd7, 0xc0, 0x00, 0x87, 0x2f, 0x04, 0x97,
0x57, 0x82, 0x2b, 0x26, 0xba, 0x48, 0x3f, 0x6b, 0xbe, 0x4c, 0x74, 0xad, 0x67, 0x1f, 0xfc, 0x7a, 0x4c, 0x74, 0x91, 0x7a, 0x56, 0x7c, 0x99, 0xe8, 0x9a, 0x4f, 0x3e, 0xfa, 0xe3, 0xa6, 0x87, 0x5e,
0xdd, 0x43, 0x57, 0xd7, 0x3d, 0xf4, 0xc7, 0x75, 0x0f, 0xfd, 0x78, 0xd3, 0x6b, 0x5c, 0xdd, 0xf4, 0xdf, 0xf4, 0xd0, 0xdf, 0x37, 0x3d, 0xf4, 0xf3, 0x6d, 0xcf, 0x78, 0x7d, 0xdb, 0x33, 0xfe, 0xba,
0x1a, 0xbf, 0xdf, 0xf4, 0x1a, 0xdf, 0x1e, 0x6d, 0xff, 0x8d, 0xf7, 0x7a, 0xdf, 0x7c, 0x7c, 0xf4, 0xed, 0x19, 0xdf, 0x9f, 0x6c, 0xfe, 0x85, 0xf7, 0xf2, 0x50, 0x7f, 0x7c, 0xf2, 0x5f, 0x00, 0x00,
0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x93, 0x89, 0xed, 0xeb, 0x04, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0xd2, 0xee, 0x14, 0x02, 0x0a, 0x00, 0x00,
} }
func (m *RawACLRecord) Marshal() (dAtA []byte, err error) { func (m *RawACLRecord) Marshal() (dAtA []byte, err error) {
@ -1223,6 +1223,16 @@ func (m *ACLRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.Timestamp != 0 {
i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp))
i--
dAtA[i] = 0x38
}
if m.CurrentReadKeyHash != 0 {
i = encodeVarintAclrecord(dAtA, i, uint64(m.CurrentReadKeyHash))
i--
dAtA[i] = 0x30
}
if len(m.DerivationScheme) > 0 { if len(m.DerivationScheme) > 0 {
i -= len(m.DerivationScheme) i -= len(m.DerivationScheme)
copy(dAtA[i:], m.DerivationScheme) copy(dAtA[i:], m.DerivationScheme)
@ -1536,29 +1546,10 @@ func (m *ACLUserState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.IsConfirmed {
i--
if m.IsConfirmed {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x28
}
if m.Permissions != 0 { if m.Permissions != 0 {
i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions)) i = encodeVarintAclrecord(dAtA, i, uint64(m.Permissions))
i-- i--
dAtA[i] = 0x20 dAtA[i] = 0x18
}
if len(m.EncryptedReadKeys) > 0 {
for iNdEx := len(m.EncryptedReadKeys) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.EncryptedReadKeys[iNdEx])
copy(dAtA[i:], m.EncryptedReadKeys[iNdEx])
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx])))
i--
dAtA[i] = 0x1a
}
} }
if len(m.EncryptionKey) > 0 { if len(m.EncryptionKey) > 0 {
i -= len(m.EncryptionKey) i -= len(m.EncryptionKey)
@ -1967,6 +1958,12 @@ func (m *ACLRoot) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovAclrecord(uint64(l)) n += 1 + l + sovAclrecord(uint64(l))
} }
if m.CurrentReadKeyHash != 0 {
n += 1 + sovAclrecord(uint64(m.CurrentReadKeyHash))
}
if m.Timestamp != 0 {
n += 1 + sovAclrecord(uint64(m.Timestamp))
}
return n return n
} }
@ -2106,18 +2103,9 @@ func (m *ACLUserState) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovAclrecord(uint64(l)) n += 1 + l + sovAclrecord(uint64(l))
} }
if len(m.EncryptedReadKeys) > 0 {
for _, b := range m.EncryptedReadKeys {
l = len(b)
n += 1 + l + sovAclrecord(uint64(l))
}
}
if m.Permissions != 0 { if m.Permissions != 0 {
n += 1 + sovAclrecord(uint64(m.Permissions)) n += 1 + sovAclrecord(uint64(m.Permissions))
} }
if m.IsConfirmed {
n += 2
}
return n return n
} }
@ -2887,6 +2875,44 @@ func (m *ACLRoot) Unmarshal(dAtA []byte) error {
} }
m.DerivationScheme = string(dAtA[iNdEx:postIndex]) m.DerivationScheme = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType)
}
m.CurrentReadKeyHash = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentReadKeyHash |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType)
}
m.Timestamp = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Timestamp |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:]) skippy, err := skipAclrecord(dAtA[iNdEx:])
@ -3604,38 +3630,6 @@ func (m *ACLUserState) Unmarshal(dAtA []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
case 3: case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthAclrecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthAclrecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.EncryptedReadKeys = append(m.EncryptedReadKeys, make([]byte, postIndex-iNdEx))
copy(m.EncryptedReadKeys[len(m.EncryptedReadKeys)-1], dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType)
} }
@ -3654,26 +3648,6 @@ func (m *ACLUserState) Unmarshal(dAtA []byte) error {
break break
} }
} }
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field IsConfirmed", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAclrecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.IsConfirmed = bool(v != 0)
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipAclrecord(dAtA[iNdEx:]) skippy, err := skipAclrecord(dAtA[iNdEx:])

View File

@ -26,6 +26,8 @@ message ACLRoot {
string spaceId = 3; string spaceId = 3;
bytes encryptedReadKey = 4; bytes encryptedReadKey = 4;
string derivationScheme = 5; string derivationScheme = 5;
uint64 currentReadKeyHash = 6;
int64 timestamp = 7;
} }
message ACLContentValue { message ACLContentValue {
@ -51,9 +53,7 @@ message ACLState {
message ACLUserState { message ACLUserState {
bytes identity = 1; bytes identity = 1;
bytes encryptionKey = 2; bytes encryptionKey = 2;
repeated bytes encryptedReadKeys = 3; ACLUserPermissions permissions = 3;
ACLUserPermissions permissions = 4;
bool isConfirmed = 5;
} }
message ACLUserAdd { message ACLUserAdd {

View File

@ -1,18 +1,15 @@
package common package common
import ( import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
) )
type Keychain struct { type Keychain struct {
decoder keys.Decoder
keys map[string]signingkey.PubKey keys map[string]signingkey.PubKey
} }
func NewKeychain() *Keychain { func NewKeychain() *Keychain {
return &Keychain{ return &Keychain{
decoder: signingkey.NewEDPubKeyDecoder(),
keys: make(map[string]signingkey.PubKey), keys: make(map[string]signingkey.PubKey),
} }
} }
@ -21,7 +18,7 @@ func (k *Keychain) GetOrAdd(identity string) (signingkey.PubKey, error) {
if key, exists := k.keys[identity]; exists { if key, exists := k.keys[identity]; exists {
return key, nil return key, nil
} }
res, err := k.decoder.DecodeFromBytes([]byte(identity)) res, err := signingkey.NewSigningEd25519PubKeyFromBytes([]byte(identity))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -0,0 +1,10 @@
package list
import "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
func ACLReadKeyDerive(signKey []byte, encKey []byte) (*symmetric.Key, error) {
concBuf := make([]byte, 0, len(signKey)+len(encKey))
concBuf = append(concBuf, signKey...)
concBuf = append(concBuf, encKey...)
return symmetric.DeriveFromBytes(concBuf)
}

View File

@ -0,0 +1,95 @@
package list
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/gogo/protobuf/proto"
)
type ACLRecordBuilder interface {
ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error)
}
type aclRecordBuilder struct {
id string
keychain *common.Keychain
}
func newACLRecordBuilder(id string, keychain *common.Keychain) ACLRecordBuilder {
return &aclRecordBuilder{
id: id,
keychain: keychain,
}
}
func (a *aclRecordBuilder) ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error) {
rawRec := &aclrecordproto.RawACLRecord{}
err = proto.Unmarshal(rawIdRecord.Payload, rawRec)
if err != nil {
return
}
if rawIdRecord.Id == a.id {
aclRoot := &aclrecordproto.ACLRoot{}
err = proto.Unmarshal(rawRec.Payload, aclRoot)
if err != nil {
return
}
rec = &ACLRecord{
Id: rawIdRecord.Id,
CurrentReadKeyHash: aclRoot.CurrentReadKeyHash,
Timestamp: aclRoot.Timestamp,
Signature: rawRec.Signature,
Identity: aclRoot.Identity,
Model: aclRoot,
}
} else {
aclRecord := &aclrecordproto.ACLRecord{}
err = proto.Unmarshal(rawRec.Payload, aclRecord)
if err != nil {
return
}
rec = &ACLRecord{
Id: rawIdRecord.Id,
PrevId: aclRecord.PrevId,
CurrentReadKeyHash: aclRecord.CurrentReadKeyHash,
Timestamp: aclRecord.Timestamp,
Data: aclRecord.Data,
Signature: rawRec.Signature,
Identity: aclRecord.Identity,
}
}
err = verifyRaw(a.keychain, rawRec, rawIdRecord, rec.Identity)
return
}
func verifyRaw(
keychain *common.Keychain,
rawRec *aclrecordproto.RawACLRecord,
recWithId *aclrecordproto.RawACLRecordWithId,
identity []byte) (err error) {
identityKey, err := keychain.GetOrAdd(string(identity))
if err != nil {
return
}
// verifying signature
res, err := identityKey.Verify(rawRec.Payload, rawRec.Signature)
if err != nil {
return
}
if !res {
err = ErrInvalidSignature
return
}
// verifying ID
if !cid.VerifyCID(recWithId.Payload, recWithId.Id) {
err = ErrIncorrectCID
}
return
}

View File

@ -27,6 +27,7 @@ var ErrNoSuchRecord = errors.New("no such record")
var ErrInsufficientPermissions = errors.New("insufficient permissions") var ErrInsufficientPermissions = errors.New("insufficient permissions")
var ErrNoReadKey = errors.New("acl state doesn't have a read key") var ErrNoReadKey = errors.New("acl state doesn't have a read key")
var ErrInvalidSignature = errors.New("signature is invalid") var ErrInvalidSignature = errors.New("signature is invalid")
var ErrIncorrectRoot = errors.New("incorrect root")
type UserPermissionPair struct { type UserPermissionPair struct {
Identity string Identity string
@ -34,13 +35,13 @@ type UserPermissionPair struct {
} }
type ACLState struct { type ACLState struct {
id string
currentReadKeyHash uint64 currentReadKeyHash uint64
userReadKeys map[uint64]*symmetric.Key userReadKeys map[uint64]*symmetric.Key
userStates map[string]*aclrecordproto.ACLUserState userStates map[string]*aclrecordproto.ACLUserState
userInvites map[string]*aclrecordproto.ACLUserInvite userInvites map[string]*aclrecordproto.ACLUserInvite
signingPubKeyDecoder keys.Decoder
encryptionKey encryptionkey.PrivKey encryptionKey encryptionkey.PrivKey
signingKey signingkey.PrivKey
identity string identity string
permissionsAtRecord map[string][]UserPermissionPair permissionsAtRecord map[string][]UserPermissionPair
@ -48,30 +49,30 @@ type ACLState struct {
keychain *common.Keychain keychain *common.Keychain
} }
func newACLStateWithIdentity( func newACLStateWithKeys(
identity string, signingKey signingkey.PrivKey,
encryptionKey encryptionkey.PrivKey, encryptionKey encryptionkey.PrivKey) (*ACLState, error) {
decoder keys.Decoder) *ACLState { identity, err := signingKey.Raw()
if err != nil {
return nil, err
}
return &ACLState{ return &ACLState{
identity: identity, identity: string(identity),
signingKey: signingKey,
encryptionKey: encryptionKey, encryptionKey: encryptionKey,
userReadKeys: make(map[uint64]*symmetric.Key), userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclrecordproto.ACLUserState), userStates: make(map[string]*aclrecordproto.ACLUserState),
userInvites: make(map[string]*aclrecordproto.ACLUserInvite), userInvites: make(map[string]*aclrecordproto.ACLUserInvite),
signingPubKeyDecoder: decoder,
permissionsAtRecord: make(map[string][]UserPermissionPair), permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(), }, nil
}
} }
func newACLState(decoder keys.Decoder) *ACLState { func newACLState(decoder keys.Decoder) *ACLState {
return &ACLState{ return &ACLState{
signingPubKeyDecoder: decoder,
userReadKeys: make(map[uint64]*symmetric.Key), userReadKeys: make(map[uint64]*symmetric.Key),
userStates: make(map[string]*aclrecordproto.ACLUserState), userStates: make(map[string]*aclrecordproto.ACLUserState),
userInvites: make(map[string]*aclrecordproto.ACLUserInvite), userInvites: make(map[string]*aclrecordproto.ACLUserInvite),
permissionsAtRecord: make(map[string][]UserPermissionPair), permissionsAtRecord: make(map[string][]UserPermissionPair),
keychain: common.NewKeychain(),
} }
} }
@ -106,44 +107,31 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
return UserPermissionPair{}, ErrNoSuchUser return UserPermissionPair{}, ErrNoSuchUser
} }
func (st *ACLState) applyRecord(record *aclrecordproto.ACLRecord) (err error) { func (st *ACLState) applyRecord(record *ACLRecord) (err error) {
if record.Id == st.id {
root, ok := record.Model.(*aclrecordproto.ACLRoot)
if !ok {
return ErrIncorrectRoot
}
return st.applyRoot(root)
}
aclData := &aclrecordproto.ACLData{} aclData := &aclrecordproto.ACLData{}
if record.Model != nil {
aclData = record.Model.(*aclrecordproto.ACLData)
} else {
err = proto.Unmarshal(record.Data, aclData) err = proto.Unmarshal(record.Data, aclData)
if err != nil { if err != nil {
return return
} }
record.Model = aclData
}
err = st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity) err = st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity)
if err != nil { if err != nil {
return return
} }
st.currentReadKeyHash = record.CurrentReadKeyHash
return
}
func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
var (
change = recordWrapper.Content
aclData = &aclrecordproto.ACLData{}
)
if recordWrapper.Model != nil {
aclData = recordWrapper.Model.(*aclrecordproto.ACLData)
} else {
err = proto.Unmarshal(change.Data, aclData)
if err != nil {
return
}
recordWrapper.Model = aclData
}
err = st.applyChangeData(aclData, recordWrapper.Content.CurrentReadKeyHash, recordWrapper.Content.Identity)
if err != nil {
return
}
// getting all permissions for users at record // getting all permissions for users at record
var permissions []UserPermissionPair var permissions []UserPermissionPair
for _, state := range st.userStates { for _, state := range st.userStates {
@ -154,10 +142,61 @@ func (st *ACLState) applyChangeAndUpdate(recordWrapper *ACLRecord) (err error) {
permissions = append(permissions, permission) permissions = append(permissions, permission)
} }
st.permissionsAtRecord[recordWrapper.Id] = permissions st.permissionsAtRecord[record.Id] = permissions
return nil return nil
} }
func (st *ACLState) applyRoot(root *aclrecordproto.ACLRoot) (err error) {
if st.signingKey != nil && st.encryptionKey != nil {
err = st.saveReadKeyFromRoot(root)
if err != nil {
return
}
}
// adding user to the list
userState := &aclrecordproto.ACLUserState{
Identity: root.Identity,
EncryptionKey: root.EncryptionKey,
Permissions: aclrecordproto.ACLUserPermissions_Admin,
}
st.userStates[string(root.Identity)] = userState
return
}
func (st *ACLState) saveReadKeyFromRoot(root *aclrecordproto.ACLRoot) (err error) {
var readKey *symmetric.Key
if len(root.GetDerivationScheme()) != 0 {
var encPubKey []byte
encPubKey, err = st.encryptionKey.GetPublic().Raw()
if err != nil {
return
}
readKey, err = ACLReadKeyDerive([]byte(st.identity), encPubKey)
if err != nil {
return
}
} else {
readKey, _, err = st.decryptReadKeyAndHash(root.EncryptedReadKey)
if err != nil {
return
}
}
hasher := fnv.New64()
_, err = hasher.Write(readKey.Bytes())
if err != nil {
return
}
if hasher.Sum64() != root.CurrentReadKeyHash {
return ErrIncorrectRoot
}
st.currentReadKeyHash = root.CurrentReadKeyHash
st.userReadKeys[root.CurrentReadKeyHash] = readKey
return
}
func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uint64, identity []byte) (err error) { func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uint64, identity []byte) (err error) {
defer func() { defer func() {
if err != nil { if err != nil {
@ -166,11 +205,8 @@ func (st *ACLState) applyChangeData(changeData *aclrecordproto.ACLData, hash uin
st.currentReadKeyHash = hash st.currentReadKeyHash = hash
}() }()
// we can't check this for the user which is joining, because it will not be in our list if !st.isUserJoin(changeData) {
// the same is for the first change to be added // we check signature when we add this to the List, so no need to do it here
skipIdentityCheck := st.isUserJoin(changeData) || (st.currentReadKeyHash == 0 && st.isUserAdd(changeData, identity))
if !skipIdentityCheck {
// we check signature when we add this to the Tree, so no need to do it here
if _, exists := st.userStates[string(identity)]; !exists { if _, exists := st.userStates[string(identity)]; !exists {
err = ErrNoSuchUser err = ErrNoSuchUser
return return
@ -204,8 +240,6 @@ func (st *ACLState) applyChangeContent(ch *aclrecordproto.ACLContentValue) error
return st.applyUserInvite(ch.GetUserInvite()) return st.applyUserInvite(ch.GetUserInvite())
case ch.GetUserJoin() != nil: case ch.GetUserJoin() != nil:
return st.applyUserJoin(ch.GetUserJoin()) return st.applyUserJoin(ch.GetUserJoin())
case ch.GetUserConfirm() != nil:
return st.applyUserConfirm(ch.GetUserConfirm())
default: default:
return fmt.Errorf("unexpected change type: %v", ch) return fmt.Errorf("unexpected change type: %v", ch)
} }
@ -228,9 +262,9 @@ func (st *ACLState) applyUserInvite(ch *aclrecordproto.ACLUserInvite) error {
} }
func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error { func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error {
invite, exists := st.userInvites[ch.UserInviteId] invite, exists := st.userInvites[ch.InviteId]
if !exists { if !exists {
return fmt.Errorf("no such invite with id %s", ch.UserInviteId) return fmt.Errorf("no such invite with id %s", ch.InviteId)
} }
chIdentity := string(ch.Identity) chIdentity := string(ch.Identity)
@ -240,7 +274,7 @@ func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error {
// validating signature // validating signature
signature := ch.GetAcceptSignature() signature := ch.GetAcceptSignature()
verificationKey, err := st.signingPubKeyDecoder.DecodeFromBytes(invite.AcceptPublicKey) verificationKey, err := signingkey.NewSigningEd25519PubKeyFromBytes(invite.AcceptPublicKey)
if err != nil { if err != nil {
return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err) return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
} }
@ -269,9 +303,7 @@ func (st *ACLState) applyUserJoin(ch *aclrecordproto.ACLUserJoin) error {
userState := &aclrecordproto.ACLUserState{ userState := &aclrecordproto.ACLUserState{
Identity: ch.Identity, Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey, EncryptionKey: ch.EncryptionKey,
EncryptedReadKeys: ch.EncryptedReadKeys,
Permissions: invite.Permissions, Permissions: invite.Permissions,
IsConfirmed: true,
} }
st.userStates[chIdentity] = userState st.userStates[chIdentity] = userState
return nil return nil
@ -287,7 +319,6 @@ func (st *ACLState) applyUserAdd(ch *aclrecordproto.ACLUserAdd) error {
Identity: ch.Identity, Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey, EncryptionKey: ch.EncryptionKey,
Permissions: ch.Permissions, Permissions: ch.Permissions,
EncryptedReadKeys: ch.EncryptedReadKeys,
} }
if chIdentity == st.identity { if chIdentity == st.identity {
@ -318,12 +349,6 @@ func (st *ACLState) applyUserRemove(ch *aclrecordproto.ACLUserRemove) error {
for _, replace := range ch.ReadKeyReplaces { for _, replace := range ch.ReadKeyReplaces {
repIdentity := string(replace.Identity) repIdentity := string(replace.Identity)
userState, exists := st.userStates[repIdentity]
if !exists {
continue
}
userState.EncryptedReadKeys = append(userState.EncryptedReadKeys, replace.EncryptedReadKey)
// if this is our identity then we have to decrypt the key // if this is our identity then we have to decrypt the key
if repIdentity == st.identity { if repIdentity == st.identity {
key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey) key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey)
@ -338,17 +363,6 @@ func (st *ACLState) applyUserRemove(ch *aclrecordproto.ACLUserRemove) error {
return nil return nil
} }
func (st *ACLState) applyUserConfirm(ch *aclrecordproto.ACLUserConfirm) error {
chIdentity := string(ch.Identity)
state, exists := st.userStates[chIdentity]
if !exists {
return ErrNoSuchUser
}
state.IsConfirmed = true
return nil
}
func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) { func (st *ACLState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) {
decrypted, err := st.encryptionKey.Decrypt(msg) decrypted, err := st.encryptionKey.Decrypt(msg)
if err != nil { if err != nil {

View File

@ -4,19 +4,20 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey"
) )
type aclStateBuilder struct { type aclStateBuilder struct {
identity string signPrivKey signingkey.PrivKey
key encryptionkey.PrivKey encPrivKey encryptionkey.PrivKey
decoder keys.Decoder decoder keys.Decoder
} }
func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder { func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder {
return &aclStateBuilder{ return &aclStateBuilder{
decoder: decoder, decoder: decoder,
identity: string(accountData.Identity), signPrivKey: accountData.SignKey,
key: accountData.EncKey, encPrivKey: accountData.EncKey,
} }
} }
@ -26,19 +27,17 @@ func newACLStateBuilder(decoder keys.Decoder) *aclStateBuilder {
} }
} }
func (sb *aclStateBuilder) Build(records []*ACLRecord) (*ACLState, error) { func (sb *aclStateBuilder) Build(records []*ACLRecord) (state *ACLState, err error) {
var ( if sb.encPrivKey != nil && sb.signPrivKey != nil {
err error state, err = newACLStateWithKeys(sb.signPrivKey, sb.encPrivKey)
state *ACLState if err != nil {
) return
}
if sb.key != nil {
state = newACLStateWithIdentity(sb.identity, sb.key, sb.decoder)
} else { } else {
state = newACLState(sb.decoder) state = newACLState(sb.decoder)
} }
for _, rec := range records { for _, rec := range records {
err = state.applyChangeAndUpdate(rec) err = state.applyRecord(rec)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,131 +0,0 @@
package list
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric"
"github.com/gogo/protobuf/proto"
"hash/fnv"
"time"
)
type MarshalledChange = []byte
type ACLChangeBuilder interface {
UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error
AddId(id string) // TODO: this is only for testing
}
type aclChangeBuilder struct {
aclState *ACLState
list ACLList
acc *account.AccountData
aclData *aclpb.ACLData
id string
readKey *symmetric.Key
readKeyHash uint64
}
func newACLChangeBuilder() *aclChangeBuilder {
return &aclChangeBuilder{}
}
func (c *aclChangeBuilder) Init(state *ACLState, list ACLList, acc *account.AccountData) {
c.aclState = state
c.list = list
c.acc = acc
c.aclData = &aclpb.ACLData{}
// setting read key for further encryption etc
if state.currentReadKeyHash == 0 {
c.readKey, _ = symmetric.NewRandom()
hasher := fnv.New64()
hasher.Write(c.readKey.Bytes())
c.readKeyHash = hasher.Sum64()
} else {
c.readKey = c.aclState.userReadKeys[c.aclState.currentReadKeyHash]
c.readKeyHash = c.aclState.currentReadKeyHash
}
}
func (c *aclChangeBuilder) AddId(id string) {
c.id = id
}
func (c *aclChangeBuilder) UserAdd(identity string, encryptionKey encryptionkey.PubKey, permissions aclpb.ACLUserPermissions) error {
var allKeys []*symmetric.Key
if c.aclState.currentReadKeyHash != 0 {
for _, key := range c.aclState.userReadKeys {
allKeys = append(allKeys, key)
}
} else {
allKeys = append(allKeys, c.readKey)
}
var encryptedKeys [][]byte
for _, k := range allKeys {
res, err := encryptionKey.Encrypt(k.Bytes())
if err != nil {
return err
}
encryptedKeys = append(encryptedKeys, res)
}
rawKey, err := encryptionKey.Raw()
if err != nil {
return err
}
ch := &aclpb.ACLContentValue{
Value: &aclpb.ACLContentValue_UserAdd{
UserAdd: &aclpb.ACLUserAdd{
Identity: []byte(identity),
EncryptionKey: rawKey,
EncryptedReadKeys: encryptedKeys,
Permissions: permissions,
},
},
}
c.aclData.AclContent = append(c.aclData.AclContent, ch)
return nil
}
func (c *aclChangeBuilder) BuildAndApply() (*ACLRecord, []byte, error) {
aclRecord := &aclpb.ACLRecord{
PrevId: c.list.Head().Id,
CurrentReadKeyHash: c.readKeyHash,
Timestamp: int64(time.Now().Nanosecond()),
Identity: c.acc.Identity,
}
marshalledData, err := proto.Marshal(c.aclData)
if err != nil {
return nil, nil, err
}
aclRecord.Data = marshalledData
err = c.aclState.applyRecord(aclRecord)
if err != nil {
return nil, nil, err
}
fullMarshalledChange, err := proto.Marshal(aclRecord)
if err != nil {
return nil, nil, err
}
signature, err := c.acc.SignKey.Sign(fullMarshalledChange)
if err != nil {
return nil, nil, err
}
id, err := cid.NewCIDFromBytes(fullMarshalledChange)
if err != nil {
return nil, nil, err
}
ch := NewRecord(id, aclRecord)
ch.Model = c.aclData
ch.Sign = signature
return ch, fullMarshalledChange, nil
}

View File

@ -5,10 +5,9 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto/aclpb" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common"
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys"
"sync" "sync"
) )
@ -26,7 +25,7 @@ type RWLocker interface {
type ACLList interface { type ACLList interface {
RWLocker RWLocker
ID() string ID() string
Header() *aclpb.ACLHeader Root() *aclrecordproto.ACLRoot
Records() []*ACLRecord Records() []*ACLRecord
ACLState() *ACLState ACLState() *ACLState
IsAfter(first string, second string) (bool, error) IsAfter(first string, second string) (bool, error)
@ -38,7 +37,7 @@ type ACLList interface {
} }
type aclList struct { type aclList struct {
header *aclpb.ACLHeader root *aclrecordproto.ACLRoot
records []*ACLRecord records []*ACLRecord
indexes map[string]int indexes map[string]int
id string id string
@ -51,52 +50,50 @@ type aclList struct {
} }
func BuildACLListWithIdentity(acc *account.AccountData, storage storage.ListStorage) (ACLList, error) { func BuildACLListWithIdentity(acc *account.AccountData, storage storage.ListStorage) (ACLList, error) {
id, err := storage.ID()
if err != nil {
return nil, err
}
builder := newACLStateBuilderWithIdentity(acc.Decoder, acc) builder := newACLStateBuilderWithIdentity(acc.Decoder, acc)
return buildWithACLStateBuilder(builder, storage) return build(id, builder, newACLRecordBuilder(id, common.NewKeychain()), storage)
} }
func BuildACLList(decoder keys.Decoder, storage storage.ListStorage) (ACLList, error) { func BuildACLList(decoder keys.Decoder, storage storage.ListStorage) (ACLList, error) {
return buildWithACLStateBuilder(newACLStateBuilder(decoder), storage)
}
func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStorage) (list ACLList, err error) {
header, err := storage.Root()
if err != nil {
return
}
id, err := storage.ID() id, err := storage.ID()
if err != nil { if err != nil {
return return nil, err
}
return build(id, newACLStateBuilder(decoder), newACLRecordBuilder(id, common.NewKeychain()), storage)
} }
rawRecord, err := storage.Head() func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder, storage storage.ListStorage) (list ACLList, err error) {
rootWithId, err := storage.Root()
if err != nil {
return
}
aclRecRoot, err := recBuilder.ConvertFromRaw(rootWithId)
if err != nil { if err != nil {
return return
} }
keychain := common.NewKeychain() rawRecordWithId, err := storage.Head()
record, err := NewFromRawRecord(rawRecord)
if err != nil { if err != nil {
return return
} }
err = verifyRecord(keychain, rawRecord, record)
record, err := recBuilder.ConvertFromRaw(rawRecordWithId)
if err != nil { if err != nil {
return return
} }
records := []*ACLRecord{record} records := []*ACLRecord{record}
for record.Content.PrevId != "" { for record.PrevId != "" {
rawRecord, err = storage.GetRawRecord(context.Background(), record.Content.PrevId) rawRecordWithId, err = storage.GetRawRecord(context.Background(), record.PrevId)
if err != nil { if err != nil {
return return
} }
record, err = NewFromRawRecord(rawRecord) record, err = recBuilder.ConvertFromRaw(rawRecordWithId)
if err != nil {
return
}
err = verifyRecord(keychain, rawRecord, record)
if err != nil { if err != nil {
return return
} }
@ -114,16 +111,16 @@ func buildWithACLStateBuilder(builder *aclStateBuilder, storage storage.ListStor
indexes[records[len(records)/2].Id] = len(records) / 2 indexes[records[len(records)/2].Id] = len(records) / 2
} }
state, err := builder.Build(records) state, err := stateBuilder.Build(records)
if err != nil { if err != nil {
return return
} }
list = &aclList{ list = &aclList{
header: header, root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
records: records, records: records,
indexes: indexes, indexes: indexes,
builder: builder, builder: stateBuilder,
aclState: state, aclState: state,
id: id, id: id,
RWMutex: sync.RWMutex{}, RWMutex: sync.RWMutex{},
@ -139,8 +136,8 @@ func (a *aclList) ID() string {
return a.id return a.id
} }
func (a *aclList) Header() *aclpb.ACLHeader { func (a *aclList) Root() *aclrecordproto.ACLRoot {
return a.header return a.root
} }
func (a *aclList) ACLState() *ACLState { func (a *aclList) ACLState() *ACLState {
@ -191,26 +188,3 @@ func (a *aclList) IterateFrom(startId string, iterFunc IterFunc) {
func (a *aclList) Close() (err error) { func (a *aclList) Close() (err error) {
return nil return nil
} }
func verifyRecord(keychain *common.Keychain, rawRecord *aclpb.RawACLRecord, record *ACLRecord) (err error) {
identityKey, err := keychain.GetOrAdd(record.Identity)
if err != nil {
return
}
// verifying signature
res, err := identityKey.Verify(rawRecord.Payload, rawRecord.Signature)
if err != nil {
return
}
if !res {
err = ErrInvalidSignature
return
}
// verifying ID
if !cid.VerifyCID(rawRecord.Payload, rawRecord.Id) {
err = ErrIncorrectCID
}
return
}

View File

@ -1,65 +1,12 @@
package list package list
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto"
"github.com/gogo/protobuf/proto"
)
type ACLRecord struct { type ACLRecord struct {
Id string Id string
Content *aclrecordproto.ACLRecord PrevId string
Identity string CurrentReadKeyHash uint64
Timestamp int64
Data []byte
Identity []byte
Model interface{} Model interface{}
Sign []byte Signature []byte
} }
func NewRecord(id string, aclRecord *aclrecordproto.ACLRecord) *ACLRecord {
return &ACLRecord{
Id: id,
Content: aclRecord,
Identity: string(aclRecord.Identity),
}
}
func NewFromRawRecord(rawRecWithId *aclrecordproto.RawACLRecordWithId) (aclRec *ACLRecord, err error) {
rawRec := &aclrecordproto.RawACLRecord{}
err = proto.Unmarshal(rawRecWithId.Payload, rawRec)
if err != nil {
return
}
protoAclRec := &aclrecordproto.ACLRecord{}
err = proto.Unmarshal(rawRec.Payload, protoAclRec)
if err != nil {
return
}
return &ACLRecord{
Id: rawRecWithId.Id,
Content: protoAclRec,
Sign: rawRec.Signature,
Identity: string(protoAclRec.Identity),
}, nil
}
func NewFromRawRoot(rawRecWithId *aclrecordproto.RawACLRecordWithId) (aclRec *ACLRecord, err error) {
rawRec := &aclrecordproto.RawACLRecord{}
err = proto.Unmarshal(rawRecWithId.Payload, rawRec)
if err != nil {
return
}
protoAclRec := &aclrecordproto.ACLRecord{}
err = proto.Unmarshal(rawRec.Payload, protoAclRec)
if err != nil {
return
}
return &ACLRecord{
Id: rawRecWithId.Id,
Content: protoAclRec,
Sign: rawRec.Signature,
Identity: string(protoAclRec.Identity),
}, nil
}

View File

@ -5,6 +5,7 @@ import (
"crypto/cipher" "crypto/cipher"
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"github.com/minio/sha256-simd"
mbase "github.com/multiformats/go-multibase" mbase "github.com/multiformats/go-multibase"
) )
@ -21,6 +22,12 @@ type Key struct {
raw []byte raw []byte
} }
func DeriveFromBytes(bytes []byte) (*Key, error) {
bArray := sha256.Sum256(bytes)
bSlice := bArray[:]
return FromBytes(bSlice)
}
func (k *Key) Equals(otherKey *Key) bool { func (k *Key) Equals(otherKey *Key) bool {
otherRaw := otherKey.raw otherRaw := otherKey.raw
keyRaw := k.raw keyRaw := k.raw