From 755e03891a13cd41a8943c05594c0aa82523569e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Ujv=C3=A1ri?= <58116288+bosi95@users.noreply.github.com> Date: Fri, 24 May 2024 18:55:06 +0200 Subject: [PATCH] refactor(act): controller logic (#47) --- pkg/dynamicaccess/controller.go | 270 +++++++++++++++----------------- 1 file changed, 129 insertions(+), 141 deletions(-) diff --git a/pkg/dynamicaccess/controller.go b/pkg/dynamicaccess/controller.go index 7ce650ef348..48e771cddc5 100644 --- a/pkg/dynamicaccess/controller.go +++ b/pkg/dynamicaccess/controller.go @@ -19,18 +19,18 @@ import ( type Grantees interface { // UpdateHandler manages the grantees for the given publisher, updating the list based on provided public keys to add or remove. // Only the publisher can make changes to the grantee list. - UpdateHandler(ctx context.Context, ls file.LoadSaver, gls file.LoadSaver, granteeref swarm.Address, historyref swarm.Address, publisher *ecdsa.PublicKey, addList, removeList []*ecdsa.PublicKey) (swarm.Address, swarm.Address, swarm.Address, swarm.Address, error) + UpdateHandler(ctx context.Context, ls file.LoadSaver, gls file.LoadSaver, granteeRef swarm.Address, historyRef swarm.Address, publisher *ecdsa.PublicKey, addList, removeList []*ecdsa.PublicKey) (swarm.Address, swarm.Address, swarm.Address, swarm.Address, error) // Get returns the list of grantees for the given publisher. // The list is accessible only by the publisher. - Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglref swarm.Address) ([]*ecdsa.PublicKey, error) + Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglRef swarm.Address) ([]*ecdsa.PublicKey, error) } type Controller interface { Grantees // DownloadHandler decrypts the encryptedRef using the lookupkey based on the history and timestamp. - DownloadHandler(ctx context.Context, ls file.LoadSaver, encryptedRef swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address, timestamp int64) (swarm.Address, error) + DownloadHandler(ctx context.Context, ls file.LoadSaver, encryptedRef swarm.Address, publisher *ecdsa.PublicKey, historyRef swarm.Address, timestamp int64) (swarm.Address, error) // UploadHandler encrypts the reference and stores it in the history as the latest update. - UploadHandler(ctx context.Context, ls file.LoadSaver, reference swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address) (swarm.Address, swarm.Address, swarm.Address, error) + UploadHandler(ctx context.Context, ls file.LoadSaver, reference swarm.Address, publisher *ecdsa.PublicKey, historyRef swarm.Address) (swarm.Address, swarm.Address, swarm.Address, error) io.Closer } @@ -40,23 +40,21 @@ type ControllerStruct struct { var _ Controller = (*ControllerStruct)(nil) +func NewController(accessLogic ActLogic) *ControllerStruct { + return &ControllerStruct{ + accessLogic: accessLogic, + } +} + func (c *ControllerStruct) DownloadHandler( ctx context.Context, ls file.LoadSaver, encryptedRef swarm.Address, publisher *ecdsa.PublicKey, - historyRootHash swarm.Address, + historyRef swarm.Address, timestamp int64, ) (swarm.Address, error) { - history, err := NewHistoryReference(ls, historyRootHash) - if err != nil { - return swarm.ZeroAddress, err - } - entry, err := history.Lookup(ctx, timestamp) - if err != nil { - return swarm.ZeroAddress, err - } - act, err := kvs.NewReference(ls, entry.Reference()) + _, act, err := c.getHistoryAndAct(ctx, ls, historyRef, publisher, timestamp) if err != nil { return swarm.ZeroAddress, err } @@ -69,125 +67,43 @@ func (c *ControllerStruct) UploadHandler( ls file.LoadSaver, reference swarm.Address, publisher *ecdsa.PublicKey, - historyRootHash swarm.Address, + historyRef swarm.Address, ) (swarm.Address, swarm.Address, swarm.Address, error) { - historyRef := historyRootHash - var ( - storage kvs.KeyValueStore - actRef swarm.Address - ) + history, act, err := c.getHistoryAndAct(ctx, ls, historyRef, publisher, time.Now().Unix()) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err + } + actRef := swarm.ZeroAddress + newHistoryRef := historyRef if historyRef.IsZero() { - history, err := NewHistory(ls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - storage, err = kvs.New(ls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - err = c.accessLogic.AddGrantee(ctx, storage, publisher, publisher) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - actRef, err = storage.Save(ctx) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - err = history.Add(ctx, actRef, nil, nil) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - historyRef, err = history.Store(ctx) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - } else { - history, err := NewHistoryReference(ls, historyRef) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - entry, err := history.Lookup(ctx, time.Now().Unix()) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - storage, err = kvs.NewReference(ls, entry.Reference()) + newHistoryRef, actRef, err = c.saveHistoryAndAct(ctx, history, nil, act) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } } - encryptedRef, err := c.accessLogic.EncryptRef(ctx, storage, publisher, reference) - return actRef, historyRef, encryptedRef, err -} - -func NewController(accessLogic ActLogic) *ControllerStruct { - return &ControllerStruct{ - accessLogic: accessLogic, - } + encryptedRef, err := c.accessLogic.EncryptRef(ctx, act, publisher, reference) + return actRef, newHistoryRef, encryptedRef, err } func (c *ControllerStruct) UpdateHandler( ctx context.Context, ls file.LoadSaver, gls file.LoadSaver, - encryptedglref swarm.Address, - historyref swarm.Address, + encryptedglRef swarm.Address, + historyRef swarm.Address, publisher *ecdsa.PublicKey, addList []*ecdsa.PublicKey, removeList []*ecdsa.PublicKey, ) (swarm.Address, swarm.Address, swarm.Address, swarm.Address, error) { - var ( - err error - h History - act kvs.KeyValueStore - granteeref swarm.Address - ) - if !historyref.IsZero() { - h, err = NewHistoryReference(ls, historyref) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - entry, err := h.Lookup(ctx, time.Now().Unix()) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - actref := entry.Reference() - act, err = kvs.NewReference(ls, actref) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - } else { - h, err = NewHistory(ls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - // generate new access key and new act - act, err = kvs.New(ls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - err = c.accessLogic.AddGrantee(ctx, act, publisher, publisher) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } + history, act, err := c.getHistoryAndAct(ctx, ls, historyRef, publisher, time.Now().Unix()) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } - var gl GranteeList - if encryptedglref.IsZero() { - gl, err = NewGranteeList(gls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - } else { - granteeref, err = c.decryptRefForPublisher(publisher, encryptedglref) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - - gl, err = NewGranteeListReference(ctx, gls, granteeref) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } + gl, err := c.getGranteeList(ctx, gls, encryptedglRef, publisher) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } if len(addList) != 0 { err = gl.Add(addList) @@ -201,14 +117,12 @@ func (c *ControllerStruct) UpdateHandler( if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } - // generate new access key and new act - act, err = kvs.New(ls) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - err = c.accessLogic.AddGrantee(ctx, act, publisher, publisher) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err + // generate new access key and new act, only if history was not newly created + if !historyRef.IsZero() { + act, err = c.newActWithPublisher(ctx, ls, publisher) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err + } } granteesToAdd = gl.Get() } @@ -220,51 +134,125 @@ func (c *ControllerStruct) UpdateHandler( } } - actref, err := act.Save(ctx) + granteeRef, err := gl.Save(ctx) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } - glref, err := gl.Save(ctx) - if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err - } - - eglref, err := c.encryptRefForPublisher(publisher, glref) + egranteeRef, err := c.encryptRefForPublisher(publisher, granteeRef) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } // need to re-initialize history, because Lookup loads the forks causing the manifest save to skip the root node - if !historyref.IsZero() { - h, err = NewHistoryReference(ls, historyref) + if !historyRef.IsZero() { + history, err = NewHistoryReference(ls, historyRef) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } } - mtdt := map[string]string{"encryptedglref": eglref.String()} - err = h.Add(ctx, actref, nil, &mtdt) + mtdt := map[string]string{"encryptedglref": egranteeRef.String()} + hRef, actRef, err := c.saveHistoryAndAct(ctx, history, &mtdt, act) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } - href, err := h.Store(ctx) + + return granteeRef, egranteeRef, hRef, actRef, nil +} + +func (c *ControllerStruct) Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglRef swarm.Address) ([]*ecdsa.PublicKey, error) { + gl, err := c.getGranteeList(ctx, ls, encryptedglRef, publisher) if err != nil { - return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err + return nil, err } - - return glref, eglref, href, actref, nil + return gl.Get(), nil } -func (c *ControllerStruct) Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglref swarm.Address) ([]*ecdsa.PublicKey, error) { - granteeRef, err := c.decryptRefForPublisher(publisher, encryptedglref) +func (c *ControllerStruct) newActWithPublisher(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey) (kvs.KeyValueStore, error) { + act, err := kvs.New(ls) if err != nil { return nil, err } - gl, err := NewGranteeListReference(ctx, ls, granteeRef) + err = c.accessLogic.AddGrantee(ctx, act, publisher, publisher) if err != nil { return nil, err } - return gl.Get(), nil + + return act, nil +} +func (c *ControllerStruct) getHistoryAndAct(ctx context.Context, ls file.LoadSaver, historyRef swarm.Address, publisher *ecdsa.PublicKey, timestamp int64) (History, kvs.KeyValueStore, error) { + var ( + history History + act kvs.KeyValueStore + err error + ) + if historyRef.IsZero() { + history, err = NewHistory(ls) + if err != nil { + return nil, nil, err + } + act, err = c.newActWithPublisher(ctx, ls, publisher) + if err != nil { + return nil, nil, err + } + } else { + history, err = NewHistoryReference(ls, historyRef) + if err != nil { + return nil, nil, err + } + entry, err := history.Lookup(ctx, timestamp) + if err != nil { + return nil, nil, err + } + act, err = kvs.NewReference(ls, entry.Reference()) + if err != nil { + return nil, nil, err + } + } + + return history, act, nil +} + +func (c *ControllerStruct) saveHistoryAndAct(ctx context.Context, history History, mtdt *map[string]string, act kvs.KeyValueStore) (swarm.Address, swarm.Address, error) { + actRef, err := act.Save(ctx) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, err + } + err = history.Add(ctx, actRef, nil, mtdt) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, err + } + historyRef, err := history.Store(ctx) + if err != nil { + return swarm.ZeroAddress, swarm.ZeroAddress, err + } + + return historyRef, actRef, nil +} + +func (c *ControllerStruct) getGranteeList(ctx context.Context, ls file.LoadSaver, encryptedglRef swarm.Address, publisher *ecdsa.PublicKey) (GranteeList, error) { + var ( + gl GranteeList + err error + ) + if encryptedglRef.IsZero() { + gl, err = NewGranteeList(ls) + if err != nil { + return nil, err + } + } else { + granteeref, err := c.decryptRefForPublisher(publisher, encryptedglRef) + if err != nil { + return nil, err + } + + gl, err = NewGranteeListReference(ctx, ls, granteeref) + if err != nil { + return nil, err + } + } + + return gl, nil } func (c *ControllerStruct) encryptRefForPublisher(publisherPubKey *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error) {