Skip to content

Commit

Permalink
refactor(act): controller logic (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
bosi95 authored and aranyia committed Jun 6, 2024
1 parent 5e377cc commit 755e038
Showing 1 changed file with 129 additions and 141 deletions.
270 changes: 129 additions & 141 deletions pkg/dynamicaccess/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}
Expand All @@ -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)
Expand All @@ -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()
}
Expand All @@ -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) {
Expand Down

0 comments on commit 755e038

Please sign in to comment.