diff --git a/cmd/bee/cmd/start.go b/cmd/bee/cmd/start.go index 9403dc69571..c0378e52e2b 100644 --- a/cmd/bee/cmd/start.go +++ b/cmd/bee/cmd/start.go @@ -24,10 +24,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" "github.com/ethersphere/bee/v2" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" chaincfg "github.com/ethersphere/bee/v2/pkg/config" "github.com/ethersphere/bee/v2/pkg/crypto" "github.com/ethersphere/bee/v2/pkg/crypto/clef" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" "github.com/ethersphere/bee/v2/pkg/keystore" filekeystore "github.com/ethersphere/bee/v2/pkg/keystore/file" memkeystore "github.com/ethersphere/bee/v2/pkg/keystore/mem" @@ -374,7 +374,7 @@ type signerConfig struct { publicKey *ecdsa.PublicKey libp2pPrivateKey *ecdsa.PrivateKey pssPrivateKey *ecdsa.PrivateKey - session dynamicaccess.Session + session accesscontrol.Session } func waitForClef(logger log.Logger, maxRetries uint64, endpoint string) (externalSigner *external.ExternalSigner, err error) { @@ -405,7 +405,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config var signer crypto.Signer var password string var publicKey *ecdsa.PublicKey - var session dynamicaccess.Session + var session accesscontrol.Session if p := c.config.GetString(optionNamePassword); p != "" { password = p } else if pf := c.config.GetString(optionNamePasswordFile); pf != "" { @@ -478,7 +478,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config } signer = crypto.NewDefaultSigner(swarmPrivateKey) publicKey = &swarmPrivateKey.PublicKey - session = dynamicaccess.NewDefaultSession(swarmPrivateKey) + session = accesscontrol.NewDefaultSession(swarmPrivateKey) } logger.Info("swarm public key", "public_key", hex.EncodeToString(crypto.EncodeSecp256k1PublicKey(publicKey))) diff --git a/pkg/dynamicaccess/accesslogic.go b/pkg/accesscontrol/access.go similarity index 75% rename from pkg/dynamicaccess/accesslogic.go rename to pkg/accesscontrol/access.go index 671537486e9..79f60facb2d 100644 --- a/pkg/dynamicaccess/accesslogic.go +++ b/pkg/accesscontrol/access.go @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess +package accesscontrol import ( "context" "crypto/ecdsa" "fmt" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs" "github.com/ethersphere/bee/v2/pkg/encryption" - "github.com/ethersphere/bee/v2/pkg/kvs" "github.com/ethersphere/bee/v2/pkg/swarm" "golang.org/x/crypto/sha3" ) @@ -24,7 +24,7 @@ var ( // Decryptor is a read-only interface for the ACT. type Decryptor interface { - // DecryptRef will return a decrypted reference, for given encrypted reference and grantee + // DecryptRef will return a decrypted reference, for given encrypted reference and grantee. DecryptRef(ctx context.Context, storage kvs.KeyValueStore, encryptedRef swarm.Address, publisher *ecdsa.PublicKey) (swarm.Address, error) Session } @@ -32,19 +32,20 @@ type Decryptor interface { // Control interface for the ACT (does write operations). type Control interface { Decryptor - // AddGrantee adds a new grantee to the ACT + // AddGrantee adds a new grantee to the ACT. AddGrantee(ctx context.Context, storage kvs.KeyValueStore, publisherPubKey, granteePubKey *ecdsa.PublicKey) error - // EncryptRef encrypts a Swarm reference for a given grantee + // EncryptRef encrypts a Swarm reference for a given grantee. EncryptRef(ctx context.Context, storage kvs.KeyValueStore, grantee *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error) } +// ActLogic represents the access control logic. type ActLogic struct { Session } var _ Control = (*ActLogic)(nil) -// EncryptRef encrypts a SWARM reference for a publisher. +// EncryptRef encrypts a Swarm reference for a publisher. func (al ActLogic) EncryptRef(ctx context.Context, storage kvs.KeyValueStore, publisherPubKey *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error) { accessKey, err := al.getAccessKey(ctx, storage, publisherPubKey) if err != nil { @@ -66,32 +67,36 @@ func (al ActLogic) AddGrantee(ctx context.Context, storage kvs.KeyValueStore, pu err error ) - // Create new access key because grantee is the publisher + // Create new access key because grantee is the publisher. if publisherPubKey.Equal(granteePubKey) { accessKey = encryption.GenerateRandomKey(encryption.KeyLength) } else { - // Get previously generated access key + // Get previously generated access key. accessKey, err = al.getAccessKey(ctx, storage, publisherPubKey) if err != nil { return err } } - // Encrypt the access key for the new Grantee lookupKey, accessKeyDecryptionKey, err := al.getKeys(granteePubKey) if err != nil { return err } - // Encrypt the access key for the new Grantee + // Encrypt the access key for the new Grantee. cipher := encryption.New(encryption.Key(accessKeyDecryptionKey), 0, uint32(0), hashFunc) granteeEncryptedAccessKey, err := cipher.Encrypt(accessKey) if err != nil { return fmt.Errorf("failed to encrypt access key: %w", err) } - // Add the new encrypted access key to the Act - return storage.Put(ctx, lookupKey, granteeEncryptedAccessKey) + // Add the new encrypted access key to the Act. + err = storage.Put(ctx, lookupKey, granteeEncryptedAccessKey) + if err != nil { + return fmt.Errorf("failed to put value to KVS: %w", err) + } + + return nil } // Will return the access key for a publisher (public key). @@ -100,56 +105,48 @@ func (al *ActLogic) getAccessKey(ctx context.Context, storage kvs.KeyValueStore, if err != nil { return nil, err } - // no need for constructor call if value not found in act + // no need for constructor call if value not found in act. accessKeyDecryptionCipher := encryption.New(encryption.Key(publisherAKDecryptionKey), 0, uint32(0), hashFunc) encryptedAK, err := storage.Get(ctx, publisherLookupKey) if err != nil { return nil, fmt.Errorf("failed go get value from KVS: %w", err) } - return accessKeyDecryptionCipher.Decrypt(encryptedAK) + accessKey, err := accessKeyDecryptionCipher.Decrypt(encryptedAK) + if err != nil { + return nil, fmt.Errorf("failed to decrypt access key: %w", err) + } + + return accessKey, nil } -// Generate lookup key and access key decryption key for a given public key +// Generate lookup key and access key decryption key for a given public key. func (al *ActLogic) getKeys(publicKey *ecdsa.PublicKey) ([]byte, []byte, error) { nonces := [][]byte{zeroByteArray, oneByteArray} keys, err := al.Session.Key(publicKey, nonces) - if keys == nil { + if len(keys) != len(nonces) { return nil, nil, err } return keys[0], keys[1], err } -// DecryptRef will return a decrypted reference, for given encrypted reference and publisher +// DecryptRef will return a decrypted reference, for given encrypted reference and publisher. func (al ActLogic) DecryptRef(ctx context.Context, storage kvs.KeyValueStore, encryptedRef swarm.Address, publisher *ecdsa.PublicKey) (swarm.Address, error) { - lookupKey, accessKeyDecryptionKey, err := al.getKeys(publisher) - if err != nil { - return swarm.ZeroAddress, err - } - - // Lookup encrypted access key from the ACT manifest - encryptedAccessKey, err := storage.Get(ctx, lookupKey) - if err != nil { - return swarm.ZeroAddress, fmt.Errorf("failed to get access key from KVS: %w", err) - } - - // Decrypt access key - accessKeyCipher := encryption.New(encryption.Key(accessKeyDecryptionKey), 0, uint32(0), hashFunc) - accessKey, err := accessKeyCipher.Decrypt(encryptedAccessKey) + accessKey, err := al.getAccessKey(ctx, storage, publisher) if err != nil { return swarm.ZeroAddress, err } - // Decrypt reference refCipher := encryption.New(accessKey, 0, uint32(0), hashFunc) ref, err := refCipher.Decrypt(encryptedRef.Bytes()) if err != nil { - return swarm.ZeroAddress, err + return swarm.ZeroAddress, fmt.Errorf("failed to decrypt reference: %w", err) } return swarm.NewAddress(ref), nil } +// NewLogic creates a new ACT Logic from a session. func NewLogic(s Session) ActLogic { return ActLogic{ Session: s, diff --git a/pkg/dynamicaccess/accesslogic_test.go b/pkg/accesscontrol/access_test.go similarity index 89% rename from pkg/dynamicaccess/accesslogic_test.go rename to pkg/accesscontrol/access_test.go index b8cab2f8fbf..d976131ec92 100644 --- a/pkg/dynamicaccess/accesslogic_test.go +++ b/pkg/accesscontrol/access_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess_test +package accesscontrol_test import ( "context" @@ -12,18 +12,18 @@ import ( "encoding/hex" "testing" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" + kvsmock "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs/mock" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" - kvsmock "github.com/ethersphere/bee/v2/pkg/kvs/mock" "github.com/ethersphere/bee/v2/pkg/swarm" "github.com/stretchr/testify/assert" ) -// Generates a new test environment with a fix private key -func setupAccessLogic() dynamicaccess.ActLogic { +// Generates a new test environment with a fix private key. +func setupAccessLogic() accesscontrol.ActLogic { privateKey := getPrivKey(1) - diffieHellman := dynamicaccess.NewDefaultSession(privateKey) - al := dynamicaccess.NewLogic(diffieHellman) + diffieHellman := accesscontrol.NewDefaultSession(privateKey) + al := accesscontrol.NewLogic(diffieHellman) return al } @@ -87,8 +87,8 @@ func TestDecryptRefWithGrantee_Success(t *testing.T) { t.Parallel() ctx := context.Background() id0, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - diffieHellman := dynamicaccess.NewDefaultSession(id0) - al := dynamicaccess.NewLogic(diffieHellman) + diffieHellman := accesscontrol.NewDefaultSession(id0) + al := accesscontrol.NewLogic(diffieHellman) s := kvsmock.New() err := al.AddGrantee(ctx, s, &id0.PublicKey, &id0.PublicKey) @@ -111,8 +111,8 @@ func TestDecryptRefWithGrantee_Success(t *testing.T) { t.Fatalf("There was an error while calling EncryptRef: %v", err) } - diffieHellman2 := dynamicaccess.NewDefaultSession(id1) - granteeAccessLogic := dynamicaccess.NewLogic(diffieHellman2) + diffieHellman2 := accesscontrol.NewDefaultSession(id1) + granteeAccessLogic := accesscontrol.NewLogic(diffieHellman2) actualRef, err := granteeAccessLogic.DecryptRef(ctx, s, encryptedRef, &id0.PublicKey) if err != nil { t.Fatalf("There was an error while calling Get: %v", err) @@ -139,8 +139,7 @@ func TestDecryptRef_Error(t *testing.T) { r, err := al.DecryptRef(ctx, s, encryptedRef, nil) if err == nil { - t.Logf("r: %s", r.String()) - t.Fatalf("Get should return encrypted access key not found error!") + t.Fatalf("Get should return error but got reference: %v", r) } } @@ -168,9 +167,6 @@ func TestAddPublisher(t *testing.T) { if len(decodedEncryptedAccessKey) != 64 { t.Fatalf("AddGrantee: expected encrypted access key length 64, got %d", len(decodedEncryptedAccessKey)) } - if s == nil { - t.Fatalf("AddGrantee: expected act, got nil") - } } func TestAddNewGranteeToContent(t *testing.T) { diff --git a/pkg/dynamicaccess/controller.go b/pkg/accesscontrol/controller.go similarity index 82% rename from pkg/dynamicaccess/controller.go rename to pkg/accesscontrol/controller.go index dffe4bbdf64..f2c843c6b36 100644 --- a/pkg/dynamicaccess/controller.go +++ b/pkg/accesscontrol/controller.go @@ -2,20 +2,24 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess +// Package accesscontrol provides functionalities needed +// for managing access control on Swarm +package accesscontrol import ( "context" "crypto/ecdsa" + "fmt" "io" "time" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs" "github.com/ethersphere/bee/v2/pkg/encryption" "github.com/ethersphere/bee/v2/pkg/file" - "github.com/ethersphere/bee/v2/pkg/kvs" "github.com/ethersphere/bee/v2/pkg/swarm" ) +// Grantees represents an interface for managing and retrieving grantees for a publisher. 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. @@ -25,6 +29,8 @@ type Grantees interface { Get(ctx context.Context, ls file.LoadSaver, publisher *ecdsa.PublicKey, encryptedglRef swarm.Address) ([]*ecdsa.PublicKey, error) } +// Controller the interface for managing access control on Swarm. +// It provides methods for handling downloads, uploads and updates for grantee lists and references. type Controller interface { Grantees // DownloadHandler decrypts the encryptedRef using the lookupkey based on the history and timestamp. @@ -34,18 +40,21 @@ type Controller interface { io.Closer } +// ControllerStruct represents a controller for access control logic. type ControllerStruct struct { - accessLogic ActLogic + access ActLogic } var _ Controller = (*ControllerStruct)(nil) -func NewController(accessLogic ActLogic) *ControllerStruct { +// NewController creates a new access controller with the given access logic. +func NewController(access ActLogic) *ControllerStruct { return &ControllerStruct{ - accessLogic: accessLogic, + access: access, } } +// DownloadHandler decrypts the encryptedRef using the lookupkey based on the history and timestamp. func (c *ControllerStruct) DownloadHandler( ctx context.Context, ls file.LoadSaver, @@ -59,9 +68,10 @@ func (c *ControllerStruct) DownloadHandler( return swarm.ZeroAddress, err } - return c.accessLogic.DecryptRef(ctx, act, encryptedRef, publisher) + return c.access.DecryptRef(ctx, act, encryptedRef, publisher) } +// UploadHandler encrypts the reference and stores it in the history as the latest update. func (c *ControllerStruct) UploadHandler( ctx context.Context, ls file.LoadSaver, @@ -82,12 +92,14 @@ func (c *ControllerStruct) UploadHandler( } } - encryptedRef, err := c.accessLogic.EncryptRef(ctx, act, publisher, reference) + encryptedRef, err := c.access.EncryptRef(ctx, act, publisher, reference) return actRef, newHistoryRef, encryptedRef, err } +// 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. // 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 +// because the key (timestamp) is already present, hence a new fork is not created. func (c *ControllerStruct) UpdateHandler( ctx context.Context, ls file.LoadSaver, @@ -130,7 +142,7 @@ func (c *ControllerStruct) UpdateHandler( } for _, grantee := range granteesToAdd { - err := c.accessLogic.AddGrantee(ctx, act, publisher, grantee) + err := c.access.AddGrantee(ctx, act, publisher, grantee) if err != nil { return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, err } @@ -162,6 +174,8 @@ func (c *ControllerStruct) UpdateHandler( return granteeRef, egranteeRef, hRef, actRef, nil } +// Get returns the list of grantees for the given publisher. +// The list is accessible only by the publisher. 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 { @@ -175,7 +189,7 @@ func (c *ControllerStruct) newActWithPublisher(ctx context.Context, ls file.Load if err != nil { return nil, err } - err = c.accessLogic.AddGrantee(ctx, act, publisher, publisher) + err = c.access.AddGrantee(ctx, act, publisher, publisher) if err != nil { return nil, err } @@ -230,10 +244,7 @@ func (c *ControllerStruct) saveHistoryAndAct(ctx context.Context, history Histor 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 { - return nil, err - } + gl = NewGranteeList(ls) } else { granteeref, err := c.decryptRefForPublisher(publisher, encryptedglRef) if err != nil { @@ -250,34 +261,34 @@ func (c *ControllerStruct) getGranteeList(ctx context.Context, ls file.LoadSaver } func (c *ControllerStruct) encryptRefForPublisher(publisherPubKey *ecdsa.PublicKey, ref swarm.Address) (swarm.Address, error) { - keys, err := c.accessLogic.Session.Key(publisherPubKey, [][]byte{oneByteArray}) + keys, err := c.access.Session.Key(publisherPubKey, [][]byte{oneByteArray}) if err != nil { return swarm.ZeroAddress, err } refCipher := encryption.New(keys[0], 0, uint32(0), hashFunc) encryptedRef, err := refCipher.Encrypt(ref.Bytes()) if err != nil { - return swarm.ZeroAddress, err + return swarm.ZeroAddress, fmt.Errorf("failed to encrypt reference: %w", err) } return swarm.NewAddress(encryptedRef), nil } func (c *ControllerStruct) decryptRefForPublisher(publisherPubKey *ecdsa.PublicKey, encryptedRef swarm.Address) (swarm.Address, error) { - keys, err := c.accessLogic.Session.Key(publisherPubKey, [][]byte{oneByteArray}) + keys, err := c.access.Session.Key(publisherPubKey, [][]byte{oneByteArray}) if err != nil { return swarm.ZeroAddress, err } refCipher := encryption.New(keys[0], 0, uint32(0), hashFunc) ref, err := refCipher.Decrypt(encryptedRef.Bytes()) if err != nil { - return swarm.ZeroAddress, err + return swarm.ZeroAddress, fmt.Errorf("failed to decrypt reference: %w", err) } return swarm.NewAddress(ref), nil } -// TODO: what to do in close ? +// Close simply returns nil func (c *ControllerStruct) Close() error { return nil } diff --git a/pkg/dynamicaccess/controller_test.go b/pkg/accesscontrol/controller_test.go similarity index 81% rename from pkg/dynamicaccess/controller_test.go rename to pkg/accesscontrol/controller_test.go index c25d8079bfa..11a922cacae 100644 --- a/pkg/dynamicaccess/controller_test.go +++ b/pkg/accesscontrol/controller_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess_test +package accesscontrol_test import ( "context" @@ -11,12 +11,12 @@ import ( "testing" "time" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs" encryption "github.com/ethersphere/bee/v2/pkg/encryption" "github.com/ethersphere/bee/v2/pkg/file" "github.com/ethersphere/bee/v2/pkg/file/loadsave" "github.com/ethersphere/bee/v2/pkg/file/redundancy" - "github.com/ethersphere/bee/v2/pkg/kvs" "github.com/ethersphere/bee/v2/pkg/swarm" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -24,8 +24,8 @@ import ( ) //nolint:errcheck,gosec,wrapcheck -func getHistoryFixture(ctx context.Context, ls file.LoadSaver, al dynamicaccess.ActLogic, publisher *ecdsa.PublicKey) (swarm.Address, error) { - h, err := dynamicaccess.NewHistory(ls) +func getHistoryFixture(ctx context.Context, ls file.LoadSaver, al accesscontrol.ActLogic, publisher *ecdsa.PublicKey) (swarm.Address, error) { + h, err := accesscontrol.NewHistory(ls) if err != nil { return swarm.ZeroAddress, err } @@ -57,9 +57,9 @@ func TestController_UploadHandler(t *testing.T) { t.Parallel() ctx := context.Background() publisher := getPrivKey(0) - diffieHellman := dynamicaccess.NewDefaultSession(publisher) - al := dynamicaccess.NewLogic(diffieHellman) - c := dynamicaccess.NewController(al) + diffieHellman := accesscontrol.NewDefaultSession(publisher) + al := accesscontrol.NewLogic(diffieHellman) + c := accesscontrol.NewController(al) ls := createLs() t.Run("New upload", func(t *testing.T) { @@ -67,7 +67,7 @@ func TestController_UploadHandler(t *testing.T) { _, hRef, encRef, err := c.UploadHandler(ctx, ls, ref, &publisher.PublicKey, swarm.ZeroAddress) assert.NoError(t, err) - h, _ := dynamicaccess.NewHistoryReference(ls, hRef) + h, _ := accesscontrol.NewHistoryReference(ls, hRef) entry, _ := h.Lookup(ctx, time.Now().Unix()) actRef := entry.Reference() act, _ := kvs.NewReference(ls, actRef) @@ -84,20 +84,20 @@ func TestController_UploadHandler(t *testing.T) { assert.NoError(t, err) _, hRef2, encRef, err := c.UploadHandler(ctx, ls, ref, &publisher.PublicKey, hRef1) assert.NoError(t, err) - h, err := dynamicaccess.NewHistoryReference(ls, hRef2) + h, err := accesscontrol.NewHistoryReference(ls, hRef2) assert.NoError(t, err) hRef2, err = h.Store(ctx) assert.NoError(t, err) assert.True(t, hRef1.Equal(hRef2)) - h, _ = dynamicaccess.NewHistoryReference(ls, hRef2) + h, _ = accesscontrol.NewHistoryReference(ls, hRef2) entry, _ := h.Lookup(ctx, time.Now().Unix()) actRef := entry.Reference() act, _ := kvs.NewReference(ls, actRef) expRef, err := al.EncryptRef(ctx, act, &publisher.PublicKey, ref) assert.NoError(t, err) - assert.Equal(t, encRef, expRef) + assert.Equal(t, expRef, encRef) assert.NotEqual(t, hRef2, swarm.ZeroAddress) }) } @@ -106,13 +106,13 @@ func TestController_PublisherDownload(t *testing.T) { t.Parallel() ctx := context.Background() publisher := getPrivKey(0) - diffieHellman := dynamicaccess.NewDefaultSession(publisher) - al := dynamicaccess.NewLogic(diffieHellman) - c := dynamicaccess.NewController(al) + diffieHellman := accesscontrol.NewDefaultSession(publisher) + al := accesscontrol.NewLogic(diffieHellman) + c := accesscontrol.NewController(al) ls := createLs() ref := swarm.RandAddress(t) href, _ := getHistoryFixture(ctx, ls, al, &publisher.PublicKey) - h, _ := dynamicaccess.NewHistoryReference(ls, href) + h, _ := accesscontrol.NewHistoryReference(ls, href) entry, _ := h.Lookup(ctx, time.Now().Unix()) actRef := entry.Reference() act, _ := kvs.NewReference(ls, actRef) @@ -129,16 +129,16 @@ func TestController_GranteeDownload(t *testing.T) { ctx := context.Background() publisher := getPrivKey(0) grantee := getPrivKey(2) - publisherDH := dynamicaccess.NewDefaultSession(publisher) - publisherAL := dynamicaccess.NewLogic(publisherDH) + publisherDH := accesscontrol.NewDefaultSession(publisher) + publisherAL := accesscontrol.NewLogic(publisherDH) - diffieHellman := dynamicaccess.NewDefaultSession(grantee) - al := dynamicaccess.NewLogic(diffieHellman) + diffieHellman := accesscontrol.NewDefaultSession(grantee) + al := accesscontrol.NewLogic(diffieHellman) ls := createLs() - c := dynamicaccess.NewController(al) + c := accesscontrol.NewController(al) ref := swarm.RandAddress(t) href, _ := getHistoryFixture(ctx, ls, publisherAL, &publisher.PublicKey) - h, _ := dynamicaccess.NewHistoryReference(ls, href) + h, _ := accesscontrol.NewHistoryReference(ls, href) ts := time.Date(2001, time.April, 1, 0, 0, 0, 0, time.UTC).Unix() entry, _ := h.Lookup(ctx, ts) actRef := entry.Reference() @@ -155,13 +155,13 @@ func TestController_UpdateHandler(t *testing.T) { t.Parallel() ctx := context.Background() publisher := getPrivKey(1) - diffieHellman := dynamicaccess.NewDefaultSession(publisher) - al := dynamicaccess.NewLogic(diffieHellman) + diffieHellman := accesscontrol.NewDefaultSession(publisher) + al := accesscontrol.NewLogic(diffieHellman) keys, _ := al.Session.Key(&publisher.PublicKey, [][]byte{{1}}) refCipher := encryption.New(keys[0], 0, uint32(0), sha3.NewLegacyKeccak256) ls := createLs() gls := loadsave.New(mockStorer.ChunkStore(), mockStorer.Cache(), requestPipelineFactory(context.Background(), mockStorer.Cache(), true, redundancy.NONE)) - c := dynamicaccess.NewController(al) + c := accesscontrol.NewController(al) href, _ := getHistoryFixture(ctx, ls, al, &publisher.PublicKey) grantee1 := getPrivKey(0) @@ -172,7 +172,7 @@ func TestController_UpdateHandler(t *testing.T) { granteeRef, _, _, _, err := c.UpdateHandler(ctx, ls, ls, swarm.ZeroAddress, swarm.ZeroAddress, &publisher.PublicKey, addList, nil) assert.NoError(t, err) - gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef) + gl, err := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 1) @@ -182,27 +182,27 @@ func TestController_UpdateHandler(t *testing.T) { granteeRef, eglref, _, _, err := c.UpdateHandler(ctx, ls, gls, swarm.ZeroAddress, href, &publisher.PublicKey, addList, nil) assert.NoError(t, err) - gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef) + gl, err := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 1) addList = []*ecdsa.PublicKey{&getPrivKey(0).PublicKey} granteeRef, _, _, _, _ = c.UpdateHandler(ctx, ls, ls, eglref, href, &publisher.PublicKey, addList, nil) - gl, err = dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef) + gl, err = accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 2) }) t.Run("add and revoke", func(t *testing.T) { addList := []*ecdsa.PublicKey{&grantee.PublicKey} revokeList := []*ecdsa.PublicKey{&grantee1.PublicKey} - gl, _ := dynamicaccess.NewGranteeList(ls) + gl := accesscontrol.NewGranteeList(ls) _ = gl.Add([]*ecdsa.PublicKey{&publisher.PublicKey, &grantee1.PublicKey}) granteeRef, _ := gl.Save(ctx) eglref, _ := refCipher.Encrypt(granteeRef.Bytes()) granteeRef, _, _, _, _ = c.UpdateHandler(ctx, ls, gls, swarm.NewAddress(eglref), href, &publisher.PublicKey, addList, revokeList) - gl, err := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef) + gl, err := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 2) @@ -223,15 +223,15 @@ func TestController_UpdateHandler(t *testing.T) { 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) + gl, err := accesscontrol.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) + granteeDH := accesscontrol.NewDefaultSession(grantee) + granteeAl := accesscontrol.NewLogic(granteeDH) + granteeCtrl := accesscontrol.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) @@ -252,7 +252,7 @@ func TestController_UpdateHandler(t *testing.T) { //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, ls, granteeRef) + gl, err := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 1) @@ -260,7 +260,7 @@ func TestController_UpdateHandler(t *testing.T) { 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, ls, granteeRef) + gl, err := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.NoError(t, err) assert.Len(t, gl.Get(), 1) @@ -273,14 +273,14 @@ func TestController_Get(t *testing.T) { publisher := getPrivKey(1) caller := getPrivKey(0) grantee := getPrivKey(2) - diffieHellman1 := dynamicaccess.NewDefaultSession(publisher) - diffieHellman2 := dynamicaccess.NewDefaultSession(caller) - al1 := dynamicaccess.NewLogic(diffieHellman1) - al2 := dynamicaccess.NewLogic(diffieHellman2) + diffieHellman1 := accesscontrol.NewDefaultSession(publisher) + diffieHellman2 := accesscontrol.NewDefaultSession(caller) + al1 := accesscontrol.NewLogic(diffieHellman1) + al2 := accesscontrol.NewLogic(diffieHellman2) ls := createLs() gls := loadsave.New(mockStorer.ChunkStore(), mockStorer.Cache(), requestPipelineFactory(context.Background(), mockStorer.Cache(), true, redundancy.NONE)) - c1 := dynamicaccess.NewController(al1) - c2 := dynamicaccess.NewController(al2) + c1 := accesscontrol.NewController(al1) + c2 := accesscontrol.NewController(al2) t.Run("get by publisher", func(t *testing.T) { addList := []*ecdsa.PublicKey{&grantee.PublicKey} @@ -290,7 +290,7 @@ func TestController_Get(t *testing.T) { assert.NoError(t, err) assert.True(t, reflect.DeepEqual(grantees, addList)) - gl, _ := dynamicaccess.NewGranteeListReference(ctx, ls, granteeRef) + gl, _ := accesscontrol.NewGranteeListReference(ctx, ls, granteeRef) assert.True(t, reflect.DeepEqual(gl.Get(), addList)) }) t.Run("get by non-publisher", func(t *testing.T) { diff --git a/pkg/dynamicaccess/grantee.go b/pkg/accesscontrol/grantee.go similarity index 79% rename from pkg/dynamicaccess/grantee.go rename to pkg/accesscontrol/grantee.go index 44832032754..902aebbf433 100644 --- a/pkg/dynamicaccess/grantee.go +++ b/pkg/accesscontrol/grantee.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess +package accesscontrol import ( "context" @@ -20,6 +20,15 @@ const ( publicKeyLen = 65 ) +var ( + // ErrNothingToRemove indicates that the remove list is empty. + ErrNothingToRemove = errors.New("nothing to remove") + // ErrNoGranteeFound indicates that the grantee list is empty. + ErrNoGranteeFound = errors.New("no grantee found") + // ErrNothingToAdd indicates that the add list is empty. + ErrNothingToAdd = errors.New("nothing to add") +) + // GranteeList manages a list of public keys. type GranteeList interface { // Add adds a list of public keys to the grantee list. It filters out duplicates. @@ -32,6 +41,7 @@ type GranteeList interface { Save(ctx context.Context) (swarm.Address, error) } +// GranteeListStruct represents a list of grantee public keys. type GranteeListStruct struct { grantees []*ecdsa.PublicKey loadSave file.LoadSaver @@ -39,13 +49,15 @@ type GranteeListStruct struct { var _ GranteeList = (*GranteeListStruct)(nil) +// Get simply returns the list of public keys. func (g *GranteeListStruct) Get() []*ecdsa.PublicKey { return g.grantees } +// Add adds a list of public keys to the grantee list. It filters out duplicates. func (g *GranteeListStruct) Add(addList []*ecdsa.PublicKey) error { if len(addList) == 0 { - return fmt.Errorf("no public key provided") + return ErrNothingToAdd } filteredList := make([]*ecdsa.PublicKey, 0, len(addList)) for _, addkey := range addList { @@ -71,6 +83,7 @@ func (g *GranteeListStruct) Add(addList []*ecdsa.PublicKey) error { return nil } +// Save saves the grantee list to the underlying storage and returns the reference. func (g *GranteeListStruct) Save(ctx context.Context) (swarm.Address, error) { data := serialize(g.grantees) refBytes, err := g.loadSave.Save(ctx, data) @@ -81,11 +94,7 @@ func (g *GranteeListStruct) Save(ctx context.Context) (swarm.Address, error) { return swarm.NewAddress(refBytes), nil } -var ( - ErrNothingToRemove = errors.New("nothing to remove") - ErrNoGranteeFound = errors.New("no grantee found") -) - +// Remove removes a list of public keys from the grantee list, if there is any. func (g *GranteeListStruct) Remove(keysToRemove []*ecdsa.PublicKey) error { if len(keysToRemove) == 0 { return ErrNothingToRemove @@ -109,17 +118,19 @@ func (g *GranteeListStruct) Remove(keysToRemove []*ecdsa.PublicKey) error { return nil } -func NewGranteeList(ls file.LoadSaver) (*GranteeListStruct, error) { // Why is the error necessary? +// NewGranteeList creates a new (and empty) grantee list. +func NewGranteeList(ls file.LoadSaver) *GranteeListStruct { return &GranteeListStruct{ grantees: []*ecdsa.PublicKey{}, loadSave: ls, - }, nil + } } +// NewGranteeListReference loads an existing grantee list. func NewGranteeListReference(ctx context.Context, ls file.LoadSaver, reference swarm.Address) (*GranteeListStruct, error) { data, err := ls.Load(ctx, reference.Bytes()) if err != nil { - return nil, fmt.Errorf("unable to load reference, %w", err) + return nil, fmt.Errorf("failed to load grantee list reference, %w", err) } grantees := deserialize(data) diff --git a/pkg/dynamicaccess/grantee_test.go b/pkg/accesscontrol/grantee_test.go similarity index 87% rename from pkg/dynamicaccess/grantee_test.go rename to pkg/accesscontrol/grantee_test.go index f9a9b0904f8..095029fb0ca 100644 --- a/pkg/dynamicaccess/grantee_test.go +++ b/pkg/accesscontrol/grantee_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess_test +package accesscontrol_test import ( "context" @@ -11,7 +11,7 @@ import ( "testing" "github.com/btcsuite/btcd/btcec/v2" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" "github.com/ethersphere/bee/v2/pkg/file" "github.com/ethersphere/bee/v2/pkg/file/loadsave" "github.com/ethersphere/bee/v2/pkg/file/pipeline" @@ -53,7 +53,7 @@ func generateKeyListFixture() ([]*ecdsa.PublicKey, error) { func TestGranteeAddGet(t *testing.T) { t.Parallel() - gl, _ := dynamicaccess.NewGranteeList(createLs()) + gl := accesscontrol.NewGranteeList(createLs()) keys, err := generateKeyListFixture() if err != nil { t.Errorf("key generation error: %v", err) @@ -66,10 +66,10 @@ func TestGranteeAddGet(t *testing.T) { t.Run("Get should return value equal to put value", func(t *testing.T) { var ( - keys2, _ = generateKeyListFixture() - addList1 []*ecdsa.PublicKey = []*ecdsa.PublicKey{keys[0]} - addList2 []*ecdsa.PublicKey = []*ecdsa.PublicKey{keys[1], keys[2]} - addList3 []*ecdsa.PublicKey = keys2 + keys2, _ = generateKeyListFixture() + addList1 = []*ecdsa.PublicKey{keys[0]} + addList2 = []*ecdsa.PublicKey{keys[1], keys[2]} + addList3 = keys2 ) testCases := []struct { name string @@ -118,7 +118,7 @@ func TestGranteeAddGet(t *testing.T) { func TestGranteeRemove(t *testing.T) { t.Parallel() - gl, _ := dynamicaccess.NewGranteeList(createLs()) + gl := accesscontrol.NewGranteeList(createLs()) keys, err := generateKeyListFixture() if err != nil { t.Errorf("key generation error: %v", err) @@ -172,17 +172,17 @@ func TestGranteeSave(t *testing.T) { t.Errorf("key generation error: %v", err) } t.Run("Create grantee list with invalid reference, expect error", func(t *testing.T) { - gl, err := dynamicaccess.NewGranteeListReference(ctx, createLs(), swarm.RandAddress(t)) + gl, err := accesscontrol.NewGranteeListReference(ctx, createLs(), swarm.RandAddress(t)) assert.Error(t, err) assert.Nil(t, gl) }) t.Run("Save empty grantee list return NO error", func(t *testing.T) { - gl, _ := dynamicaccess.NewGranteeList(createLs()) + gl := accesscontrol.NewGranteeList(createLs()) _, err := gl.Save(ctx) assert.NoError(t, err) }) t.Run("Save not empty grantee list return valid swarm address", func(t *testing.T) { - gl, _ := dynamicaccess.NewGranteeList(createLs()) + gl := accesscontrol.NewGranteeList(createLs()) err = gl.Add(keys) ref, err := gl.Save(ctx) assert.NoError(t, err) @@ -190,7 +190,7 @@ func TestGranteeSave(t *testing.T) { }) t.Run("Save grantee list with one item, no error, pre-save value exist", func(t *testing.T) { ls := createLs() - gl1, _ := dynamicaccess.NewGranteeList(ls) + gl1 := accesscontrol.NewGranteeList(ls) err := gl1.Add(keys) assert.NoError(t, err) @@ -198,7 +198,7 @@ func TestGranteeSave(t *testing.T) { ref, err := gl1.Save(ctx) assert.NoError(t, err) - gl2, _ := dynamicaccess.NewGranteeListReference(ctx, ls, ref) + gl2, _ := accesscontrol.NewGranteeListReference(ctx, ls, ref) val := gl2.Get() assert.NoError(t, err) assert.Equal(t, keys, val) @@ -207,14 +207,14 @@ func TestGranteeSave(t *testing.T) { ls := createLs() keys2, _ := generateKeyListFixture() - gl1, _ := dynamicaccess.NewGranteeList(ls) + gl1 := accesscontrol.NewGranteeList(ls) err := gl1.Add(keys) assert.NoError(t, err) ref, err := gl1.Save(ctx) assert.NoError(t, err) - gl2, _ := dynamicaccess.NewGranteeListReference(ctx, ls, ref) + gl2, _ := accesscontrol.NewGranteeListReference(ctx, ls, ref) err = gl2.Add(keys2) assert.NoError(t, err) @@ -224,7 +224,7 @@ func TestGranteeSave(t *testing.T) { } func TestGranteeRemoveTwo(t *testing.T) { - gl, _ := dynamicaccess.NewGranteeList(createLs()) + gl := accesscontrol.NewGranteeList(createLs()) keys, err := generateKeyListFixture() if err != nil { t.Errorf("key generation error: %v", err) diff --git a/pkg/dynamicaccess/history.go b/pkg/accesscontrol/history.go similarity index 74% rename from pkg/dynamicaccess/history.go rename to pkg/accesscontrol/history.go index 27485e95f95..a5a203834f2 100644 --- a/pkg/dynamicaccess/history.go +++ b/pkg/accesscontrol/history.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess +package accesscontrol import ( "context" @@ -18,24 +18,34 @@ import ( "github.com/ethersphere/bee/v2/pkg/swarm" ) +var ( + // ErrEndIteration indicates that the iteration terminated. + ErrEndIteration = errors.New("end iteration") + // ErrUnexpectedType indicates that an error occurred during the mantary-manifest creation. + ErrUnexpectedType = errors.New("unexpected type") + // ErrInvalidTimestamp indicates that the timestamp given to Lookup is invalid. + ErrInvalidTimestamp = errors.New("invalid timestamp") +) + +// History represents the interface for managing access control history. type History interface { + // Add adds a new entry to the access control history with the given timestamp and metadata. Add(ctx context.Context, ref swarm.Address, timestamp *int64, metadata *map[string]string) error + // Lookup retrieves the entry from the history based on the given timestamp or returns error if not found. Lookup(ctx context.Context, timestamp int64) (manifest.Entry, error) + // Store stores the history to the underlying storage and returns the reference. Store(ctx context.Context) (swarm.Address, error) } var _ History = (*HistoryStruct)(nil) -var ( - ErrEndIteration = errors.New("end iteration") - ErrUnexpectedType = errors.New("unexpected type") -) - +// HistoryStruct represents an access control histroy with a mantaray-based manifest. type HistoryStruct struct { manifest *manifest.MantarayManifest ls file.LoadSaver } +// NewHistory creates a new history with a mantaray-based manifest. func NewHistory(ls file.LoadSaver) (*HistoryStruct, error) { m, err := manifest.NewDefaultManifest(ls, false) if err != nil { @@ -50,10 +60,11 @@ func NewHistory(ls file.LoadSaver) (*HistoryStruct, error) { return &HistoryStruct{manifest: mm, ls: ls}, nil } +// NewHistoryReference loads a history with a mantaray-based manifest. func NewHistoryReference(ls file.LoadSaver, ref swarm.Address) (*HistoryStruct, error) { m, err := manifest.NewDefaultManifestReference(ref, ls) if err != nil { - return nil, fmt.Errorf("failed to create default manifest: %w", err) + return nil, fmt.Errorf("failed to create default manifest reference: %w", err) } mm, ok := m.(*manifest.MantarayManifest) @@ -64,26 +75,28 @@ func NewHistoryReference(ls file.LoadSaver, ref swarm.Address) (*HistoryStruct, return &HistoryStruct{manifest: mm, ls: ls}, nil } +// Add adds a new entry to the access control history with the given timestamp and metadata. func (h *HistoryStruct) Add(ctx context.Context, ref swarm.Address, timestamp *int64, metadata *map[string]string) error { mtdt := map[string]string{} if metadata != nil { mtdt = *metadata } - // add timestamps transformed so that the latests timestamp becomes the smallest key - var unixTime int64 + // add timestamps transformed so that the latests timestamp becomes the smallest key. + unixTime := time.Now().Unix() if timestamp != nil { unixTime = *timestamp - } else { - unixTime = time.Now().Unix() } key := strconv.FormatInt(math.MaxInt64-unixTime, 10) - return h.manifest.Add(ctx, key, manifest.NewEntry(ref, mtdt)) -} + err := h.manifest.Add(ctx, key, manifest.NewEntry(ref, mtdt)) + if err != nil { + return fmt.Errorf("failed to add to manifest: %w", err) + } -var ErrInvalidTimestamp = errors.New("invalid timestamp") + return nil +} -// Lookup finds the entry for a path or returns error if not found +// Lookup retrieves the entry from the history based on the given timestamp or returns error if not found. func (h *HistoryStruct) Lookup(ctx context.Context, timestamp int64) (manifest.Entry, error) { if timestamp <= 0 { return manifest.NewEntry(swarm.ZeroAddress, map[string]string{}), ErrInvalidTimestamp @@ -147,6 +160,7 @@ func (h *HistoryStruct) lookupNode(ctx context.Context, searchedTimestamp int64) return nil, nil } +// Store stores the history to the underlying storage and returns the reference. func (h *HistoryStruct) Store(ctx context.Context) (swarm.Address, error) { return h.manifest.Store(ctx) } diff --git a/pkg/dynamicaccess/history_test.go b/pkg/accesscontrol/history_test.go similarity index 94% rename from pkg/dynamicaccess/history_test.go rename to pkg/accesscontrol/history_test.go index 871b5241eab..a9c1aaa939f 100644 --- a/pkg/dynamicaccess/history_test.go +++ b/pkg/accesscontrol/history_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess_test +package accesscontrol_test import ( "context" @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" "github.com/ethersphere/bee/v2/pkg/file/loadsave" "github.com/ethersphere/bee/v2/pkg/file/pipeline" "github.com/ethersphere/bee/v2/pkg/file/pipeline/builder" @@ -22,7 +22,7 @@ import ( func TestHistoryAdd(t *testing.T) { t.Parallel() - h, err := dynamicaccess.NewHistory(nil) + h, err := accesscontrol.NewHistory(nil) assert.NoError(t, err) addr := swarm.NewAddress([]byte("addr")) @@ -39,7 +39,7 @@ func TestSingleNodeHistoryLookup(t *testing.T) { ctx := context.Background() ls := loadsave.New(storer.ChunkStore(), storer.Cache(), pipelineFactory(storer.Cache(), false)) - h, err := dynamicaccess.NewHistory(ls) + h, err := accesscontrol.NewHistory(ls) assert.NoError(t, err) testActRef := swarm.RandAddress(t) @@ -63,7 +63,7 @@ func TestMultiNodeHistoryLookup(t *testing.T) { ctx := context.Background() ls := loadsave.New(storer.ChunkStore(), storer.Cache(), pipelineFactory(storer.Cache(), false)) - h, _ := dynamicaccess.NewHistory(ls) + h, _ := accesscontrol.NewHistory(ls) testActRef1 := swarm.NewAddress([]byte("39a5ea87b141fe44aa609c3327ecd891")) firstTime := time.Date(1994, time.April, 1, 0, 0, 0, 0, time.UTC).Unix() @@ -129,7 +129,7 @@ func TestHistoryStore(t *testing.T) { ctx := context.Background() ls := loadsave.New(storer.ChunkStore(), storer.Cache(), pipelineFactory(storer.Cache(), false)) - h1, _ := dynamicaccess.NewHistory(ls) + h1, _ := accesscontrol.NewHistory(ls) testActRef1 := swarm.NewAddress([]byte("39a5ea87b141fe44aa609c3327ecd891")) firstTime := time.Date(1994, time.April, 1, 0, 0, 0, 0, time.UTC).Unix() @@ -139,7 +139,7 @@ func TestHistoryStore(t *testing.T) { href1, err := h1.Store(ctx) assert.NoError(t, err) - h2, err := dynamicaccess.NewHistoryReference(ls, href1) + h2, err := accesscontrol.NewHistoryReference(ls, href1) assert.NoError(t, err) entry1, _ := h2.Lookup(ctx, firstTime) diff --git a/pkg/kvs/kvs.go b/pkg/accesscontrol/kvs/kvs.go similarity index 58% rename from pkg/kvs/kvs.go rename to pkg/accesscontrol/kvs/kvs.go index 0c7eae48c08..6f5e35742b8 100644 --- a/pkg/kvs/kvs.go +++ b/pkg/accesscontrol/kvs/kvs.go @@ -2,21 +2,35 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package kvs provides functionalities needed +// for storing key-value pairs on Swarm. +// +//nolint:ireturn package kvs import ( "context" "encoding/hex" "errors" + "fmt" "github.com/ethersphere/bee/v2/pkg/file" "github.com/ethersphere/bee/v2/pkg/manifest" "github.com/ethersphere/bee/v2/pkg/swarm" ) +var ( + // ErrNothingToSave indicates that no new key-value pair was added to the store. + ErrNothingToSave = errors.New("nothing to save") +) + +// KeyValueStore represents a key-value store. type KeyValueStore interface { + // Get retrieves the value associated with the given key. Get(ctx context.Context, key []byte) ([]byte, error) + // Put stores the given key-value pair in the store. Put(ctx context.Context, key, value []byte) error + // Save saves key-value pair to the underlying storage and returns the reference. Save(ctx context.Context) (swarm.Address, error) } @@ -27,40 +41,44 @@ type keyValueStore struct { var _ KeyValueStore = (*keyValueStore)(nil) +// Get retrieves the value associated with the given key. func (s *keyValueStore) Get(ctx context.Context, key []byte) ([]byte, error) { entry, err := s.manifest.Lookup(ctx, hex.EncodeToString(key)) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get value from manifest %w", err) } ref := entry.Reference() return ref.Bytes(), nil } +// Put stores the given key-value pair in the store. func (s *keyValueStore) Put(ctx context.Context, key []byte, value []byte) error { err := s.manifest.Add(ctx, hex.EncodeToString(key), manifest.NewEntry(swarm.NewAddress(value), map[string]string{})) if err != nil { - return err + return fmt.Errorf("failed to put value to manifest %w", err) } s.putCnt++ return nil } +// Save saves key-value pair to the underlying storage and returns the reference. func (s *keyValueStore) Save(ctx context.Context) (swarm.Address, error) { if s.putCnt == 0 { - return swarm.ZeroAddress, errors.New("nothing to save") + return swarm.ZeroAddress, ErrNothingToSave } ref, err := s.manifest.Store(ctx) if err != nil { - return swarm.ZeroAddress, err + return swarm.ZeroAddress, fmt.Errorf("failed to store manifest %w", err) } s.putCnt = 0 return ref, nil } +// New creates a new key-value store with a simple manifest. func New(ls file.LoadSaver) (KeyValueStore, error) { m, err := manifest.NewSimpleManifest(ls) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create simple manifest: %w", err) } return &keyValueStore{ @@ -68,10 +86,11 @@ func New(ls file.LoadSaver) (KeyValueStore, error) { }, nil } +// NewReference loads a key-value store with a simple manifest. func NewReference(ls file.LoadSaver, ref swarm.Address) (KeyValueStore, error) { m, err := manifest.NewSimpleManifestReference(ref, ls) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create simple manifest reference: %w", err) } return &keyValueStore{ diff --git a/pkg/kvs/kvs_test.go b/pkg/accesscontrol/kvs/kvs_test.go similarity index 96% rename from pkg/kvs/kvs_test.go rename to pkg/accesscontrol/kvs/kvs_test.go index 2f9af999a95..90abac1adfa 100644 --- a/pkg/kvs/kvs_test.go +++ b/pkg/accesscontrol/kvs/kvs_test.go @@ -2,24 +2,26 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//nolint:ireturn package kvs_test import ( "context" "testing" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs" "github.com/ethersphere/bee/v2/pkg/file" "github.com/ethersphere/bee/v2/pkg/file/loadsave" "github.com/ethersphere/bee/v2/pkg/file/pipeline" "github.com/ethersphere/bee/v2/pkg/file/pipeline/builder" "github.com/ethersphere/bee/v2/pkg/file/redundancy" - "github.com/ethersphere/bee/v2/pkg/kvs" "github.com/ethersphere/bee/v2/pkg/storage" mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" "github.com/ethersphere/bee/v2/pkg/swarm" "github.com/stretchr/testify/assert" ) +//nolint:gochecknoglobals var mockStorer = mockstorer.New() func requestPipelineFactory(ctx context.Context, s storage.Putter, encrypt bool, rLevel redundancy.Level) func() pipeline.Interface { @@ -66,9 +68,9 @@ func TestKvs(t *testing.T) { t.Run("Get should return value equal to put value", func(t *testing.T) { var ( - key1 []byte = []byte{1} - key2 []byte = []byte{2} - key3 []byte = []byte{3} + key1 = []byte{1} + key2 = []byte{2} + key3 = []byte{3} ) testCases := []struct { name string diff --git a/pkg/kvs/mock/kvs.go b/pkg/accesscontrol/kvs/mock/kvs.go similarity index 93% rename from pkg/kvs/mock/kvs.go rename to pkg/accesscontrol/kvs/mock/kvs.go index f5818972004..bdd0d54cc12 100644 --- a/pkg/kvs/mock/kvs.go +++ b/pkg/accesscontrol/kvs/mock/kvs.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package mock provides an in-memory key-value store implementation. package mock import ( @@ -9,7 +10,7 @@ import ( "encoding/hex" "sync" - "github.com/ethersphere/bee/v2/pkg/kvs" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs" "github.com/ethersphere/bee/v2/pkg/swarm" ) diff --git a/pkg/dynamicaccess/mock/controller.go b/pkg/accesscontrol/mock/controller.go similarity index 88% rename from pkg/dynamicaccess/mock/controller.go rename to pkg/accesscontrol/mock/controller.go index 30f617bfccb..15e87e6ce0c 100644 --- a/pkg/dynamicaccess/mock/controller.go +++ b/pkg/accesscontrol/mock/controller.go @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package mock provides a mock implementation for the +// access control functionalities. +// +//nolint:ireturn package mock import ( @@ -11,8 +15,8 @@ import ( "fmt" "time" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" "github.com/ethersphere/bee/v2/pkg/encryption" "github.com/ethersphere/bee/v2/pkg/file" "github.com/ethersphere/bee/v2/pkg/file/loadsave" @@ -26,7 +30,7 @@ import ( ) type mockController struct { - historyMap map[string]dynamicaccess.History + historyMap map[string]accesscontrol.History refMap map[string]swarm.Address acceptAll bool publisher string @@ -36,18 +40,18 @@ type mockController struct { type optionFunc func(*mockController) -// Option is an option passed to a mock dynamicaccess Service. +// Option is an option passed to a mock accesscontrol Controller. type Option interface { apply(*mockController) } func (f optionFunc) apply(r *mockController) { f(r) } -// New creates a new mock dynamicaccess service. -func New(o ...Option) dynamicaccess.Controller { +// New creates a new mock accesscontrol Controller. +func New(o ...Option) accesscontrol.Controller { storer := mockstorer.New() m := &mockController{ - historyMap: make(map[string]dynamicaccess.History), + historyMap: make(map[string]accesscontrol.History), refMap: make(map[string]swarm.Address), publisher: "", encrypter: encryption.New(encryption.Key("b6ee086390c280eeb9824c331a4427596f0c8510d5564bc1b6168d0059a46e2b"), 0, uint32(0), sha3.NewLegacyKeccak256), @@ -65,12 +69,14 @@ func WithAcceptAll() Option { return optionFunc(func(m *mockController) { m.acceptAll = true }) } -func WithHistory(h dynamicaccess.History, ref string) Option { +// WithHistory sets the mock to use the given history reference. +func WithHistory(h accesscontrol.History, ref string) Option { return optionFunc(func(m *mockController) { - m.historyMap = map[string]dynamicaccess.History{ref: h} + m.historyMap = map[string]accesscontrol.History{ref: h} }) } +// WithPublisher sets the mock to use the given reference as the publisher address. func WithPublisher(ref string) Option { return optionFunc(func(m *mockController) { m.publisher = ref @@ -109,7 +115,7 @@ func (m *mockController) UploadHandler(ctx context.Context, ls file.LoadSaver, r return kvsRef, historyRef, encryptedRef, nil } var ( - h dynamicaccess.History + h accesscontrol.History exists bool ) now := time.Now().Unix() @@ -125,7 +131,7 @@ func (m *mockController) UploadHandler(ctx context.Context, ls file.LoadSaver, r return swarm.ZeroAddress, swarm.ZeroAddress, swarm.ZeroAddress, fmt.Errorf("kvs not found") } } else { - h, _ = dynamicaccess.NewHistory(m.ls) + h, _ = accesscontrol.NewHistory(m.ls) _ = h.Add(ctx, kvsRef, &now, nil) historyRef, _ = h.Store(ctx) m.historyMap[historyRef.String()] = h @@ -180,4 +186,4 @@ func requestPipelineFactory(ctx context.Context, s storage.Putter, encrypt bool, } } -var _ dynamicaccess.Controller = (*mockController)(nil) +var _ accesscontrol.Controller = (*mockController)(nil) diff --git a/pkg/dynamicaccess/mock/grantee.go b/pkg/accesscontrol/mock/grantee.go similarity index 100% rename from pkg/dynamicaccess/mock/grantee.go rename to pkg/accesscontrol/mock/grantee.go diff --git a/pkg/dynamicaccess/mock/session.go b/pkg/accesscontrol/mock/session.go similarity index 100% rename from pkg/dynamicaccess/mock/session.go rename to pkg/accesscontrol/mock/session.go diff --git a/pkg/dynamicaccess/session.go b/pkg/accesscontrol/session.go similarity index 69% rename from pkg/dynamicaccess/session.go rename to pkg/accesscontrol/session.go index fb1f44241be..a571337c17d 100644 --- a/pkg/dynamicaccess/session.go +++ b/pkg/accesscontrol/session.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess +package accesscontrol import ( "crypto/ecdsa" @@ -10,26 +10,29 @@ import ( "fmt" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/keystore" ) -// Session represents an interface for a Diffie-Helmann key derivation +var ( + // ErrInvalidPublicKey is an error that is returned when a public key is nil. + ErrInvalidPublicKey = errors.New("invalid public key") + // ErrSecretKeyInfinity is an error that is returned when the shared secret is a point at infinity. + ErrSecretKeyInfinity = errors.New("shared secret is point at infinity") +) + +// Session represents an interface for a Diffie-Hellmann key derivation type Session interface { - // Key returns a derived key for each nonce + // Key returns a derived key for each nonce. Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]byte, error) } var _ Session = (*SessionStruct)(nil) +// SessionStruct represents a session with an access control key. type SessionStruct struct { key *ecdsa.PrivateKey } -var ( - ErrInvalidPublicKey = errors.New("invalid public key") - ErrSecretKeyInfinity = errors.New("shared secret is point at infinity") -) - +// Key returns a derived key for each nonce. func (s *SessionStruct) Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]byte, error) { if publicKey == nil { return nil, ErrInvalidPublicKey @@ -55,13 +58,9 @@ func (s *SessionStruct) Key(publicKey *ecdsa.PublicKey, nonces [][]byte) ([][]by return keys, nil } +// NewDefaultSession creates a new session from a private key. func NewDefaultSession(key *ecdsa.PrivateKey) *SessionStruct { return &SessionStruct{ key: key, } } - -// Currently implemented only in mock/session.go -func NewFromKeystore(keystore.Service, string, string) Session { - return nil -} diff --git a/pkg/dynamicaccess/session_test.go b/pkg/accesscontrol/session_test.go similarity index 84% rename from pkg/dynamicaccess/session_test.go rename to pkg/accesscontrol/session_test.go index 701384b93bb..60b175b01a3 100644 --- a/pkg/dynamicaccess/session_test.go +++ b/pkg/accesscontrol/session_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package dynamicaccess_test +package accesscontrol_test import ( "bytes" @@ -12,9 +12,9 @@ import ( "io" "testing" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" + "github.com/ethersphere/bee/v2/pkg/accesscontrol/mock" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess/mock" memkeystore "github.com/ethersphere/bee/v2/pkg/keystore/mem" ) @@ -27,7 +27,7 @@ func TestSessionNewDefaultSession(t *testing.T) { if err != nil { t.Fatalf("Error generating private key: %v", err) } - si := dynamicaccess.NewDefaultSession(pk) + si := accesscontrol.NewDefaultSession(pk) if si == nil { t.Fatal("Session instance is nil") } @@ -48,13 +48,13 @@ func TestSessionKey(t *testing.T) { if err != nil { t.Fatal(err) } - si1 := dynamicaccess.NewDefaultSession(key1) + si1 := accesscontrol.NewDefaultSession(key1) key2, err := crypto.GenerateSecp256k1Key() if err != nil { t.Fatal(err) } - si2 := dynamicaccess.NewDefaultSession(key2) + si2 := accesscontrol.NewDefaultSession(key2) nonces := make([][]byte, 2) for i := range nonces { @@ -87,13 +87,13 @@ func TestSessionKeyWithoutNonces(t *testing.T) { if err != nil { t.Fatal(err) } - si1 := dynamicaccess.NewDefaultSession(key1) + si1 := accesscontrol.NewDefaultSession(key1) key2, err := crypto.GenerateSecp256k1Key() if err != nil { t.Fatal(err) } - si2 := dynamicaccess.NewDefaultSession(key2) + si2 := accesscontrol.NewDefaultSession(key2) keys1, err := si1.Key(&key2.PublicKey, nil) if err != nil { @@ -119,7 +119,6 @@ func TestSessionKeyFromKeystore(t *testing.T) { password2 := "password2" si1 := mock.NewFromKeystore(ks, tag1, password1, mockKeyFunc) - // si1 := dynamicaccess.NewFromKeystore(ks, tag1, password1) exists, err := ks.Exists(tag1) if err != nil { t.Fatal(err) @@ -136,7 +135,6 @@ func TestSessionKeyFromKeystore(t *testing.T) { } si2 := mock.NewFromKeystore(ks, tag2, password2, mockKeyFunc) - // si2 := dynamicaccess.NewFromKeystore(ks, tag2, password2) exists, err = ks.Exists(tag2) if err != nil { t.Fatal(err) @@ -171,7 +169,4 @@ func TestSessionKeyFromKeystore(t *testing.T) { if !bytes.Equal(keys1[0], keys2[0]) { t.Fatalf("shared secrets do not match %s, %s", hex.EncodeToString(keys1[0]), hex.EncodeToString(keys2[0])) } - // if !bytes.Equal(keys1[1], keys2[1]) { - // t.Fatalf("shared secrets do not match %s, %s", hex.EncodeToString(keys1[0]), hex.EncodeToString(keys2[0])) - // } } diff --git a/pkg/api/dynamicaccess.go b/pkg/api/accesscontrol.go similarity index 87% rename from pkg/api/dynamicaccess.go rename to pkg/api/accesscontrol.go index f83f0cca435..11c0453014c 100644 --- a/pkg/api/dynamicaccess.go +++ b/pkg/api/accesscontrol.go @@ -31,7 +31,7 @@ type addressKey struct{} const granteeListEncrypt = true -// getAddressFromContext is a helper function to extract the address from the context +// getAddressFromContext is a helper function to extract the address from the context. func getAddressFromContext(ctx context.Context) swarm.Address { v, ok := ctx.Value(addressKey{}).(swarm.Address) if ok { @@ -40,37 +40,52 @@ func getAddressFromContext(ctx context.Context) swarm.Address { return swarm.ZeroAddress } -// setAddressInContext sets the swarm address in the context +// setAddressInContext sets the swarm address in the context. func setAddressInContext(ctx context.Context, address swarm.Address) context.Context { return context.WithValue(ctx, addressKey{}, address) } +// GranteesPatchRequest represents a request to patch the list of grantees. type GranteesPatchRequest struct { - Addlist []string `json:"add"` + // Addlist contains the list of grantees to add. + Addlist []string `json:"add"` + + // Revokelist contains the list of grantees to revoke. Revokelist []string `json:"revoke"` } +// GranteesPatchResponse represents the response structure for patching grantees. type GranteesPatchResponse struct { - Reference swarm.Address `json:"ref"` + // Reference represents the swarm address. + Reference swarm.Address `json:"ref"` + // HistoryReference represents the reference to the history of an access control entry. HistoryReference swarm.Address `json:"historyref"` } +// GranteesPostRequest represents the request structure for adding grantees. type GranteesPostRequest struct { + // GranteeList represents the list of grantees to be saves on Swarm. GranteeList []string `json:"grantees"` } +// GranteesPostResponse represents the response structure for adding grantees. type GranteesPostResponse struct { - Reference swarm.Address `json:"ref"` + // Reference represents the saved grantee list Swarm address. + Reference swarm.Address `json:"ref"` + // HistoryReference represents the reference to the history of an access control entry. HistoryReference swarm.Address `json:"historyref"` } +// GranteesPatch represents a structure for modifying the list of grantees. type GranteesPatch struct { - Addlist []*ecdsa.PublicKey + // Addlist is a list of ecdsa.PublicKeys to be added to a grantee list. + Addlist []*ecdsa.PublicKey + // Revokelist is a list of ecdsa.PublicKeys to be removed from a grantee list Revokelist []*ecdsa.PublicKey } // actDecryptionHandler is a middleware that looks up and decrypts the given address, -// if the act headers are present +// if the act headers are present. func (s *Service) actDecryptionHandler() func(h http.Handler) http.Handler { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -111,7 +126,7 @@ func (s *Service) actDecryptionHandler() func(h http.Handler) http.Handler { } ctx := r.Context() ls := loadsave.NewReadonly(s.storer.Download(cache)) - reference, err := s.dac.DownloadHandler(ctx, ls, paths.Address, headers.Publisher, *headers.HistoryAddress, timestamp) + reference, err := s.accesscontrol.DownloadHandler(ctx, ls, paths.Address, headers.Publisher, *headers.HistoryAddress, timestamp) if err != nil { logger.Debug("act failed to decrypt reference", "error", err) logger.Error(nil, "act failed to decrypt reference") @@ -124,7 +139,7 @@ func (s *Service) actDecryptionHandler() func(h http.Handler) http.Handler { } // actEncryptionHandler is a middleware that encrypts the given address using the publisher's public key, -// uploads the encrypted reference, history and kvs to the store +// uploads the encrypted reference, history and kvs to the store. func (s *Service) actEncryptionHandler( ctx context.Context, w http.ResponseWriter, @@ -135,7 +150,7 @@ func (s *Service) actEncryptionHandler( logger := s.logger.WithName("act_encryption_handler").Build() publisherPublicKey := &s.publicKey ls := loadsave.New(s.storer.Download(true), s.storer.Cache(), requestPipelineFactory(ctx, putter, false, redundancy.NONE)) - storageReference, historyReference, encryptedReference, err := s.dac.UploadHandler(ctx, ls, reference, publisherPublicKey, historyRootHash) + storageReference, historyReference, encryptedReference, err := s.accesscontrol.UploadHandler(ctx, ls, reference, publisherPublicKey, historyRootHash) if err != nil { logger.Debug("act failed to encrypt reference", "error", err) logger.Error(nil, "act failed to encrypt reference") @@ -163,7 +178,7 @@ func (s *Service) actEncryptionHandler( } // actListGranteesHandler is a middleware that decrypts the given address and returns the list of grantees, -// only the publisher is authorized to access the list +// only the publisher is authorized to access the list. func (s *Service) actListGranteesHandler(w http.ResponseWriter, r *http.Request) { logger := s.logger.WithName("act_list_grantees_handler").Build() paths := struct { @@ -187,7 +202,7 @@ func (s *Service) actListGranteesHandler(w http.ResponseWriter, r *http.Request) } publisher := &s.publicKey ls := loadsave.NewReadonly(s.storer.Download(cache)) - grantees, err := s.dac.Get(r.Context(), ls, publisher, paths.GranteesAddress) + grantees, err := s.accesscontrol.Get(r.Context(), ls, publisher, paths.GranteesAddress) if err != nil { logger.Debug("could not get grantees", "error", err) logger.Error(nil, "could not get grantees") @@ -202,7 +217,7 @@ func (s *Service) actListGranteesHandler(w http.ResponseWriter, r *http.Request) } // actGrantRevokeHandler is a middleware that makes updates to the list of grantees, -// only the publisher is authorized to perform this action +// only the publisher is authorized to perform this action. func (s *Service) actGrantRevokeHandler(w http.ResponseWriter, r *http.Request) { logger := s.logger.WithName("act_grant_revoke_handler").Build() @@ -328,7 +343,7 @@ func (s *Service) actGrantRevokeHandler(w http.ResponseWriter, r *http.Request) publisher := &s.publicKey ls := loadsave.New(s.storer.Download(true), s.storer.Cache(), requestPipelineFactory(ctx, putter, false, redundancy.NONE)) gls := loadsave.New(s.storer.Download(true), s.storer.Cache(), requestPipelineFactory(ctx, putter, granteeListEncrypt, redundancy.NONE)) - granteeref, encryptedglref, historyref, actref, err := s.dac.UpdateHandler(ctx, ls, gls, granteeref, historyAddress, publisher, grantees.Addlist, grantees.Revokelist) + granteeref, encryptedglref, historyref, actref, err := s.accesscontrol.UpdateHandler(ctx, ls, gls, granteeref, historyAddress, publisher, grantees.Addlist, grantees.Revokelist) if err != nil { logger.Debug("failed to update grantee list", "error", err) logger.Error(nil, "failed to update grantee list") @@ -367,7 +382,7 @@ func (s *Service) actGrantRevokeHandler(w http.ResponseWriter, r *http.Request) } // actCreateGranteesHandler is a middleware that creates a new list of grantees, -// only the publisher is authorized to perform this action +// only the publisher is authorized to perform this action. func (s *Service) actCreateGranteesHandler(w http.ResponseWriter, r *http.Request) { logger := s.logger.WithName("acthandler").Build() @@ -473,7 +488,7 @@ func (s *Service) actCreateGranteesHandler(w http.ResponseWriter, r *http.Reques publisher := &s.publicKey ls := loadsave.New(s.storer.Download(true), s.storer.Cache(), requestPipelineFactory(ctx, putter, false, redundancy.NONE)) gls := loadsave.New(s.storer.Download(true), s.storer.Cache(), requestPipelineFactory(ctx, putter, granteeListEncrypt, redundancy.NONE)) - granteeref, encryptedglref, historyref, actref, err := s.dac.UpdateHandler(ctx, ls, gls, swarm.ZeroAddress, historyAddress, publisher, list, nil) + granteeref, encryptedglref, historyref, actref, err := s.accesscontrol.UpdateHandler(ctx, ls, gls, swarm.ZeroAddress, historyAddress, publisher, list, nil) if err != nil { logger.Debug("failed to update grantee list", "error", err) logger.Error(nil, "failed to update grantee list") @@ -516,11 +531,11 @@ func parseKeys(list []string) ([]*ecdsa.PublicKey, error) { for _, g := range list { h, err := hex.DecodeString(g) if err != nil { - return []*ecdsa.PublicKey{}, err + return []*ecdsa.PublicKey{}, fmt.Errorf("failed to decode grantee: %w", err) } k, err := btcec.ParsePubKey(h) if err != nil { - return []*ecdsa.PublicKey{}, err + return []*ecdsa.PublicKey{}, fmt.Errorf("failed to parse grantee public key: %w", err) } parsedList = append(parsedList, k.ToECDSA()) } diff --git a/pkg/api/dynamicaccess_test.go b/pkg/api/accesscontrol_test.go similarity index 89% rename from pkg/api/dynamicaccess_test.go rename to pkg/api/accesscontrol_test.go index 79eac36327b..11b3e02f28e 100644 --- a/pkg/api/dynamicaccess_test.go +++ b/pkg/api/accesscontrol_test.go @@ -16,10 +16,10 @@ import ( "testing" "time" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" + mockac "github.com/ethersphere/bee/v2/pkg/accesscontrol/mock" "github.com/ethersphere/bee/v2/pkg/api" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" - mockdac "github.com/ethersphere/bee/v2/pkg/dynamicaccess/mock" "github.com/ethersphere/bee/v2/pkg/file/loadsave" "github.com/ethersphere/bee/v2/pkg/file/redundancy" "github.com/ethersphere/bee/v2/pkg/jsonhttp" @@ -32,11 +32,12 @@ import ( "gitlab.com/nolash/go-mockbytes" ) -func prepareHistoryFixture(storer api.Storer) (dynamicaccess.History, swarm.Address) { +//nolint:ireturn +func prepareHistoryFixture(storer api.Storer) (accesscontrol.History, swarm.Address) { ctx := context.Background() ls := loadsave.New(storer.ChunkStore(), storer.Cache(), pipelineFactory(storer.Cache(), false, redundancy.NONE)) - h, _ := dynamicaccess.NewHistory(ls) + h, _ := accesscontrol.NewHistory(ls) testActRef1 := swarm.NewAddress([]byte("39a5ea87b141fe44aa609c3327ecd891")) firstTime := time.Date(1994, time.April, 1, 0, 0, 0, 0, time.UTC).Unix() @@ -65,9 +66,9 @@ func prepareHistoryFixture(storer api.Storer) (dynamicaccess.History, swarm.Addr // TODO: test tag, pin, deferred, stamp // TODO: feed test // nolint:paralleltest,tparallel -// TestDacWithoutActHeader [positive tests]: +// TestAccessLogicEachEndpointWithAct [positive tests]: // On each endpoint: upload w/ "Swarm-Act" header then download and check the decrypted data -func TestDacEachEndpointWithAct(t *testing.T) { +func TestAccessLogicEachEndpointWithAct(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -185,11 +186,11 @@ func TestDacEachEndpointWithAct(t *testing.T) { } t.Run(v.name, func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(), }) header := jsonhttptest.Request(t, client, http.MethodPost, v.upurl, http.StatusCreated, upTestOpts..., @@ -221,12 +222,12 @@ func TestDacEachEndpointWithAct(t *testing.T) { } } -// TestDacWithoutActHeader [negative tests]: +// TestAccessLogicWithoutActHeader [negative tests]: // 1. upload w/ "Swarm-Act" header then try to dowload w/o the header. // 2. upload w/o "Swarm-Act" header then try to dowload w/ the header. // //nolint:paralleltest,tparallel -func TestDacWithoutAct(t *testing.T) { +func TestAccessLogicWithoutAct(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -244,11 +245,11 @@ func TestDacWithoutAct(t *testing.T) { t.Run("upload-w/-act-then-download-w/o-act", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) var ( testfile = "testfile1" @@ -277,11 +278,11 @@ func TestDacWithoutAct(t *testing.T) { t.Run("upload-w/o-act-then-download-w/-act", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(), }) var ( rootHash = "0cb947ccbc410c43139ba4409d83bf89114cb0d79556a651c06c888cf73f4d7e" @@ -322,10 +323,10 @@ func TestDacWithoutAct(t *testing.T) { }) } -// TestDacInvalidPath [negative test]: Expect Bad request when the path address is invalid. +// TestAccessLogicInvalidPath [negative test]: Expect Bad request when the path address is invalid. // //nolint:paralleltest,tparallel -func TestDacInvalidPath(t *testing.T) { +func TestAccessLogicInvalidPath(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -341,11 +342,11 @@ func TestDacInvalidPath(t *testing.T) { t.Run("invalid-path-params", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(), }) encryptedRef := "asd" @@ -369,12 +370,12 @@ func TestDacInvalidPath(t *testing.T) { } // nolint:paralleltest,tparallel -// TestDacHistory tests: +// TestAccessLogicHistory tests: // [positive tests] 1., 2.: uploading a file w/ and w/o history address then downloading it and checking the data. // [negative test] 3. uploading a file then downloading it with a wrong history address. // [negative test] 4. uploading a file to a wrong history address. // [negative test] 5. downloading a file to w/o history address. -func TestDacHistory(t *testing.T) { +func TestAccessLogicHistory(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -392,11 +393,11 @@ func TestDacHistory(t *testing.T) { t.Run("empty-history-upload-then-download-and-check-data", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(), }) var ( testfile = "testfile1" @@ -428,11 +429,11 @@ func TestDacHistory(t *testing.T) { t.Run("with-history-upload-then-download-and-check-data", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) var ( encryptedRef = "c611199e1b3674d6bf89a83e518bd16896bf5315109b4a23dcb4682a02d17b97" @@ -474,11 +475,11 @@ func TestDacHistory(t *testing.T) { t.Run("upload-then-download-wrong-history", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) var ( testfile = "testfile1" @@ -510,11 +511,11 @@ func TestDacHistory(t *testing.T) { t.Run("upload-wrong-history", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(), }) testfile := "testfile1" @@ -533,11 +534,11 @@ func TestDacHistory(t *testing.T) { t.Run("download-w/o-history", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) encryptedRef := "a5df670544eaea29e61b19d8739faa4573b19e4426e58a173e51ed0b5e7e2ade" @@ -550,10 +551,10 @@ func TestDacHistory(t *testing.T) { } // nolint:paralleltest,tparallel -// TestDacTimestamp +// TestAccessLogicTimestamp // [positive test] 1.: uploading a file w/ ACT then download it w/ timestamp and check the data. // [negative test] 2.: try to download a file w/o timestamp. -func TestDacTimestamp(t *testing.T) { +func TestAccessLogicTimestamp(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -569,11 +570,11 @@ func TestDacTimestamp(t *testing.T) { ) t.Run("upload-then-download-with-timestamp-and-check-data", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) var ( thirdTime = time.Date(2015, time.April, 1, 0, 0, 0, 0, time.UTC).Unix() @@ -617,11 +618,11 @@ func TestDacTimestamp(t *testing.T) { t.Run("download-w/o-timestamp", func(t *testing.T) { encryptedRef := "a5df670544eaea29e61b19d8739faa4573b19e4426e58a173e51ed0b5e7e2ade" client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) jsonhttptest.Request(t, client, http.MethodGet, fileDownloadResource(encryptedRef), http.StatusNotFound, @@ -633,12 +634,12 @@ func TestDacTimestamp(t *testing.T) { } // nolint:paralleltest,tparallel -// TestDacPublisher +// TestAccessLogicPublisher // [positive test] 1.: uploading a file w/ ACT then download it w/ the publisher address and check the data. // [negative test] 2.: expect Bad request when the public key is invalid. // [negative test] 3.: try to download a file w/ an incorrect publisher address. // [negative test] 3.: try to download a file w/o a publisher address. -func TestDacPublisher(t *testing.T) { +func TestAccessLogicPublisher(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -656,11 +657,11 @@ func TestDacPublisher(t *testing.T) { t.Run("upload-then-download-w/-publisher-and-check-data", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String()), mockdac.WithPublisher(publisher)), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String()), mockac.WithPublisher(publisher)), }) var ( encryptedRef = "a5a26b4915d7ce1622f9ca52252092cf2445f98d359dabaf52588c05911aaf4f" @@ -702,11 +703,11 @@ func TestDacPublisher(t *testing.T) { t.Run("upload-then-download-invalid-publickey", func(t *testing.T) { client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithPublisher(publisher)), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithPublisher(publisher)), }) var ( publickey = "b786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfb" @@ -760,11 +761,11 @@ func TestDacPublisher(t *testing.T) { encryptedRef = "a5df670544eaea29e61b19d8739faa4573b19e4426e58a173e51ed0b5e7e2ade" ) client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String()), mockdac.WithPublisher(publisher)), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String()), mockac.WithPublisher(publisher)), }) jsonhttptest.Request(t, client, http.MethodGet, fileDownloadResource(encryptedRef), http.StatusInternalServerError, @@ -782,11 +783,11 @@ func TestDacPublisher(t *testing.T) { t.Run("download-w/o-publisher", func(t *testing.T) { encryptedRef := "a5df670544eaea29e61b19d8739faa4573b19e4426e58a173e51ed0b5e7e2ade" client, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String()), mockdac.WithPublisher(publisher)), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String()), mockac.WithPublisher(publisher)), }) jsonhttptest.Request(t, client, http.MethodGet, fileDownloadResource(encryptedRef), http.StatusNotFound, @@ -798,7 +799,7 @@ func TestDacPublisher(t *testing.T) { }) } -func TestDacGrantees(t *testing.T) { +func TestAccessLogicGrantees(t *testing.T) { t.Parallel() var ( spk, _ = hex.DecodeString("a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa") @@ -808,11 +809,11 @@ func TestDacGrantees(t *testing.T) { logger = log.Noop addr = swarm.RandAddress(t) client, _, _, _ = newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String())), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String())), }) ) t.Run("get-grantees", func(t *testing.T) { @@ -821,11 +822,11 @@ func TestDacGrantees(t *testing.T) { publisher = hex.EncodeToString(publicKeyBytes) ) clientwihtpublisher, _, _, _ := newTestServer(t, testServerOptions{ - Storer: storerMock, - Logger: logger, - Post: mockpost.New(mockpost.WithAcceptAll()), - PublicKey: pk.PublicKey, - Dac: mockdac.New(mockdac.WithHistory(h, fixtureHref.String()), mockdac.WithPublisher(publisher)), + Storer: storerMock, + Logger: logger, + Post: mockpost.New(mockpost.WithAcceptAll()), + PublicKey: pk.PublicKey, + AccessControl: mockac.New(mockac.WithHistory(h, fixtureHref.String()), mockac.WithPublisher(publisher)), }) expected := []string{ "03d7660772cc3142f8a7a2dfac46ce34d12eac1718720cef0e3d94347902aa96a2", diff --git a/pkg/api/api.go b/pkg/api/api.go index ec5f4a508ad..0d97a2abf0b 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -27,10 +27,10 @@ import ( "unicode/utf8" "github.com/ethereum/go-ethereum/common" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" "github.com/ethersphere/bee/v2/pkg/accounting" "github.com/ethersphere/bee/v2/pkg/auth" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" "github.com/ethersphere/bee/v2/pkg/feeds" "github.com/ethersphere/bee/v2/pkg/file/pipeline" "github.com/ethersphere/bee/v2/pkg/file/pipeline/builder" @@ -154,7 +154,7 @@ type Service struct { feedFactory feeds.Factory signer crypto.Signer post postage.Service - dac dynamicaccess.Controller + accesscontrol accesscontrol.Controller postageContract postagecontract.Interface probe *Probe metricsRegistry *prometheus.Registry @@ -253,7 +253,7 @@ type ExtraOptions struct { Pss pss.Interface FeedFactory feeds.Factory Post postage.Service - Dac dynamicaccess.Controller + AccessControl accesscontrol.Controller PostageContract postagecontract.Interface Staking staking.Contract Steward steward.Interface @@ -337,7 +337,7 @@ func (s *Service) Configure(signer crypto.Signer, auth auth.Authenticator, trace s.pss = e.Pss s.feedFactory = e.FeedFactory s.post = e.Post - s.dac = e.Dac + s.accesscontrol = e.AccessControl s.postageContract = e.PostageContract s.steward = e.Steward s.stakingContract = e.Staking diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 8a6781f7f98..2e8ccbf5512 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -23,13 +23,13 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" + mockac "github.com/ethersphere/bee/v2/pkg/accesscontrol/mock" accountingmock "github.com/ethersphere/bee/v2/pkg/accounting/mock" "github.com/ethersphere/bee/v2/pkg/api" "github.com/ethersphere/bee/v2/pkg/auth" mockauth "github.com/ethersphere/bee/v2/pkg/auth/mock" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" - mockdac "github.com/ethersphere/bee/v2/pkg/dynamicaccess/mock" "github.com/ethersphere/bee/v2/pkg/feeds" "github.com/ethersphere/bee/v2/pkg/file/pipeline" "github.com/ethersphere/bee/v2/pkg/file/pipeline/builder" @@ -104,7 +104,7 @@ type testServerOptions struct { PostageContract postagecontract.Interface StakingContract staking.Contract Post postage.Service - Dac dynamicaccess.Controller + AccessControl accesscontrol.Controller Steward steward.Interface WsHeaders http.Header Authenticator auth.Authenticator @@ -155,8 +155,8 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. if o.Post == nil { o.Post = mockpost.New() } - if o.Dac == nil { - o.Dac = mockdac.New() + if o.AccessControl == nil { + o.AccessControl = mockac.New() } if o.BatchStore == nil { o.BatchStore = mockbatchstore.New(mockbatchstore.WithAcceptAllExistsFunc()) // default is with accept-all Exists() func @@ -204,7 +204,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. Pss: o.Pss, FeedFactory: o.Feeds, Post: o.Post, - Dac: o.Dac, + AccessControl: o.AccessControl, PostageContract: o.PostageContract, Steward: o.Steward, SyncStatus: o.SyncStatus, diff --git a/pkg/api/bzz.go b/pkg/api/bzz.go index dc26b26667a..bed074ff3ed 100644 --- a/pkg/api/bzz.go +++ b/pkg/api/bzz.go @@ -264,9 +264,9 @@ func (s *Service) fileUploadHandler( } logger.Debug("store", "manifest_reference", manifestReference) - encryptedReference := manifestReference + reference := manifestReference if act { - encryptedReference, err = s.actEncryptionHandler(r.Context(), w, putter, manifestReference, historyAddress) + reference, err = s.actEncryptionHandler(r.Context(), w, putter, reference, historyAddress) if err != nil { jsonhttp.InternalServerError(w, errActUpload) return @@ -275,24 +275,24 @@ func (s *Service) fileUploadHandler( err = putter.Done(manifestReference) if err != nil { - logger.Debug("done split failed", "error", err) + logger.Debug("done split failed", "reference", manifestReference, "error", err) logger.Error(nil, "done split failed") jsonhttp.InternalServerError(w, "done split failed") ext.LogError(span, err, olog.String("action", "putter.Done")) return } span.LogFields(olog.Bool("success", true)) - span.SetTag("root_address", encryptedReference) + span.SetTag("root_address", reference) if tagID != 0 { w.Header().Set(SwarmTagHeader, fmt.Sprint(tagID)) span.SetTag("tagID", tagID) } - w.Header().Set(ETagHeader, fmt.Sprintf("%q", encryptedReference.String())) + w.Header().Set(ETagHeader, fmt.Sprintf("%q", reference.String())) w.Header().Set("Access-Control-Expose-Headers", SwarmTagHeader) jsonhttp.Created(w, bzzUploadResponse{ - Reference: encryptedReference, + Reference: reference, }) } diff --git a/pkg/api/chunk.go b/pkg/api/chunk.go index 21daa0d0f57..534e2924866 100644 --- a/pkg/api/chunk.go +++ b/pkg/api/chunk.go @@ -141,9 +141,9 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) { } } - encryptedReference := chunk.Address() + reference := chunk.Address() if headers.Act { - encryptedReference, err = s.actEncryptionHandler(r.Context(), w, putter, chunk.Address(), headers.HistoryAddress) + reference, err = s.actEncryptionHandler(r.Context(), w, putter, reference, headers.HistoryAddress) if err != nil { jsonhttp.InternalServerError(w, errActUpload) return @@ -176,7 +176,7 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Access-Control-Expose-Headers", SwarmTagHeader) - jsonhttp.Created(w, chunkAddressResponse{Reference: encryptedReference}) + jsonhttp.Created(w, chunkAddressResponse{Reference: reference}) } func (s *Service) chunkGetHandler(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/soc.go b/pkg/api/soc.go index 29777066b10..3ceb462d028 100644 --- a/pkg/api/soc.go +++ b/pkg/api/soc.go @@ -157,9 +157,9 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) { return } - encryptedReference := sch.Address() + reference := sch.Address() if headers.Act { - encryptedReference, err = s.actEncryptionHandler(r.Context(), w, putter, sch.Address(), headers.HistoryAddress) + reference, err = s.actEncryptionHandler(r.Context(), w, putter, reference, headers.HistoryAddress) if err != nil { jsonhttp.InternalServerError(w, errActUpload) return @@ -182,5 +182,5 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) { return } - jsonhttp.Created(w, socPostResponse{Reference: encryptedReference}) + jsonhttp.Created(w, socPostResponse{Reference: reference}) } diff --git a/pkg/dynamicaccess/mock/accesslogic.go b/pkg/dynamicaccess/mock/accesslogic.go deleted file mode 100644 index 6b48c824eb9..00000000000 --- a/pkg/dynamicaccess/mock/accesslogic.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2024 The Swarm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package mock - -type AccessLogicMock struct { - GetFunc func(string, string, string) (string, error) -} - -func (ma *AccessLogicMock) Get(encryped_ref string, publisher string, tag string) (string, error) { - if ma.GetFunc == nil { - return "", nil - } - return ma.GetFunc(encryped_ref, publisher, tag) -} diff --git a/pkg/node/devnode.go b/pkg/node/devnode.go index 389dc2337a5..853eff94807 100644 --- a/pkg/node/devnode.go +++ b/pkg/node/devnode.go @@ -17,12 +17,12 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" mockAccounting "github.com/ethersphere/bee/v2/pkg/accounting/mock" "github.com/ethersphere/bee/v2/pkg/api" "github.com/ethersphere/bee/v2/pkg/auth" "github.com/ethersphere/bee/v2/pkg/bzz" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" "github.com/ethersphere/bee/v2/pkg/feeds/factory" "github.com/ethersphere/bee/v2/pkg/log" mockP2P "github.com/ethersphere/bee/v2/pkg/p2p/mock" @@ -62,15 +62,15 @@ import ( ) type DevBee struct { - tracerCloser io.Closer - stateStoreCloser io.Closer - localstoreCloser io.Closer - apiCloser io.Closer - pssCloser io.Closer - dacCloser io.Closer - errorLogWriter io.Writer - apiServer *http.Server - debugAPIServer *http.Server + tracerCloser io.Closer + stateStoreCloser io.Closer + localstoreCloser io.Closer + apiCloser io.Closer + pssCloser io.Closer + accesscontrolCloser io.Closer + errorLogWriter io.Writer + apiServer *http.Server + debugAPIServer *http.Server } type DevOptions struct { @@ -236,10 +236,10 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { } b.localstoreCloser = localStore - session := dynamicaccess.NewDefaultSession(mockKey) - actLogic := dynamicaccess.NewLogic(session) - dac := dynamicaccess.NewController(actLogic) - b.dacCloser = dac + session := accesscontrol.NewDefaultSession(mockKey) + actLogic := accesscontrol.NewLogic(session) + accesscontrol := accesscontrol.NewController(actLogic) + b.accesscontrolCloser = accesscontrol pssService := pss.New(mockKey, logger) b.pssCloser = pssService @@ -390,7 +390,7 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { Pss: pssService, FeedFactory: mockFeeds, Post: post, - Dac: dac, + AccessControl: accesscontrol, PostageContract: postageContract, Staking: mockStaking, Steward: mockSteward, @@ -499,7 +499,7 @@ func (b *DevBee) Shutdown() error { } tryClose(b.pssCloser, "pss") - tryClose(b.dacCloser, "dac") + tryClose(b.accesscontrolCloser, "accesscontrol") tryClose(b.tracerCloser, "tracer") tryClose(b.stateStoreCloser, "statestore") tryClose(b.localstoreCloser, "localstore") diff --git a/pkg/node/node.go b/pkg/node/node.go index 4ab881bc8ab..09fa43b4589 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -24,13 +24,13 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethersphere/bee/v2/pkg/accesscontrol" "github.com/ethersphere/bee/v2/pkg/accounting" "github.com/ethersphere/bee/v2/pkg/addressbook" "github.com/ethersphere/bee/v2/pkg/api" "github.com/ethersphere/bee/v2/pkg/auth" "github.com/ethersphere/bee/v2/pkg/config" "github.com/ethersphere/bee/v2/pkg/crypto" - "github.com/ethersphere/bee/v2/pkg/dynamicaccess" "github.com/ethersphere/bee/v2/pkg/feeds/factory" "github.com/ethersphere/bee/v2/pkg/hive" "github.com/ethersphere/bee/v2/pkg/log" @@ -118,7 +118,7 @@ type Bee struct { shutdownInProgress bool shutdownMutex sync.Mutex syncingStopped *syncutil.Signaler - dacCloser io.Closer + accesscontrolCloser io.Closer } type Options struct { @@ -204,7 +204,7 @@ func NewBee( logger log.Logger, libp2pPrivateKey, pssPrivateKey *ecdsa.PrivateKey, - session dynamicaccess.Session, + session accesscontrol.Session, o *Options, ) (b *Bee, err error) { tracer, tracerCloser, err := tracing.NewTracer(&tracing.Options{ @@ -781,9 +781,9 @@ func NewBee( b.localstoreCloser = localStore evictFn = func(id []byte) error { return localStore.EvictBatch(context.Background(), id) } - actLogic := dynamicaccess.NewLogic(session) - dac := dynamicaccess.NewController(actLogic) - b.dacCloser = dac + actLogic := accesscontrol.NewLogic(session) + accesscontrol := accesscontrol.NewController(actLogic) + b.accesscontrolCloser = accesscontrol var ( syncErr atomic.Value @@ -1100,7 +1100,7 @@ func NewBee( Pss: pssService, FeedFactory: feedFactory, Post: post, - Dac: dac, + AccessControl: accesscontrol, PostageContract: postageStampContractService, Staking: stakingContract, Steward: steward, @@ -1363,7 +1363,7 @@ func (b *Bee) Shutdown() error { c() } - tryClose(b.dacCloser, "dac") + tryClose(b.accesscontrolCloser, "accesscontrol") tryClose(b.tracerCloser, "tracer") tryClose(b.topologyCloser, "topology driver") tryClose(b.storageIncetivesCloser, "storage incentives agent") diff --git a/pkg/soc/testing/soc.go b/pkg/soc/testing/soc.go index 9516a721d83..20bfe74c9cd 100644 --- a/pkg/soc/testing/soc.go +++ b/pkg/soc/testing/soc.go @@ -72,7 +72,7 @@ func GenerateMockSOC(t *testing.T, data []byte) *MockSOC { } } -// GenerateMockSOC generates a valid mocked SOC from given data and key. +// GenerateMockSOCWithKey generates a valid mocked SOC from given data and key. func GenerateMockSOCWithKey(t *testing.T, data []byte, privKey *ecdsa.PrivateKey) *MockSOC { t.Helper()