Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions openapi/Swarm.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3

info:
version: 8.1.1
version: 8.2.0
title: Bee API
description: "API endpoints for interacting with the Swarm network, supporting file operations, messaging, and node management"

Expand Down Expand Up @@ -345,8 +345,6 @@ paths:
$ref: "SwarmCommon.yaml#/components/parameters/SwarmPostageBatchId"
required: false
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmPostageStamp"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmAct"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmActHistoryAddress"
requestBody:
description: Chunk binary data containing at least 8 bytes.
content:
Expand All @@ -362,8 +360,6 @@ paths:
description: Tag UID from the request `swarm-tag` header if provided.
schema:
$ref: "SwarmCommon.yaml#/components/schemas/Uid"
"swarm-act-history-address":
$ref: "SwarmCommon.yaml#/components/headers/SwarmActHistoryAddress"
content:
application/json:
schema:
Expand Down Expand Up @@ -1013,8 +1009,6 @@ paths:
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmTagParameter"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmPinParameter"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmDeferredUpload"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmAct"
- $ref: "SwarmCommon.yaml#/components/parameters/SwarmActHistoryAddress"
requestBody:
required: true
description: The SOC binary data, composed of the span (8 bytes) and up to 4KB of payload.
Expand All @@ -1035,8 +1029,6 @@ paths:
description: Tag UID, returned when an upload session is in use (either because `swarm-tag` was supplied, `swarm-deferred-upload` requested deferred mode, or `swarm-pin` was set).
schema:
$ref: "SwarmCommon.yaml#/components/schemas/Uid"
"swarm-act-history-address":
$ref: "SwarmCommon.yaml#/components/headers/SwarmActHistoryAddress"
"400":
$ref: "SwarmCommon.yaml#/components/responses/400"
"401":
Expand Down
57 changes: 7 additions & 50 deletions pkg/api/accesscontrol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/ethersphere/bee/v2/pkg/jsonhttp/jsonhttptest"
"github.com/ethersphere/bee/v2/pkg/log"
mockpost "github.com/ethersphere/bee/v2/pkg/postage/mock"
testingsoc "github.com/ethersphere/bee/v2/pkg/soc/testing"
mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock"
"github.com/ethersphere/bee/v2/pkg/swarm"
"gitlab.com/nolash/go-mockbytes"
Expand Down Expand Up @@ -77,16 +76,10 @@ func TestAccessLogicEachEndpointWithAct(t *testing.T) {
storerMock = mockstorer.New()
logger = log.Noop
now = time.Now().Unix()
chunk = swarm.NewChunk(
swarm.MustParseHexAddress("0025737be11979e91654dffd2be817ac1e52a2dadb08c97a7cef12f937e707bc"),
[]byte{72, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 149, 179, 31, 244, 146, 247, 129, 123, 132, 248, 215, 77, 44, 47, 91, 248, 229, 215, 89, 156, 210, 243, 3, 110, 204, 74, 101, 119, 53, 53, 145, 188, 193, 153, 130, 197, 83, 152, 36, 140, 150, 209, 191, 214, 193, 4, 144, 121, 32, 45, 205, 220, 59, 227, 28, 43, 161, 51, 108, 14, 106, 180, 135, 2},
)
g = mockbytes.New(0, mockbytes.MockTypeStandard).WithModulus(255)
bytedata, _ = g.SequentialBytes(swarm.ChunkSize * 2)
tag, _ = storerMock.NewSession()
sch = testingsoc.GenerateMockSOCWithKey(t, []byte("foo"), pk)
dirdata = []byte("Lorem ipsum dolor sit amet")
socResource = func(owner, id, sig string) string { return fmt.Sprintf("/soc/%s/%s?sig=%s", owner, id, sig) }
g = mockbytes.New(0, mockbytes.MockTypeStandard).WithModulus(255)
bytedata, _ = g.SequentialBytes(swarm.ChunkSize * 2)
tag, _ = storerMock.NewSession()
dirdata = []byte("Lorem ipsum dolor sit amet")
)

tc := []struct {
Expand All @@ -100,7 +93,6 @@ func TestAccessLogicEachEndpointWithAct(t *testing.T) {
resp struct {
Reference swarm.Address `json:"reference"`
}
direct bool
}{
{
name: "bzz",
Expand Down Expand Up @@ -141,27 +133,6 @@ func TestAccessLogicEachEndpointWithAct(t *testing.T) {
expdata: bytedata,
contenttype: "application/octet-stream",
},
{
name: "chunks",
upurl: "/chunks",
downurl: "/chunks",
exphash: "ca8d2d29466e017cba46d383e7e0794d99a141185ec525086037f25fc2093155",
resp: api.ChunkAddressResponse{Reference: swarm.MustParseHexAddress("ca8d2d29466e017cba46d383e7e0794d99a141185ec525086037f25fc2093155")},
data: bytes.NewReader(chunk.Data()),
expdata: chunk.Data(),
contenttype: "binary/octet-stream",
},
{
name: "soc",
upurl: socResource(hex.EncodeToString(sch.Owner), hex.EncodeToString(sch.ID), hex.EncodeToString(sch.Signature)),
downurl: "/chunks",
exphash: "b100d7ce487426b17b98ff779fad4f2dd471d04ab1c8949dd2a1a78fe4a1524e",
resp: api.ChunkAddressResponse{Reference: swarm.MustParseHexAddress("b100d7ce487426b17b98ff779fad4f2dd471d04ab1c8949dd2a1a78fe4a1524e")},
data: bytes.NewReader(sch.WrappedChunk.Data()),
expdata: sch.Chunk().Data(),
contenttype: "binary/octet-stream",
direct: true,
},
}

for _, v := range tc {
Expand All @@ -175,35 +146,21 @@ func TestAccessLogicEachEndpointWithAct(t *testing.T) {
jsonhttptest.WithExpectedJSONResponse(v.resp),
jsonhttptest.WithRequestHeader(api.ContentTypeHeader, v.contenttype),
}
if v.name == "soc" {
upTestOpts = append(upTestOpts, jsonhttptest.WithRequestHeader(api.SwarmPinHeader, "true"))
} else {
upTestOpts = append(upTestOpts, jsonhttptest.WithNonEmptyResponseHeader(api.SwarmTagHeader))
}
upTestOpts = append(upTestOpts, jsonhttptest.WithNonEmptyResponseHeader(api.SwarmTagHeader))
expcontenttype := v.contenttype
if v.name == "bzz-dir" {
expcontenttype = "text/plain; charset=utf-8"
upTestOpts = append(upTestOpts, jsonhttptest.WithRequestHeader(api.SwarmCollectionHeader, "True"))
}
t.Run(v.name, func(t *testing.T) {
client, _, _, chanStore := newTestServer(t, testServerOptions{
client, _, _, _ := newTestServer(t, testServerOptions{
Storer: storerMock,
Logger: logger,
Post: mockpost.New(mockpost.WithAcceptAll()),
PublicKey: pk.PublicKey,
AccessControl: mockac.New(),
DirectUpload: v.direct,
})

if chanStore != nil {
chanStore.Subscribe(func(chunk swarm.Chunk) {
err := storerMock.Put(context.Background(), chunk)
if err != nil {
t.Fatal(err)
}
})
}

header := jsonhttptest.Request(t, client, http.MethodPost, v.upurl, http.StatusCreated,
upTestOpts...,
)
Expand All @@ -218,7 +175,7 @@ func TestAccessLogicEachEndpointWithAct(t *testing.T) {
jsonhttptest.WithExpectedResponseHeader(api.ContentTypeHeader, expcontenttype),
)

if v.name != "bzz-dir" && v.name != "soc" && v.name != "chunks" {
if v.name != "bzz-dir" {
t.Run("head", func(t *testing.T) {
jsonhttptest.Request(t, client, http.MethodHead, v.downurl+"/"+v.exphash, http.StatusOK,
jsonhttptest.WithRequestHeader(api.SwarmActTimestampHeader, strconv.FormatInt(now, 10)),
Expand Down
39 changes: 5 additions & 34 deletions pkg/api/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"net/http"
"strconv"

"github.com/ethersphere/bee/v2/pkg/accesscontrol"
"github.com/ethersphere/bee/v2/pkg/cac"
"github.com/ethersphere/bee/v2/pkg/file/redundancy"
"github.com/ethersphere/bee/v2/pkg/soc"
"github.com/ethersphere/bee/v2/pkg/storer"

Expand All @@ -33,11 +31,9 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
logger := s.logger.WithName("post_chunk").Build()

headers := struct {
BatchID []byte `map:"Swarm-Postage-Batch-Id"`
StampSig []byte `map:"Swarm-Postage-Stamp"`
SwarmTag uint64 `map:"Swarm-Tag"`
Act bool `map:"Swarm-Act"`
HistoryAddress swarm.Address `map:"Swarm-Act-History-Address"`
BatchID []byte `map:"Swarm-Postage-Batch-Id"`
StampSig []byte `map:"Swarm-Postage-Stamp"`
SwarmTag uint64 `map:"Swarm-Tag"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
Expand Down Expand Up @@ -183,28 +179,6 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
return
}

reference := chunk.Address()
historyReference := swarm.ZeroAddress
if headers.Act {
// Redundancy level is hardcoded; ACT on chunk endpoints is semantically broken and will be removed, see https://github.com/ethersphere/bee/issues/5469.
reference, historyReference, err = s.actEncryptionHandler(r.Context(), putter, reference, headers.HistoryAddress, redundancy.DefaultUploadLevel)
if err != nil {
logger.Debug("access control upload failed", "error", err)
logger.Error(nil, "access control upload failed")
switch {
case errors.Is(err, accesscontrol.ErrNotFound):
jsonhttp.NotFound(w, "act or history entry not found")
case errors.Is(err, accesscontrol.ErrInvalidPublicKey) || errors.Is(err, accesscontrol.ErrSecretKeyInfinity):
jsonhttp.BadRequest(w, "invalid public key")
case errors.Is(err, accesscontrol.ErrUnexpectedType):
jsonhttp.BadRequest(w, "failed to create history")
default:
jsonhttp.InternalServerError(w, errActUpload)
}
return
}
}

err = putter.Done(swarm.ZeroAddress)
if err != nil {
logger.Debug("done split failed", "error", err)
Expand All @@ -218,11 +192,8 @@ func (s *Service) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
}

w.Header().Set(AccessControlExposeHeaders, SwarmTagHeader)
if headers.Act {
w.Header().Set(SwarmActHistoryAddressHeader, historyReference.String())
w.Header().Add(AccessControlExposeHeaders, SwarmActHistoryAddressHeader)
}
jsonhttp.Created(w, chunkAddressResponse{Reference: reference})

jsonhttp.Created(w, chunkAddressResponse{Reference: chunk.Address()})
}

func (s *Service) chunkGetHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
42 changes: 6 additions & 36 deletions pkg/api/soc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import (
"net/http"
"strconv"

"github.com/ethersphere/bee/v2/pkg/accesscontrol"
"github.com/ethersphere/bee/v2/pkg/cac"
"github.com/ethersphere/bee/v2/pkg/file/redundancy"
"github.com/ethersphere/bee/v2/pkg/jsonhttp"
"github.com/ethersphere/bee/v2/pkg/postage"
"github.com/ethersphere/bee/v2/pkg/soc"
Expand Down Expand Up @@ -50,13 +48,11 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) {
}

headers := struct {
BatchID []byte `map:"Swarm-Postage-Batch-Id"`
StampSig []byte `map:"Swarm-Postage-Stamp"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
Act bool `map:"Swarm-Act"`
HistoryAddress swarm.Address `map:"Swarm-Act-History-Address"`
BatchID []byte `map:"Swarm-Postage-Batch-Id"`
StampSig []byte `map:"Swarm-Postage-Stamp"`
SwarmTag uint64 `map:"Swarm-Tag"`
Pin bool `map:"Swarm-Pin"`
Deferred *bool `map:"Swarm-Deferred-Upload"`
}{}
if response := s.mapStructure(r.Header, &headers); response != nil {
response("invalid header params", logger, w)
Expand Down Expand Up @@ -213,28 +209,6 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) {
return
}

reference := sch.Address()
historyReference := swarm.ZeroAddress
if headers.Act {
// Redundancy level is hardcoded; ACT on SOC is semantically broken and will be removed, see https://github.com/ethersphere/bee/issues/5469.
reference, historyReference, err = s.actEncryptionHandler(r.Context(), putter, reference, headers.HistoryAddress, redundancy.DefaultUploadLevel)
if err != nil {
logger.Debug("access control upload failed", "error", err)
logger.Error(nil, "access control upload failed")
switch {
case errors.Is(err, accesscontrol.ErrNotFound):
jsonhttp.NotFound(w, "act or history entry not found")
case errors.Is(err, accesscontrol.ErrInvalidPublicKey) || errors.Is(err, accesscontrol.ErrSecretKeyInfinity):
jsonhttp.BadRequest(w, "invalid public key")
case errors.Is(err, accesscontrol.ErrUnexpectedType):
jsonhttp.BadRequest(w, "failed to create history")
default:
jsonhttp.InternalServerError(w, errActUpload)
}
return
}
}

err = putter.Done(sch.Address())
if err != nil {
logger.Debug("done split failed", "error", err)
Expand All @@ -247,12 +221,8 @@ func (s *Service) socUploadHandler(w http.ResponseWriter, r *http.Request) {
}

w.Header().Set(AccessControlExposeHeaders, SwarmTagHeader)
if headers.Act {
w.Header().Set(SwarmActHistoryAddressHeader, historyReference.String())
w.Header().Add(AccessControlExposeHeaders, SwarmActHistoryAddressHeader)
}

jsonhttp.Created(w, socPostResponse{Reference: reference})
jsonhttp.Created(w, socPostResponse{Reference: sch.Address()})
}

func (s *Service) socGetHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
Loading