Import acl document from the start
This commit is contained in:
parent
0efa617075
commit
1ab430d088
28
etc/acl.yml
Normal file
28
etc/acl.yml
Normal file
@ -0,0 +1,28 @@
|
||||
records:
|
||||
- identity: A
|
||||
aclChanges:
|
||||
- userAdd:
|
||||
identity: A
|
||||
permission: admin
|
||||
encryptionKey: key.Enc.A
|
||||
encryptedReadKeys: [key.Read.1]
|
||||
- userAdd:
|
||||
identity: B
|
||||
permission: admin
|
||||
encryptionKey: key.Enc.B
|
||||
encryptedReadKeys: [key.Read.1]
|
||||
readKey: key.Read.1
|
||||
keys:
|
||||
Enc:
|
||||
- name: A
|
||||
value: JgG4CcCbae1qEpe7mKpBzsHjZhXUmDSNVNX2B1gxFZsJyMX4V6kBQUott9zRWyeXaW1ZmpzuxDXnwSQpAnNurhXyGa9iQaAPqzY9A9VWBPD33Yy1eW7TRuVemzToh8jJQKQKnZNbF8ucTWV9qahusKzyvN8uyhrqoW2tAPfA9S3E3ognCuqbLSW6yjE2rBKayvyS1BVwzjSd6FZK4DDyjfU3pbEVjut3wytGEAn9af6sNMmyCnf2MX5vLovWs9rU8av61wD4z7HTsXyGFx4K75N4Go249Hpe9SKAT6HxhRc3yvj63krPLiQV5yMuH2UeMUXBDekUQyNmBEdn9wrur7mLqB67Bc6tcc2PP8XApBCdWJHvHjN4FktSpaG5vbCqoZbLD1oCbk36q2x9s6XM8pydVqD1J9P3nTbfgMb5pJCTFjNtgKeuKv6wjfJeA9jF1VhcJQisfsahgv9MvZ9M8FJpZTq1zKUhYDCRnZxUkraoMS5yNNVdDzaUckKEDthqik7BMWCWT79vq7uVgMwEvGwGi76gtoMg1159bbPMLZ4bdPVfhH2S9QjPrzQfwZSrzB2YeVPjWpaXDeLDity5H8n1NK2oniAQR6gE71n81neSptsuhV6o6QpQ89AU8y57XmEsou4VEryn8vUxBHhULLxrLNUouxyWamCeFiDjk5cSN6koQsf9BYKSNTPFTrwjTKForDokMhcPdMtFktKwjv7u9UEGcY4MKvNzZZkc77gHiP8bqVtdNNoLpTFUC5SZ9i7bKdHvK12HpSy7yzzPeMXJ9UwhLxkok1g81ngTbN1yxRhvYXyHZFtguCR9kvGojDjka91MTBtk551qDw9eCn2xZT9U8jqzBCjdpvSg3mRWKMPnYAGB7m7u1ye165wyGFvzcHAx3vtXjxAqLUeKYZCjv2m6V9D2Y4qH1TQNddWqH14T1JVMis971UCH9Ddpj6a3387oUnufD1P6HZN2ieJCvptrmbGVvxJYYSvmVf1dkwbtqurDRNWD7TJ7gf6iqSP549C9bxP4GpLt3ygjHmMtcuUzstBuztvunJUnQhfnJxqU6LjRdsFzm53wGWgXNxab7ZvQcPyLwsevn1b98FGPnVpS5iY4LjmqW4ugrC6HgrbsjrXiKzR1yZKhLQkCbLzPoaHb8iB5iBnCr7d4yf5CtfpFRqgoqMFdK5LNZYmDX4HzUKN6A7wC3gGiSRFTLcgGZeSMkB5Pa61CZBU7WCQgFxykycE9HRA7PiQa496GWDCV15teToCpFRsAa6jDmR1MGXPeLRqQgve49VXnQN5FL7c1VuEv5SWjeTuCnMB47DJKBaP7eKJNKgLwETALzSCMF3nRiRgeb15kfoS4BbrJ5yupjrvwmbmvNg1AYFFS5sYNWft7K8v87wQvBakRtGP71Kp8NX77XFtu6xdB7sR6jpfC6qJPyB9akWNXgCrWy9kE4ih42gwAZdUugNZ9YtEsgRM3pwb6qJhkAPyEJtrxrja859PCAgqPSQiPQN33PaMkgQ6HJknu8CrjKRiXAycZ16KLUkHV64TNhEjPTcX1a7rqpD131AYMWX8d7CCdc9Ys7RUb6BwguuNSh8rJK3x4AkMDSUsaE8ynKvpC7RXZpJ9Nxfhd
|
||||
- name: B
|
||||
value: JgG4CcCbae1qEpe7mKXzp7m5hNc56SSyZd9DwUaEStKJrq7RToAC2Vgd3i6hKRwa58zCWeN6Wjc3o6qrdKPEPRvcyEPysamajVo5mdQiUgWAmr97pGEsyjuRjQoC2GY2LvLiEQxEgwFgJxKGMHMiaWMtDfxCDUaDEm4bu5RdMhqRZekAWho6c3WoEeruSr14iX1TrocFNfBkBY7CjEw8kcywXCTNgtvhb2Qiwgj5AxEF4wyw4bzaNA9ctXb1hoHPFVMu6C51pkFY7jUD9zwyH3ukgnAewkGAcPNbKmaTAtMosKRVaAN97mAwXh2VRt1hWmRvVk7r76EjnVKhD4vbsKZc56RVcHTVWRVdhU7FGyPsiE5rSQAz1JQGYzxnZpX7EG77CyrmUGyfueVfRHhwY2oq8A4uQCRaQxSaJHYLowjXSxh8DQ2V6MTqyzti32C27utBYdHzLVCJSGkmdzGwrFcHqsq7nLDxmvJVErPvyReixEe8kFmqopJ3e6LLm8WdYw9K6JYBjXnEfwPzm7Von9sf3dcaGDUHYfttMyeke7fAXJkvPRje69hYVyzdQGAauuojzGkkvQWCSMK1KCMNMznRaPDCNvofrQhYrub24WhmwpKhorufdfW8Cb4T6reBDCtaWVsbuinjtL6F6Sui5aYHJFLJ6e4pPewr1P4EuZYRbMBZwN5KvDLhTGLBuBnaTqUUdF6bj2U22NoRYMogiHiftqKqiexKNDXX1Zg9RQEvxgjuVo6SBW42mVEA8agrLhruRqCmiduJxVrfqLNGeYXHXrcmMEgW7uosJbPXvTcfRvdFWS1ov7oSALvj6vhDQ28Yi9D2ETNdNsfVWAFQuwvPpW7CHQGXTitprVbqH8JYxNZuGygcLmr5efbB22Vzu4ntd1HoraQpG12qeDEUA7tXYUpoYyuSdWwKPjSAMtaQcCSfVrhKQHQuKJargrVrez8vjWuwLfvSucV7ZHe7gjqvYgULdE1ubRCRSd7DuLjEN2Vd6obzV2c3MRet7ZSf4Sp88WM5AuTyW7BjArBc4S3gUQ8rYaiZ8Tu7NCxkEzbFwWRaemZkwfvcsX3XxqjyF37tFSGkEqE5kuBvpZW72675LkDffj7kH1zA8yE6dVujJjWsNYVFJWndUtz5Vy2KCdZAbBgq19q4AtsxWPodU2N3yZXzFAFAzTrxS6V4P7Scpdau1avgRvHLcBQPunA37xaYMy8YMifJwtmRY25mnAQwZAk3eANk7tXwZd58SDnciLNvARJvwKzTQBXcshkwyy52SX8XmXDJsPnRLaHmiYBJ63Yzr5XpZuuAtxb9qrWG2NHCNxfomHokWacV1hjZPPd6ZxT1FuRozB6Qt2NLcyqY7bnTcQJb1jPUaTAGXXCR8WVmmmYo2fDQe8CdBmgyPvbzNTEJUyScBz4RdycB5PZap4SurJCWtHbuMyQbQUB6jJgURDstfXS5Akfe4oruNq9rnYcNtnsDJPtrhXHBqzDizmf1BDxR5FB2RCxzCgeAfg8WQ1Ug9PVAGTzob6ZqCrGXzWXEUniZnf1vjr7QhGKBYXEX9SWDoSMUpP4FreVDTnx15ijRZTV3p8xG5fE9e36TnugRVvTyq7XzmyPBjW2r66f1bior
|
||||
Sign:
|
||||
- name: A
|
||||
value: 3id6ddLcoNoe9rDgGM88ET8T6TnvHm5GFqFdN6kBzn7Q8d6VUGgjeT59CNWFiaofdeRnHBvX2A5ZacMXvfwaYEFuCbug
|
||||
- name: B
|
||||
value: 3iiLPj6wMUQpPwTBNZcUgkbXub1jumg4AEV9LfMyFHZVc84GLyAjVbVvH6EAGhcNrxRxL82aW4BimhDZCpLsRCqx5vwj
|
||||
Read:
|
||||
- name: 1
|
||||
value: generated
|
||||
15
etc/path.go
Normal file
15
etc/path.go
Normal file
@ -0,0 +1,15 @@
|
||||
package etc
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
_, b, _, _ = runtime.Caller(0)
|
||||
basepath = filepath.Dir(b)
|
||||
)
|
||||
|
||||
func Path() string {
|
||||
return basepath
|
||||
}
|
||||
@ -91,6 +91,17 @@ type inMemoryStorageProvider struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func (i *inMemoryStorageProvider) AddStorage(id string, st Storage) error {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
if _, exists := i.objects[id]; exists {
|
||||
return fmt.Errorf("storage already exists")
|
||||
}
|
||||
|
||||
i.objects[id] = st
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *inMemoryStorageProvider) Storage(id string) (Storage, error) {
|
||||
i.RLock()
|
||||
defer i.RUnlock()
|
||||
|
||||
@ -9,5 +9,6 @@ var ErrUnknownTreeId = errors.New("tree does not exist")
|
||||
|
||||
type Provider interface {
|
||||
Storage(id string) (Storage, error)
|
||||
AddStorage(id string, st Storage) error
|
||||
CreateTreeStorage(treeId string, header *aclpb.Header, changes []*aclpb.RawChange) (TreeStorage, error)
|
||||
}
|
||||
|
||||
@ -54,11 +54,23 @@ func (k *Keychain) AddEncryptionKey(key *Key) {
|
||||
if _, exists := k.EncryptionKeys[key.Name]; exists {
|
||||
return
|
||||
}
|
||||
newPrivKey, _, err := encryptionkey.GenerateRandomRSAKeyPair(2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
var (
|
||||
newPrivKey encryptionkey.PrivKey
|
||||
err error
|
||||
)
|
||||
if key.Value == "generated" {
|
||||
newPrivKey, _, err = encryptionkey.GenerateRandomRSAKeyPair(2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
decoder := encryptionkey.NewRSAPrivKeyDecoder()
|
||||
privKey, err := decoder.DecodeFromString(key.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newPrivKey = privKey.(encryptionkey.PrivKey)
|
||||
}
|
||||
|
||||
k.EncryptionKeys[key.Name] = newPrivKey
|
||||
}
|
||||
|
||||
@ -66,9 +78,24 @@ func (k *Keychain) AddSigningKey(key *Key) {
|
||||
if _, exists := k.SigningKeys[key.Name]; exists {
|
||||
return
|
||||
}
|
||||
newPrivKey, pubKey, err := signingkey.GenerateRandomEd25519KeyPair()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
var (
|
||||
newPrivKey signingkey.PrivKey
|
||||
pubKey signingkey.PubKey
|
||||
err error
|
||||
)
|
||||
if key.Value == "generated" {
|
||||
newPrivKey, pubKey, err = signingkey.GenerateRandomEd25519KeyPair()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
decoder := signingkey.NewEDPrivKeyDecoder()
|
||||
privKey, err := decoder.DecodeFromString(key.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newPrivKey = privKey.(signingkey.PrivKey)
|
||||
pubKey = newPrivKey.GetPublic()
|
||||
}
|
||||
|
||||
k.SigningKeys[key.Name] = newPrivKey
|
||||
|
||||
@ -154,8 +154,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclpb.ACL
|
||||
case ch.UserAdd != nil:
|
||||
add := ch.UserAdd
|
||||
|
||||
encKey := t.keychain.
|
||||
GetKey(add.EncryptionKey).(encryptionkey.PrivKey)
|
||||
encKey := t.keychain.GetKey(add.EncryptionKey).(encryptionkey.PrivKey)
|
||||
rawKey, _ := encKey.GetPublic().Raw()
|
||||
|
||||
convCh = &aclpb.ACLChangeACLContentValue{
|
||||
|
||||
@ -58,7 +58,7 @@ func (s *service) Name() (name string) {
|
||||
}
|
||||
|
||||
func (s *service) Run(ctx context.Context) (err error) {
|
||||
return s.importACLList(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) Close(ctx context.Context) (err error) {
|
||||
@ -121,10 +121,6 @@ func (s *service) UpdateDocumentTree(ctx context.Context, id, text string) (err
|
||||
}, header, id))
|
||||
}
|
||||
|
||||
func (s *service) importACLList(ctx context.Context) (err error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (s *service) CreateDocumentTree(ctx context.Context, aclListId string, text string) (id string, err error) {
|
||||
acc := s.account.Account()
|
||||
var (
|
||||
|
||||
@ -2,13 +2,22 @@ package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/etc"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/list"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/acllistbuilder"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/account"
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/service/node"
|
||||
)
|
||||
|
||||
var CName = "storage"
|
||||
|
||||
var log = logger.NewNamed("storage").Sugar()
|
||||
|
||||
type Service interface {
|
||||
storage.Provider
|
||||
}
|
||||
@ -23,13 +32,18 @@ type service struct {
|
||||
|
||||
func (s *service) Init(ctx context.Context, a *app.App) (err error) {
|
||||
s.storageProvider = storage.NewInMemoryTreeStorageProvider()
|
||||
return nil
|
||||
// importing hardcoded acl list, check that the keys there are correct
|
||||
return s.importACLList(a)
|
||||
}
|
||||
|
||||
func (s *service) Storage(treeId string) (storage.Storage, error) {
|
||||
return s.storageProvider.Storage(treeId)
|
||||
}
|
||||
|
||||
func (s *service) AddStorage(id string, st storage.Storage) error {
|
||||
return s.storageProvider.AddStorage(id, st)
|
||||
}
|
||||
|
||||
func (s *service) CreateTreeStorage(treeId string, header *aclpb.Header, changes []*aclpb.RawChange) (storage.TreeStorage, error) {
|
||||
return s.storageProvider.CreateTreeStorage(treeId, header, changes)
|
||||
}
|
||||
@ -45,3 +59,51 @@ func (s *service) Run(ctx context.Context) (err error) {
|
||||
func (s service) Close(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *service) importACLList(a *app.App) (err error) {
|
||||
path := fmt.Sprintf("%s/%s", etc.Path(), "acl.yml")
|
||||
st, err := acllistbuilder.NewACLListStorageBuilderFromFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := st.ID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// checking that acl list contains all the needed permissions for all our nodes
|
||||
err = s.checkActualNodesPermissions(st, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("imported ACLList with id %s", id)
|
||||
return s.storageProvider.AddStorage(id, st)
|
||||
}
|
||||
|
||||
func (s *service) checkActualNodesPermissions(st *acllistbuilder.ACLListStorageBuilder, a *app.App) error {
|
||||
nodes := a.MustComponent(node.CName).(node.Service)
|
||||
acc := a.MustComponent(account.CName).(account.Service)
|
||||
|
||||
aclList, err := list.BuildACLListWithIdentity(acc.Account(), st)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
state := aclList.ACLState()
|
||||
|
||||
// checking own state
|
||||
if state.GetUserStates()[acc.Account().Identity].Permissions != aclpb.ACLChange_Admin {
|
||||
return fmt.Errorf("own node with signing key %s should be admin", acc.Account().Identity)
|
||||
}
|
||||
|
||||
// checking other nodes' states
|
||||
for _, n := range nodes.Nodes() {
|
||||
if state.GetUserStates()[n.SigningKeyString].Permissions != aclpb.ACLChange_Admin {
|
||||
return fmt.Errorf("other node with signing key %s should be admin", n.SigningKeyString)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package syncproto
|
||||
|
||||
import "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/storage/treepb"
|
||||
import (
|
||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb"
|
||||
)
|
||||
|
||||
func WrapHeadUpdate(update *SyncHeadUpdate, header *treepb.TreeHeader, treeId string) *Sync {
|
||||
func WrapHeadUpdate(update *SyncHeadUpdate, header *aclpb.Header, treeId string) *Sync {
|
||||
return &Sync{
|
||||
Message: &SyncContentValue{
|
||||
Value: &SyncContentValueValueOfHeadUpdate{HeadUpdate: update},
|
||||
@ -12,7 +14,7 @@ func WrapHeadUpdate(update *SyncHeadUpdate, header *treepb.TreeHeader, treeId st
|
||||
}
|
||||
}
|
||||
|
||||
func WrapFullRequest(request *SyncFullRequest, header *treepb.TreeHeader, treeId string) *Sync {
|
||||
func WrapFullRequest(request *SyncFullRequest, header *aclpb.Header, treeId string) *Sync {
|
||||
return &Sync{
|
||||
Message: &SyncContentValue{
|
||||
Value: &SyncContentValueValueOfFullSyncRequest{FullSyncRequest: request},
|
||||
@ -22,7 +24,7 @@ func WrapFullRequest(request *SyncFullRequest, header *treepb.TreeHeader, treeId
|
||||
}
|
||||
}
|
||||
|
||||
func WrapFullResponse(response *SyncFullResponse, header *treepb.TreeHeader, treeId string) *Sync {
|
||||
func WrapFullResponse(response *SyncFullResponse, header *aclpb.Header, treeId string) *Sync {
|
||||
return &Sync{
|
||||
Message: &SyncContentValue{
|
||||
Value: &SyncContentValueValueOfFullSyncResponse{FullSyncResponse: response},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user