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

test(act): controller add, revoke and get with history + fix typos #48

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion openapi/SwarmCommon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ components:
reserveSize:
type: integer
reserveSizeWithinRadius:
type: interger
type: integer
pullsyncRate:
type: number
storageRadius:
Expand Down
8 changes: 4 additions & 4 deletions pkg/api/dynamicaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,23 +281,23 @@ func (s *Service) actGrantRevokeHandler(w http.ResponseWriter, r *http.Request)
}

grantees := GranteesPatch{}
paresAddlist, err := parseKeys(gpr.Addlist)
parsedAddlist, err := parseKeys(gpr.Addlist)
if err != nil {
logger.Debug("add list key parse failed", "error", err)
logger.Error(nil, "add list key parse failed")
jsonhttp.InternalServerError(w, "error add list key parsing")
return
}
grantees.Addlist = append(grantees.Addlist, paresAddlist...)
grantees.Addlist = append(grantees.Addlist, parsedAddlist...)

paresRevokelist, err := parseKeys(gpr.Revokelist)
parsedRevokelist, err := parseKeys(gpr.Revokelist)
if err != nil {
logger.Debug("revoke list key parse failed", "error", err)
logger.Error(nil, "revoke list key parse failed")
jsonhttp.InternalServerError(w, "error revoke list key parsing")
return
}
grantees.Revokelist = append(grantees.Revokelist, paresRevokelist...)
grantees.Revokelist = append(grantees.Revokelist, parsedRevokelist...)

ctx := r.Context()
putter, err := s.newStamperPutter(ctx, putterOptions{
Expand Down
16 changes: 5 additions & 11 deletions pkg/dynamicaccess/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ func (c *ControllerStruct) UploadHandler(
return actRef, newHistoryRef, encryptedRef, err
}

// Limitation: If an upadate is called again within a second from the latest upload/update then mantaray save fails with ErrInvalidInput,
// because the key (timestamp) is already present, hence a new fork is not created
func (c *ControllerStruct) UpdateHandler(
ctx context.Context,
ls file.LoadSaver,
Expand Down Expand Up @@ -180,12 +182,8 @@ func (c *ControllerStruct) newActWithPublisher(ctx context.Context, ls file.Load

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
)

func (c *ControllerStruct) getHistoryAndAct(ctx context.Context, ls file.LoadSaver, historyRef swarm.Address, publisher *ecdsa.PublicKey, timestamp int64) (history History, act kvs.KeyValueStore, err error) {
if historyRef.IsZero() {
history, err = NewHistory(ls)
if err != nil {
Expand Down Expand Up @@ -230,11 +228,7 @@ func (c *ControllerStruct) saveHistoryAndAct(ctx context.Context, history Histor
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
)
func (c *ControllerStruct) getGranteeList(ctx context.Context, ls file.LoadSaver, encryptedglRef swarm.Address, publisher *ecdsa.PublicKey) (gl GranteeList, err error) {
if encryptedglRef.IsZero() {
gl, err = NewGranteeList(ls)
if err != nil {
Expand Down
44 changes: 42 additions & 2 deletions pkg/dynamicaccess/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/ethersphere/bee/v2/pkg/kvs"
"github.com/ethersphere/bee/v2/pkg/swarm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/sha3"
)

Expand Down Expand Up @@ -206,21 +207,60 @@ func TestController_UpdateHandler(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, gl.Get(), 2)
})
t.Run("add and revoke then get from history", func(t *testing.T) {
addRevokeList := []*ecdsa.PublicKey{&grantee.PublicKey}
ref := swarm.RandAddress(t)
_, hRef, encRef, err := c.UploadHandler(ctx, ls, ref, &publisher.PublicKey, swarm.ZeroAddress)
require.NoError(t, err)

// Need to wait a second before each update call so that a new history mantaray fork is created for the new key(timestamp) entry
time.Sleep(1 * time.Second)
beforeRevokeTS := time.Now().Unix()
_, egranteeRef, hrefUpdate1, _, err := c.UpdateHandler(ctx, ls, gls, swarm.ZeroAddress, hRef, &publisher.PublicKey, addRevokeList, nil)
require.NoError(t, err)

time.Sleep(1 * time.Second)
granteeRef, _, hrefUpdate2, _, err := c.UpdateHandler(ctx, ls, gls, egranteeRef, hrefUpdate1, &publisher.PublicKey, nil, addRevokeList)
require.NoError(t, err)

gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef)
require.NoError(t, err)
assert.Empty(t, gl.Get())
// expect history reference to be different after grantee list update
assert.NotEqual(t, hrefUpdate1, hrefUpdate2)

granteeDH := dynamicaccess.NewDefaultSession(grantee)
granteeAl := dynamicaccess.NewLogic(granteeDH)
granteeCtrl := dynamicaccess.NewController(granteeAl)
// download with grantee shall still work with the timestamp before the revoke
decRef, err := granteeCtrl.DownloadHandler(ctx, ls, encRef, &publisher.PublicKey, hrefUpdate2, beforeRevokeTS)
require.NoError(t, err)
assert.Equal(t, ref, decRef)

// download with grantee shall NOT work with the latest timestamp
decRef, err = granteeCtrl.DownloadHandler(ctx, ls, encRef, &publisher.PublicKey, hrefUpdate2, time.Now().Unix())
require.Error(t, err)
assert.Equal(t, swarm.ZeroAddress, decRef)

// publisher shall still be able to download with the timestamp before the revoke
decRef, err = c.DownloadHandler(ctx, ls, encRef, &publisher.PublicKey, hrefUpdate2, beforeRevokeTS)
require.NoError(t, err)
assert.Equal(t, ref, decRef)
})
t.Run("add twice", func(t *testing.T) {
addList := []*ecdsa.PublicKey{&grantee.PublicKey, &grantee.PublicKey}
//nolint:ineffassign,staticcheck,wastedassign
granteeRef, eglref, _, _, err := c.UpdateHandler(ctx, ls, gls, swarm.ZeroAddress, href, &publisher.PublicKey, addList, nil)
granteeRef, _, _, _, _ = c.UpdateHandler(ctx, ls, ls, eglref, href, &publisher.PublicKey, addList, nil)
gl, err := dynamicaccess.NewGranteeListReference(ctx, createLs(), granteeRef)
gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef)

assert.NoError(t, err)
assert.Len(t, gl.Get(), 1)
})
t.Run("revoke non-existing", func(t *testing.T) {
addList := []*ecdsa.PublicKey{&grantee.PublicKey}
granteeRef, _, _, _, _ := c.UpdateHandler(ctx, ls, ls, swarm.ZeroAddress, href, &publisher.PublicKey, addList, nil)
gl, err := dynamicaccess.NewGranteeListReference(ctx, createLs(), granteeRef)
gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef)

assert.NoError(t, err)
assert.Len(t, gl.Get(), 1)
Expand Down
28 changes: 14 additions & 14 deletions pkg/dynamicaccess/mock/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"golang.org/x/crypto/sha3"
)

type mockDacService struct {
type mockController struct {
historyMap map[string]dynamicaccess.History
refMap map[string]swarm.Address
acceptAll bool
Expand All @@ -34,19 +34,19 @@ type mockDacService struct {
ls file.LoadSaver
}

type optionFunc func(*mockDacService)
type optionFunc func(*mockController)

// Option is an option passed to a mock dynamicaccess Service.
type Option interface {
apply(*mockDacService)
apply(*mockController)
}

func (f optionFunc) apply(r *mockDacService) { f(r) }
func (f optionFunc) apply(r *mockController) { f(r) }

// New creates a new mock dynamicaccess service.
func New(o ...Option) dynamicaccess.Controller {
storer := mockstorer.New()
m := &mockDacService{
m := &mockController{
historyMap: make(map[string]dynamicaccess.History),
refMap: make(map[string]swarm.Address),
publisher: "",
Expand All @@ -62,23 +62,23 @@ func New(o ...Option) dynamicaccess.Controller {

// WithAcceptAll sets the mock to return fixed references on every call to DownloadHandler.
func WithAcceptAll() Option {
return optionFunc(func(m *mockDacService) { m.acceptAll = true })
return optionFunc(func(m *mockController) { m.acceptAll = true })
}

func WithHistory(h dynamicaccess.History, ref string) Option {
return optionFunc(func(m *mockDacService) {
return optionFunc(func(m *mockController) {
m.historyMap = map[string]dynamicaccess.History{ref: h}
})
}

func WithPublisher(ref string) Option {
return optionFunc(func(m *mockDacService) {
return optionFunc(func(m *mockController) {
m.publisher = ref
m.encrypter = encryption.New(encryption.Key(ref), 0, uint32(0), sha3.NewLegacyKeccak256)
})
}

func (m *mockDacService) DownloadHandler(ctx context.Context, ls file.LoadSaver, encryptedRef swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address, timestamp int64) (swarm.Address, error) {
func (m *mockController) DownloadHandler(ctx context.Context, ls file.LoadSaver, encryptedRef swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address, timestamp int64) (swarm.Address, error) {
if m.acceptAll {
return swarm.ParseHexAddress("36e6c1bbdfee6ac21485d5f970479fd1df458d36df9ef4e8179708ed46da557f")
}
Expand All @@ -101,7 +101,7 @@ func (m *mockDacService) DownloadHandler(ctx context.Context, ls file.LoadSaver,
return m.refMap[encryptedRef.String()], nil
}

func (m *mockDacService) UploadHandler(ctx context.Context, ls file.LoadSaver, reference swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address) (swarm.Address, swarm.Address, swarm.Address, error) {
func (m *mockController) UploadHandler(ctx context.Context, ls file.LoadSaver, reference swarm.Address, publisher *ecdsa.PublicKey, historyRootHash swarm.Address) (swarm.Address, swarm.Address, swarm.Address, error) {
historyRef, _ := swarm.ParseHexAddress("67bdf80a9bbea8eca9c8480e43fdceb485d2d74d5708e45144b8c4adacd13d9c")
kvsRef, _ := swarm.ParseHexAddress("3339613565613837623134316665343461613630396333333237656364383934")
if m.acceptAll {
Expand Down Expand Up @@ -136,19 +136,19 @@ func (m *mockDacService) UploadHandler(ctx context.Context, ls file.LoadSaver, r
return kvsRef, historyRef, swarm.NewAddress(encryptedRef), nil
}

func (m *mockDacService) Close() error {
func (m *mockController) Close() error {
return nil
}

func (m *mockDacService) UpdateHandler(_ context.Context, ls file.LoadSaver, gls file.LoadSaver, encryptedglref swarm.Address, historyref swarm.Address, publisher *ecdsa.PublicKey, addList []*ecdsa.PublicKey, removeList []*ecdsa.PublicKey) (swarm.Address, swarm.Address, swarm.Address, swarm.Address, error) {
func (m *mockController) UpdateHandler(_ context.Context, ls file.LoadSaver, gls file.LoadSaver, encryptedglref swarm.Address, historyref swarm.Address, publisher *ecdsa.PublicKey, addList []*ecdsa.PublicKey, removeList []*ecdsa.PublicKey) (swarm.Address, swarm.Address, swarm.Address, swarm.Address, error) {
historyRef, _ := swarm.ParseHexAddress("67bdf80a9bbea8eca9c8480e43fdceb485d2d74d5708e45144b8c4adacd13d9c")
glRef, _ := swarm.ParseHexAddress("3339613565613837623134316665343461613630396333333237656364383934")
eglRef, _ := swarm.ParseHexAddress("fc4e9fe978991257b897d987bc4ff13058b66ef45a53189a0b4fe84bb3346396")
actref, _ := swarm.ParseHexAddress("39a5ea87b141fe44aa609c3327ecd896c0e2122897f5f4bbacf74db1033c5559")
return glRef, eglRef, historyRef, actref, nil
}

func (m *mockDacService) Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglref swarm.Address) ([]*ecdsa.PublicKey, error) {
func (m *mockController) Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglref swarm.Address) ([]*ecdsa.PublicKey, error) {
if m.publisher == "" {
return nil, fmt.Errorf("granteelist not found")
}
Expand Down Expand Up @@ -180,4 +180,4 @@ func requestPipelineFactory(ctx context.Context, s storage.Putter, encrypt bool,
}
}

var _ dynamicaccess.Controller = (*mockDacService)(nil)
var _ dynamicaccess.Controller = (*mockController)(nil)
10 changes: 5 additions & 5 deletions pkg/kvs/kvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,23 @@ func (s *keyValueStore) Save(ctx context.Context) (swarm.Address, error) {
}

func New(ls file.LoadSaver) (KeyValueStore, error) {
manif, err := manifest.NewSimpleManifest(ls)
m, err := manifest.NewSimpleManifest(ls)
if err != nil {
return nil, err
}

return &keyValueStore{
manifest: manif,
manifest: m,
}, nil
}

func NewReference(ls file.LoadSaver, rootHash swarm.Address) (KeyValueStore, error) {
manif, err := manifest.NewSimpleManifestReference(rootHash, ls)
func NewReference(ls file.LoadSaver, ref swarm.Address) (KeyValueStore, error) {
m, err := manifest.NewSimpleManifestReference(ref, ls)
if err != nil {
return nil, err
}

return &keyValueStore{
manifest: manif,
manifest: m,
}, nil
}
Loading