any-sync/node/acl/service.go
Sergey Cherepanov 8d7eaf665c
node acl service
2022-11-02 13:54:57 +03:00

135 lines
3.6 KiB
Go

package acl
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/synchandler"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"time"
)
const CName = "node.acl"
var log = logger.NewNamed(CName)
func New() Service {
return &service{}
}
type Service interface {
CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error)
AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error)
Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error)
UnWatch(aclId string) (err error)
app.Component
}
type service struct {
consService consensusclient.Service
account account.Service
}
func (s *service) Init(a *app.App) (err error) {
s.consService = a.MustComponent(consensusclient.CName).(consensusclient.Service)
s.account = a.MustComponent(account.CName).(account.Service)
return
}
func (s *service) Name() (name string) {
return CName
}
func (s *service) CreateLog(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (firstRecId string, err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
recId, _, payload, err := s.signAndMarshal(rawRec)
if err != nil {
return
}
if err = s.consService.AddLog(ctx, &consensusproto.Log{
Id: logId,
Records: []*consensusproto.Record{
{
Id: recId,
Payload: payload,
CreatedUnix: uint64(time.Now().Unix()),
},
},
}); err != nil {
return
}
return cidToString(recId)
}
func (s *service) AddRecord(ctx context.Context, aclId string, rawRec *aclrecordproto.RawACLRecord) (id string, err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
recId, prevId, payload, err := s.signAndMarshal(rawRec)
if err != nil {
return
}
if err = s.consService.AddRecord(ctx, logId, &consensusproto.Record{
Id: recId,
PrevId: prevId,
Payload: payload,
CreatedUnix: uint64(time.Now().Unix()),
}); err != nil {
return
}
return cidToString(recId)
}
func (s *service) Watch(ctx context.Context, spaceId, aclId string, h synchandler.SyncHandler) (err error) {
w, err := newWatcher(spaceId, aclId, h)
if err != nil {
return
}
if err = s.consService.Watch(w.logId, w); err != nil {
return err
}
return w.Ready(ctx)
}
func (s *service) UnWatch(aclId string) (err error) {
logId, err := cidToByte(aclId)
if err != nil {
return
}
return s.consService.UnWatch(logId)
}
func (s *service) signAndMarshal(rawRec *aclrecordproto.RawACLRecord) (recId, prevId, payload []byte, err error) {
var rec = &aclrecordproto.ACLRecord{}
if err = rec.Unmarshal(rawRec.Payload); err != nil {
return
}
if rec.PrevId != "" {
if prevId, err = cidToByte(rec.PrevId); err != nil {
return
}
}
rawRec.AcceptorIdentity = s.account.Account().Identity
if rawRec.AcceptorSignature, err = s.account.Account().SignKey.Sign(rawRec.Payload); err != nil {
return
}
if payload, err = rawRec.Marshal(); err != nil {
return
}
recCid, err := cid.NewCIDFromBytes(payload)
if err != nil {
return
}
recId, err = cidToByte(recCid)
return
}