Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(act): controller logic #47

Merged
merged 1 commit into from
May 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading