Skip to content

Commit

Permalink
Dynamicaccess service for ACT (#35)
Browse files Browse the repository at this point in the history
* feat: add act.go with TODOs

feat: Add Act interface

feat: Add Marshal, Unmarshal skeleton

feat: Refactor AccessType to iota

feat: Add upload

feat: Rename GenerateAccessControlManifest -> create

feat: Add saltLengthIs32

feat: Add Mrshal, Unmarshal impl

feat: Add Marshal Unmarshal

feat: Remove ManifestEntry json annotations

feat: Modify to public finc/method

feat: Add ErrSaltLength

Add pkg/dynamicaccess

Refactor interfaces and implement default structs

Refactor typo

Refactor History package to use NewHistory() function

Add Act interface and default implementation

Add ACT use cases to act_ucs.md

Add new files and implement interfaces, refactor packeges

Update act_ucs.md

base usecases

Refactor access logic and add mock implementations***

Add DiffieHellman implementation and remove Keystore***

Refactor NewAccessLogic function

Replace encryption.go to pkg/encryption

Refactor packages

Update act_ucs.md

Update act_ucs.md

Update act_ucs.md

Update act_ucs.md

Update act_ucs.md

* Diffie-Hellman (#3)

* Use DiffieHellmanMock

* Adds a comment about Get

* Add support for ECDSA public key in DiffieHellman.SharedSecret function

* Update defaultAct implementation

* Adds pseudo code for Access Logic

* Update default Act creation; Fix basic Act tests

* Refactor access logic to use new ActMock implementation

* feat(history): test mockups wip

* Refactor DiffieHellman implementation

* changes pseudocode for Diffie-Hellmann read

* Co-authored-by: Bálint Ujvári <[email protected]>

* DiffieHellman mock generates a real sherd secret

* Refactor Act

* Adds manifest lookup

* Extend act_test

* Adds unit tests, some values are mocked

* Refactor act mock impl with map[string]map[string]string

* Add check mock implementation for DiffieHellman interface

* Add Load, Store to Act interface. Refactor Act interface

* refactor act, diffieHellman mocks, tests

* Add TestLoadStore function to act_test.go

* Remove unnecessary code in Load function

* Add history mock and History lookup test

* Act refactor

Co-authored-by: Bálint Ujvári <[email protected]>

* Refactor Add method to return Act interface

* Change Get method return type to []byte

---------

Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Peter Ott <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>
Co-authored-by: Levente Kiss <[email protected]>
Co-authored-by: Roland Seres <[email protected]>
Co-authored-by: Kexort <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>

* Acces Logic (#8)

* Use DiffieHellmanMock

* Adds a comment about Get

* Add support for ECDSA public key in DiffieHellman.SharedSecret function

* Update defaultAct implementation

* Adds pseudo code for Access Logic

* Update default Act creation; Fix basic Act tests

* Refactor access logic to use new ActMock implementation

* feat(history): test mockups wip

* Refactor DiffieHellman implementation

* changes pseudocode for Diffie-Hellmann read

* Co-authored-by: Bálint Ujvári <[email protected]>

* DiffieHellman mock generates a real sherd secret

* Refactor Act

* Adds manifest lookup

* Extend act_test

* Adds unit tests, some values are mocked

* Refactor act mock impl with map[string]map[string]string

* Add check mock implementation for DiffieHellman interface

* started Add

* changed some sig

* save

* new grantee addition handling

* mod

* changed helper function visibilities

* some mod with grantee

* test mod

* save

* no error in actInit

* Add_New_Grantee_To_Content

* comment

* copied act_test.go

* no compiler errors on our side

* Adds Add_New_Grantee_To_Content and ActInit

* almost complete grantee container

* maybe complete grantee container

* Solves merge conflict

* access-logic-merge

* fix merge issues

* Added context & details to use cases (#6)

ZH ethersphere#106 Added context & details to use cases

* Add grantee management (#10)

* Add grantee management

* Added controller test

* Fix test fixture, refactor accesslogic

* Add UploadHandler

---------

Co-authored-by: Bálint Ujvári <[email protected]>

* (refactor): from `Get` to `Lookup` to improve clarity and consistency. The changes have been made in the `accesslogic.go`, `act.go`, `act_test.go`, `history_test.go`, and `mock/act.go` files. (#13)

Co-authored-by: Ferenc Sárai <[email protected]>

* Act params rename doc (#14)

* (refactor): ACT interface params + add doc comments

* Revert "(refactor): ACT interface params + add doc comments"

This reverts commit ee8da04.

* (refactor): ACT interface params + add doc comments

* (refactor): Add error to ACT interface methods

---------

Co-authored-by: Ferenc Sárai <[email protected]>

* Move and refactor ACT diffieHellman to Session. Add Key and NewFromKeystore functions. (#16)

* Act swarm address (#15)

* (refactor): ACT interface params + add doc comments

* Revert "(refactor): ACT interface params + add doc comments"

This reverts commit ee8da04.

* (refactor): ACT interface params + add doc comments

* (refactor): Add error to ACT interface methods

* Add in-memory storage and implement Store and Load methods

* Move and refactor ACT diffieHellman to Session. Add Key and NewFromKeystore functions.

---------

Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>

* (rename): defaultAct to inMemoryAct (#17)

* (refactor): ACT interface params + add doc comments

* Revert "(refactor): ACT interface params + add doc comments"

This reverts commit ee8da04.

* (refactor): ACT interface params + add doc comments

* (refactor): Add error to ACT interface methods

* Add in-memory storage and implement Store and Load methods

* *refactor) Rename defaultAct to inMemroryAct

---------

Co-authored-by: Ferenc Sárai <[email protected]>

* (refactor): Update controller_test.go to use NewInMemoryAct, modify Session.Key to return correct dimensional byte slice (#18)

* (refactor): Update controller_test.go to use NewInMemoryAct, modify Session.Key to return two-dimensional byte slice

* (refactor:) Refactor session Key function to use append instead of index-based assignment

---------

Co-authored-by: Ferenc Sárai <[email protected]>

* Act access logic merge (#19)

* grantee container and access logc tests are passed

* refactored access logic and grantee container

* PR 19 comments resolving

* Refactor

* Refactor

* Act kvs merge (#22)

* grantee container and access logc tests are passed

* refactored access logic and grantee container

* PR 19 comments resolving

* Refactor

* Refactor

* working manifest ACT with basic tests

* (refactor:) Refactor act_test

* (refactor:) Refactor kvs -> kvs.manifest, kvs.memory

* (refactror:) kvs

* refactor kvs contsructors

---------

Co-authored-by: Roland Seres <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>
Co-authored-by: Ferenc Sárai <[email protected]>

* Session refactor (#24)

* pr comment fix

* add comment to session.NewFromKeystore

* Access logic refactor (#25)

Refactors access logic

---------

Co-authored-by: Peter Ott <[email protected]>
Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>
Co-authored-by: Peter Ott <[email protected]>

* (refactor:) PR comments (#23)

* grantee-refactor

* Dried up code, related to AddPublisher - AddNewGranteeToContent

* Refactor

* removed getEncryptedAccessKey

* Renamed AddGrentees, RemoveGrantees, etc to Add, Remove, etc

* (refactor:) PR comments

* (refactor:) compile check

* removed encrypted_ref, grantee check (validation)

* changed interface

* comments

* some more comments

* refactor kvs and add load and store

* (refactor:) Use ref

* renamed defaultGrantee to granteeList

* removed null encrypted test in  in TestGet_Error

* refactor kvs: pass kvs IF argument instead of storing it

* Refactor according to the result of the workshop

* refactor kvs IF and mock

* fix merge errors and Logic/get_error test

* (test:) Add test for put/get after kvs.Save

---------

Co-authored-by: Roland Seres <[email protected]>
Co-authored-by: Peter Ott <[email protected]>
Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>
Co-authored-by: Peter Ott <[email protected]>

* Add referenced mock kvs (#26)

* add controller upload test

* compile

* Add test for grantee

* Add Upload test

* Implement controller logic, move grantee management

* Act kvs test (#27)

* (test:) Refactor tests

* (fix:) Save reset counter

---------

Co-authored-by: Ferenc Sárai <[email protected]>

* feat: add history lookup and add

* feat: expose mantaray manifest

* Small refactor + al test (#28)

Adds TestDecryptRefWithGrantee_Success and replaces generateFixPrivateKey with getPrivKey

Co-authored-by: Peter Ott <[email protected]>

* chore: tests + minor fixes

* chore: minor test change

* feat: history with reference

* chore: debugging

* Persist grantee list on swarm (#30)

* Persist grantee list on swarm
* accesslogic refactor
* Refactor grantee list tests

Co-authored-by: Roland Seres <[email protected]>

* Merging Swarm 2.0 master (#32)

* fix(stamper): global lock stamper across multiple upload sessions (ethersphere#4578)
* fix: strategy and fetch timeout parsing (ethersphere#4579)
* feat: neighborhood suggester config (ethersphere#4580)
* feat: add codeql.yml (ethersphere#4334)
* feat: add reserveSizeWithinRadius to status protocol (ethersphere#4585)
* fix: missing 200 response (ethersphere#4526)
* feat: pinned reference integrity check API (ethersphere#4573)
* fix(redundancy/getter): wait for recovery and return error (ethersphere#4581)
* fix(pushsync): store the chunk locally when no peers are available fo… (ethersphere#4597)
* fix(redundancy): on by default when downloading (ethersphere#4602)
* fix: add missing openapi spec (ethersphere#4598)
* feat: bzz resource info API (ethersphere#4588)
* fix(redundancy): bzz unit test (ethersphere#4603)
* feat: redundancy ci (ethersphere#4591)
* chore: bump github.com/quic-go/quic-go from 0.38.1 to 0.38.2 (ethersphere#4534)
* feat: split input file to chunks with specified redundancy (ethersphere#4600)
* perf(getter): cancel inflight requests if enough chunks are fetched for recovery (ethersphere#4608)
* fix: store dir error info (ethersphere#4605)
* chore: remove repetitive words (ethersphere#4611)
* fix: use neighborhood suggester only on mainnet (ethersphere#4612)
* feat: alternative withdrawal address (ethersphere#4606)
* fix(seg65) (ethersphere#4604)
* fix(getter): redundancy getter cleanup (ethersphere#4610)
* feat: v2 (ethersphere#4615)
* fix(pin_integrity): changed route and added openapi (ethersphere#4616)
* fix: missing v2 in the makefile and goreleaser (ethersphere#4622)

* chore: package update

* Update package imports to use the v2 version of the modules (#33)

Co-authored-by: Ferenc Sárai <[email protected]>

* fix walkfn with key sort

* feat: new option to walk nodes of mantaray in sequence

* feat: add latest timestamp check

* chore: uncomment wip stuff

* chore: requested changes

* test: fix to latest adjustment

* Add ctrl logic

* Add dac service

* Continue add ACT handler

* chore: use ZeroAddress

* chore: make var name more general

* connect api test with dac service

* refactor ctrl based on history v2

* Fix: controller upload download flow + basic tests

* hacked mock dac service for simple upload and download

* Insert act uploadhandler into /bzz endpoint and remove uphandler

* Refactor controller and api; enrypt and rLevel passed on during up/download

* Connect Get,Head,Post endpoints with ACT

* Add: act to devnode

* devnode: close dac during shutdown

* pass decrypted ref in r.ctx

* set address ctx as swarm address

* refactor: call actEncrpytionHandler in every endpoint

* typo and comment fix in dynamicaccess

* Add: mock dynamicaccess service and api tests

* Add: TestDacEachEndpointWithAct; fixed some review comments

* Add ACT head test for endpoints

* CHG: first encrypt via ACT then upload normal reference

* FIX: apiservice.dac nil error

---------

Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Ferenc Sárai <[email protected]>
Co-authored-by: Peter Ott <[email protected]>
Co-authored-by: Levente Kiss <[email protected]>
Co-authored-by: Roland Seres <[email protected]>
Co-authored-by: Kexort <[email protected]>
Co-authored-by: Bálint Ujvári <[email protected]>
Co-authored-by: András Arányi <[email protected]>
Co-authored-by: rolandlor <[email protected]>
Co-authored-by: Peter Ott <[email protected]>
  • Loading branch information
11 people committed May 17, 2024
1 parent ce408ac commit 94b69e4
Show file tree
Hide file tree
Showing 30 changed files with 1,707 additions and 319 deletions.
7 changes: 6 additions & 1 deletion cmd/bee/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
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"
Expand Down Expand Up @@ -293,7 +294,7 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo
neighborhoodSuggester = c.config.GetString(optionNameNeighborhoodSuggester)
}

b, err := node.NewBee(ctx, c.config.GetString(optionNameP2PAddr), signerConfig.publicKey, signerConfig.signer, networkID, logger, signerConfig.libp2pPrivateKey, signerConfig.pssPrivateKey, &node.Options{
b, err := node.NewBee(ctx, c.config.GetString(optionNameP2PAddr), signerConfig.publicKey, signerConfig.signer, networkID, logger, signerConfig.libp2pPrivateKey, signerConfig.pssPrivateKey, signerConfig.session, &node.Options{
DataDir: c.config.GetString(optionNameDataDir),
CacheCapacity: c.config.GetUint64(optionNameCacheCapacity),
DBOpenFilesLimit: c.config.GetUint64(optionNameDBOpenFilesLimit),
Expand Down Expand Up @@ -373,6 +374,7 @@ type signerConfig struct {
publicKey *ecdsa.PublicKey
libp2pPrivateKey *ecdsa.PrivateKey
pssPrivateKey *ecdsa.PrivateKey
session dynamicaccess.Session
}

func waitForClef(logger log.Logger, maxRetries uint64, endpoint string) (externalSigner *external.ExternalSigner, err error) {
Expand Down Expand Up @@ -403,6 +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
if p := c.config.GetString(optionNamePassword); p != "" {
password = p
} else if pf := c.config.GetString(optionNamePasswordFile); pf != "" {
Expand Down Expand Up @@ -475,6 +478,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config
}
signer = crypto.NewDefaultSigner(swarmPrivateKey)
publicKey = &swarmPrivateKey.PublicKey
session = dynamicaccess.NewDefaultSession(swarmPrivateKey)
}

logger.Info("swarm public key", "public_key", hex.EncodeToString(crypto.EncodeSecp256k1PublicKey(publicKey)))
Expand Down Expand Up @@ -513,6 +517,7 @@ func (c *command) configureSigner(cmd *cobra.Command, logger log.Logger) (config
publicKey: publicKey,
libp2pPrivateKey: libp2pPrivateKey,
pssPrivateKey: pssPrivateKey,
session: session,
}, nil
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"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"
Expand Down Expand Up @@ -85,6 +86,10 @@ const (
SwarmRedundancyFallbackModeHeader = "Swarm-Redundancy-Fallback-Mode"
SwarmChunkRetrievalTimeoutHeader = "Swarm-Chunk-Retrieval-Timeout"
SwarmLookAheadBufferSizeHeader = "Swarm-Lookahead-Buffer-Size"
SwarmActHeader = "Swarm-Act"
SwarmActTimestampHeader = "Swarm-Act-Timestamp"
SwarmActPublisherHeader = "Swarm-Act-Publisher"
SwarmActHistoryAddressHeader = "Swarm-Act-History-Address"

ImmutableHeader = "Immutable"
GasPriceHeader = "Gas-Price"
Expand Down Expand Up @@ -117,6 +122,8 @@ var (
errBatchUnusable = errors.New("batch not usable")
errUnsupportedDevNodeOperation = errors.New("operation not supported in dev mode")
errOperationSupportedOnlyInFullMode = errors.New("operation is supported only in full mode")
errActDownload = errors.New("act download failed")
errActUpload = errors.New("act upload failed")
)

// Storer interface provides the functionality required from the local storage
Expand Down Expand Up @@ -147,6 +154,7 @@ type Service struct {
feedFactory feeds.Factory
signer crypto.Signer
post postage.Service
dac dynamicaccess.Service
postageContract postagecontract.Interface
probe *Probe
metricsRegistry *prometheus.Registry
Expand Down Expand Up @@ -245,6 +253,7 @@ type ExtraOptions struct {
Pss pss.Interface
FeedFactory feeds.Factory
Post postage.Service
Dac dynamicaccess.Service
PostageContract postagecontract.Interface
Staking staking.Contract
Steward steward.Interface
Expand Down Expand Up @@ -328,6 +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.postageContract = e.PostageContract
s.steward = e.Steward
s.stakingContract = e.Staking
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
"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"
Expand Down Expand Up @@ -102,6 +104,7 @@ type testServerOptions struct {
PostageContract postagecontract.Interface
StakingContract staking.Contract
Post postage.Service
Dac dynamicaccess.Service
Steward steward.Interface
WsHeaders http.Header
Authenticator auth.Authenticator
Expand Down Expand Up @@ -152,6 +155,9 @@ 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.BatchStore == nil {
o.BatchStore = mockbatchstore.New(mockbatchstore.WithAcceptAllExistsFunc()) // default is with accept-all Exists() func
}
Expand Down Expand Up @@ -198,6 +204,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket.
Pss: o.Pss,
FeedFactory: o.Feeds,
Post: o.Post,
Dac: o.Dac,
PostageContract: o.PostageContract,
Steward: o.Steward,
SyncStatus: o.SyncStatus,
Expand Down
47 changes: 34 additions & 13 deletions pkg/api/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ func (s *Service) bytesUploadHandler(w http.ResponseWriter, r *http.Request) {
defer span.Finish()

headers := struct {
BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
Encrypt bool `map:"Swarm-Encrypt"`
RLevel redundancy.Level `map:"Swarm-Redundancy-Level"`
BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
Encrypt bool `map:"Swarm-Encrypt"`
RLevel redundancy.Level `map:"Swarm-Redundancy-Level"`
Act bool `map:"Swarm-Act"`
HistoryAddress *swarm.Address `map:"Swarm-Act-History-Address"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
Expand Down Expand Up @@ -100,7 +102,7 @@ func (s *Service) bytesUploadHandler(w http.ResponseWriter, r *http.Request) {
}

p := requestPipelineFn(putter, headers.Encrypt, headers.RLevel)
address, err := p(ctx, r.Body)
reference, err := p(ctx, r.Body)
if err != nil {
logger.Debug("split write all failed", "error", err)
logger.Error(nil, "split write all failed")
Expand All @@ -114,9 +116,18 @@ func (s *Service) bytesUploadHandler(w http.ResponseWriter, r *http.Request) {
return
}

span.SetTag("root_address", address)
encryptedReference := reference
if headers.Act {
encryptedReference, err = s.actEncryptionHandler(r.Context(), logger, w, putter, reference, headers.HistoryAddress)
if err != nil {
jsonhttp.InternalServerError(w, errActUpload)
return
}
}
// TODO: what should be the root_address ? (eref vs ref)
span.SetTag("root_address", reference)

err = putter.Done(address)
err = putter.Done(reference)
if err != nil {
logger.Debug("done split failed", "error", err)
logger.Error(nil, "done split failed")
Expand All @@ -133,7 +144,7 @@ func (s *Service) bytesUploadHandler(w http.ResponseWriter, r *http.Request) {

w.Header().Set("Access-Control-Expose-Headers", SwarmTagHeader)
jsonhttp.Created(w, bytesPostResponse{
Reference: address,
Reference: encryptedReference,
})
}

Expand All @@ -149,11 +160,16 @@ func (s *Service) bytesGetHandler(w http.ResponseWriter, r *http.Request) {
return
}

address := paths.Address
if v := getAddressFromContext(r.Context()); !v.Equal(swarm.ZeroAddress) {
address = v
}

additionalHeaders := http.Header{
ContentTypeHeader: {"application/octet-stream"},
}

s.downloadHandler(logger, w, r, paths.Address, additionalHeaders, true, false)
s.downloadHandler(logger, w, r, address, additionalHeaders, true, false)
}

func (s *Service) bytesHeadHandler(w http.ResponseWriter, r *http.Request) {
Expand All @@ -167,11 +183,16 @@ func (s *Service) bytesHeadHandler(w http.ResponseWriter, r *http.Request) {
return
}

address := paths.Address
if v := getAddressFromContext(r.Context()); !v.Equal(swarm.ZeroAddress) {
address = v
}

getter := s.storer.Download(true)

ch, err := getter.Get(r.Context(), paths.Address)
ch, err := getter.Get(r.Context(), address)
if err != nil {
logger.Debug("get root chunk failed", "chunk_address", paths.Address, "error", err)
logger.Debug("get root chunk failed", "chunk_address", address, "error", err)
logger.Error(nil, "get rook chunk failed")
w.WriteHeader(http.StatusNotFound)
return
Expand Down
54 changes: 39 additions & 15 deletions pkg/api/bzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,16 @@ func (s *Service) bzzUploadHandler(w http.ResponseWriter, r *http.Request) {
defer span.Finish()

headers := struct {
ContentType string `map:"Content-Type,mimeMediaType" validate:"required"`
BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
Encrypt bool `map:"Swarm-Encrypt"`
IsDir bool `map:"Swarm-Collection"`
RLevel redundancy.Level `map:"Swarm-Redundancy-Level"`
ContentType string `map:"Content-Type,mimeMediaType" validate:"required"`
BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
Encrypt bool `map:"Swarm-Encrypt"`
IsDir bool `map:"Swarm-Collection"`
RLevel redundancy.Level `map:"Swarm-Redundancy-Level"`
Act bool `map:"Swarm-Act"`
HistoryAddress *swarm.Address `map:"Swarm-Act-History-Address"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
Expand Down Expand Up @@ -132,10 +134,10 @@ func (s *Service) bzzUploadHandler(w http.ResponseWriter, r *http.Request) {
}

if headers.IsDir || headers.ContentType == multiPartFormData {
s.dirUploadHandler(ctx, logger, span, ow, r, putter, r.Header.Get(ContentTypeHeader), headers.Encrypt, tag, headers.RLevel)
s.dirUploadHandler(ctx, logger, span, ow, r, putter, r.Header.Get(ContentTypeHeader), headers.Encrypt, tag, headers.RLevel, headers.Act, headers.HistoryAddress)
return
}
s.fileUploadHandler(ctx, logger, span, ow, r, putter, headers.Encrypt, tag, headers.RLevel)
s.fileUploadHandler(ctx, logger, span, ow, r, putter, headers.Encrypt, tag, headers.RLevel, headers.Act, headers.HistoryAddress)
}

// fileUploadResponse is returned when an HTTP request to upload a file is successful
Expand All @@ -155,6 +157,8 @@ func (s *Service) fileUploadHandler(
encrypt bool,
tagID uint64,
rLevel redundancy.Level,
act bool,
historyAddress *swarm.Address,
) {
queries := struct {
FileName string `map:"name" validate:"startsnotwith=/"`
Expand Down Expand Up @@ -260,6 +264,15 @@ func (s *Service) fileUploadHandler(
}
logger.Debug("store", "manifest_reference", manifestReference)

encryptedReference := manifestReference
if act {
encryptedReference, err = s.actEncryptionHandler(r.Context(), logger, w, putter, manifestReference, historyAddress)
if err != nil {
jsonhttp.InternalServerError(w, errActUpload)
return
}
}

err = putter.Done(manifestReference)
if err != nil {
logger.Debug("done split failed", "error", err)
Expand All @@ -268,18 +281,19 @@ func (s *Service) fileUploadHandler(
ext.LogError(span, err, olog.String("action", "putter.Done"))
return
}

// TODO: what should be the root_address ? (eref vs ref)
span.LogFields(olog.Bool("success", true))
span.SetTag("root_address", manifestReference)

if tagID != 0 {
w.Header().Set(SwarmTagHeader, fmt.Sprint(tagID))
span.SetTag("tagID", tagID)
}
w.Header().Set(ETagHeader, fmt.Sprintf("%q", manifestReference.String()))
w.Header().Set(ETagHeader, fmt.Sprintf("%q", encryptedReference.String()))
w.Header().Set("Access-Control-Expose-Headers", SwarmTagHeader)
// TODO: do we need to return reference as well ?
jsonhttp.Created(w, bzzUploadResponse{
Reference: manifestReference,
Reference: encryptedReference,
})
}

Expand All @@ -295,11 +309,16 @@ func (s *Service) bzzDownloadHandler(w http.ResponseWriter, r *http.Request) {
return
}

address := paths.Address
if v := getAddressFromContext(r.Context()); !v.Equal(swarm.ZeroAddress) {
address = v
}

if strings.HasSuffix(paths.Path, "/") {
paths.Path = strings.TrimRight(paths.Path, "/") + "/" // NOTE: leave one slash if there was some.
}

s.serveReference(logger, paths.Address, paths.Path, w, r, false)
s.serveReference(logger, address, paths.Path, w, r, false)
}

func (s *Service) bzzHeadHandler(w http.ResponseWriter, r *http.Request) {
Expand All @@ -314,11 +333,16 @@ func (s *Service) bzzHeadHandler(w http.ResponseWriter, r *http.Request) {
return
}

address := paths.Address
if v := getAddressFromContext(r.Context()); !v.Equal(swarm.ZeroAddress) {
address = v
}

if strings.HasSuffix(paths.Path, "/") {
paths.Path = strings.TrimRight(paths.Path, "/") + "/" // NOTE: leave one slash if there was some.
}

s.serveReference(logger, paths.Address, paths.Path, w, r, true)
s.serveReference(logger, address, paths.Path, w, r, true)
}

func (s *Service) serveReference(logger log.Logger, address swarm.Address, pathVar string, w http.ResponseWriter, r *http.Request, headerOnly bool) {
Expand Down
Loading

0 comments on commit 94b69e4

Please sign in to comment.