Commit db47d88c authored by Janoš Guljaš's avatar Janoš Guljaš Committed by GitHub

api gateway mode (#675)

parent dfeca7c2
...@@ -41,6 +41,7 @@ const ( ...@@ -41,6 +41,7 @@ const (
optionNamePaymentThreshold = "payment-threshold" optionNamePaymentThreshold = "payment-threshold"
optionNamePaymentTolerance = "payment-tolerance" optionNamePaymentTolerance = "payment-tolerance"
optionNameResolverEndpoints = "resolver-options" optionNameResolverEndpoints = "resolver-options"
optionNameGatewayMode = "gateway-mode"
) )
func init() { func init() {
...@@ -184,4 +185,5 @@ func (c *command) setAllFlags(cmd *cobra.Command) { ...@@ -184,4 +185,5 @@ func (c *command) setAllFlags(cmd *cobra.Command) {
cmd.Flags().Uint64(optionNamePaymentThreshold, 100000, "threshold in BZZ where you expect to get paid from your peers") cmd.Flags().Uint64(optionNamePaymentThreshold, 100000, "threshold in BZZ where you expect to get paid from your peers")
cmd.Flags().Uint64(optionNamePaymentTolerance, 10000, "excess debt above payment threshold in BZZ where you disconnect from your peer") cmd.Flags().Uint64(optionNamePaymentTolerance, 10000, "excess debt above payment threshold in BZZ where you disconnect from your peer")
cmd.Flags().StringSlice(optionNameResolverEndpoints, []string{}, "resolver connection string, see help for format") cmd.Flags().StringSlice(optionNameResolverEndpoints, []string{}, "resolver connection string, see help for format")
cmd.Flags().Bool(optionNameGatewayMode, false, "disable a set of sensitive features in the api")
} }
...@@ -161,6 +161,7 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz ...@@ -161,6 +161,7 @@ Welcome to the Swarm.... Bzzz Bzzzz Bzzzz
PaymentThreshold: c.config.GetUint64(optionNamePaymentThreshold), PaymentThreshold: c.config.GetUint64(optionNamePaymentThreshold),
PaymentTolerance: c.config.GetUint64(optionNamePaymentTolerance), PaymentTolerance: c.config.GetUint64(optionNamePaymentTolerance),
ResolverConnectionCfgs: resolverCfgs, ResolverConnectionCfgs: resolverCfgs,
GatewayMode: c.config.GetBool(optionNameGatewayMode),
}) })
if err != nil { if err != nil {
return err return err
......
...@@ -156,7 +156,7 @@ func newTestServer(t *testing.T, storer storage.Storer) *url.URL { ...@@ -156,7 +156,7 @@ func newTestServer(t *testing.T, storer storage.Storer) *url.URL {
t.Helper() t.Helper()
logger := logging.New(ioutil.Discard, 0) logger := logging.New(ioutil.Discard, 0)
store := statestore.NewStateStore() store := statestore.NewStateStore()
s := api.New(tags.NewTags(store, logger), storer, nil, nil, logger, nil) s := api.New(tags.NewTags(store, logger), storer, nil, logger, nil, api.Options{})
ts := httptest.NewServer(s) ts := httptest.NewServer(s)
srvUrl, err := url.Parse(ts.URL) srvUrl, err := url.Parse(ts.URL)
if err != nil { if err != nil {
......
...@@ -69,6 +69,8 @@ paths: ...@@ -69,6 +69,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse' $ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -169,6 +171,8 @@ paths: ...@@ -169,6 +171,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/Status' $ref: 'SwarmCommon.yaml#/components/schemas/Status'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -227,6 +231,8 @@ paths: ...@@ -227,6 +231,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse' $ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -301,6 +307,8 @@ paths: ...@@ -301,6 +307,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse' $ref: 'SwarmCommon.yaml#/components/schemas/ReferenceResponse'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -367,6 +375,8 @@ paths: ...@@ -367,6 +375,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: 'SwarmCommon.yaml#/components/schemas/NewTagResponse' $ref: 'SwarmCommon.yaml#/components/schemas/NewTagResponse'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -393,6 +403,8 @@ paths: ...@@ -393,6 +403,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/NewTagResponse' $ref: 'SwarmCommon.yaml#/components/schemas/NewTagResponse'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
...@@ -413,6 +425,8 @@ paths: ...@@ -413,6 +425,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/responses/204' $ref: 'SwarmCommon.yaml#/components/responses/204'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'404': '404':
$ref: 'SwarmCommon.yaml#/components/responses/404' $ref: 'SwarmCommon.yaml#/components/responses/404'
'500': '500':
...@@ -444,6 +458,8 @@ paths: ...@@ -444,6 +458,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: 'SwarmCommon.yaml#/components/schemas/Status' $ref: 'SwarmCommon.yaml#/components/schemas/Status'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'404': '404':
$ref: 'SwarmCommon.yaml#/components/responses/404' $ref: 'SwarmCommon.yaml#/components/responses/404'
'500': '500':
...@@ -472,6 +488,8 @@ paths: ...@@ -472,6 +488,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/Response' $ref: 'SwarmCommon.yaml#/components/schemas/Response'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'404': '404':
$ref: 'SwarmCommon.yaml#/components/responses/404' $ref: 'SwarmCommon.yaml#/components/responses/404'
default: default:
...@@ -489,6 +507,8 @@ paths: ...@@ -489,6 +507,8 @@ paths:
$ref: 'SwarmCommon.yaml#/components/schemas/Response' $ref: 'SwarmCommon.yaml#/components/schemas/Response'
'400': '400':
$ref: 'SwarmCommon.yaml#/components/responses/400' $ref: 'SwarmCommon.yaml#/components/responses/400'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'404': '404':
$ref: 'SwarmCommon.yaml#/components/responses/404' $ref: 'SwarmCommon.yaml#/components/responses/404'
default: default:
...@@ -504,12 +524,14 @@ paths: ...@@ -504,12 +524,14 @@ paths:
application/json: application/json:
schema: schema:
$ref: 'SwarmCommon.yaml#/components/schemas/PinningState' $ref: 'SwarmCommon.yaml#/components/schemas/PinningState'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
description: Default response description: Default response
'/pinning/chunks/': '/pinning/chunks':
get: get:
summary: Get list of pinned chunks summary: Get list of pinned chunks
tags: tags:
...@@ -521,6 +543,8 @@ paths: ...@@ -521,6 +543,8 @@ paths:
application/json: application/json:
schema: schema:
$ref: 'SwarmCommon.yaml#/components/schemas/BzzChunksPinned' $ref: 'SwarmCommon.yaml#/components/schemas/BzzChunksPinned'
'403':
$ref: 'SwarmCommon.yaml#/components/responses/403'
'500': '500':
$ref: 'SwarmCommon.yaml#/components/responses/500' $ref: 'SwarmCommon.yaml#/components/responses/500'
default: default:
......
...@@ -228,6 +228,12 @@ components: ...@@ -228,6 +228,12 @@ components:
application/problem+json: application/problem+json:
schema: schema:
$ref: '#/components/schemas/ProblemDetails' $ref: '#/components/schemas/ProblemDetails'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetails'
'404': '404':
description: Not Found description: Not Found
content: content:
......
...@@ -39,31 +39,36 @@ type Service interface { ...@@ -39,31 +39,36 @@ type Service interface {
} }
type server struct { type server struct {
Tags *tags.Tags Tags *tags.Tags
Storer storage.Storer Storer storage.Storer
Resolver resolver.Interface Resolver resolver.Interface
CORSAllowedOrigins []string Logger logging.Logger
Logger logging.Logger Tracer *tracing.Tracer
Tracer *tracing.Tracer Options
http.Handler http.Handler
metrics metrics metrics metrics
} }
type Options struct {
CORSAllowedOrigins []string
GatewayMode bool
}
const ( const (
// TargetsRecoveryHeader defines the Header for Recovery targets in Global Pinning // TargetsRecoveryHeader defines the Header for Recovery targets in Global Pinning
TargetsRecoveryHeader = "swarm-recovery-targets" TargetsRecoveryHeader = "swarm-recovery-targets"
) )
// New will create a and initialize a new API service. // New will create a and initialize a new API service.
func New(tags *tags.Tags, storer storage.Storer, resolver resolver.Interface, corsAllowedOrigins []string, logger logging.Logger, tracer *tracing.Tracer) Service { func New(tags *tags.Tags, storer storage.Storer, resolver resolver.Interface, logger logging.Logger, tracer *tracing.Tracer, o Options) Service {
s := &server{ s := &server{
Tags: tags, Tags: tags,
Storer: storer, Storer: storer,
Resolver: resolver, Resolver: resolver,
CORSAllowedOrigins: corsAllowedOrigins, Options: o,
Logger: logger, Logger: logger,
Tracer: tracer, Tracer: tracer,
metrics: newMetrics(), metrics: newMetrics(),
} }
s.setupRouting() s.setupRouting()
......
...@@ -14,7 +14,6 @@ import ( ...@@ -14,7 +14,6 @@ import (
"github.com/ethersphere/bee/pkg/api" "github.com/ethersphere/bee/pkg/api"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/pingpong"
"github.com/ethersphere/bee/pkg/resolver" "github.com/ethersphere/bee/pkg/resolver"
resolverMock "github.com/ethersphere/bee/pkg/resolver/mock" resolverMock "github.com/ethersphere/bee/pkg/resolver/mock"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
...@@ -24,11 +23,11 @@ import ( ...@@ -24,11 +23,11 @@ import (
) )
type testServerOptions struct { type testServerOptions struct {
Pingpong pingpong.Interface Storer storage.Storer
Storer storage.Storer Resolver resolver.Interface
Resolver resolver.Interface Tags *tags.Tags
Tags *tags.Tags GatewayMode bool
Logger logging.Logger Logger logging.Logger
} }
func newTestServer(t *testing.T, o testServerOptions) *http.Client { func newTestServer(t *testing.T, o testServerOptions) *http.Client {
...@@ -38,7 +37,9 @@ func newTestServer(t *testing.T, o testServerOptions) *http.Client { ...@@ -38,7 +37,9 @@ func newTestServer(t *testing.T, o testServerOptions) *http.Client {
if o.Resolver == nil { if o.Resolver == nil {
o.Resolver = resolverMock.NewResolver() o.Resolver = resolverMock.NewResolver()
} }
s := api.New(o.Tags, o.Storer, o.Resolver, nil, o.Logger, nil) s := api.New(o.Tags, o.Storer, o.Resolver, o.Logger, nil, api.Options{
GatewayMode: o.GatewayMode,
})
ts := httptest.NewServer(s) ts := httptest.NewServer(s)
t.Cleanup(ts.Close) t.Cleanup(ts.Close)
...@@ -115,7 +116,7 @@ func TestParseName(t *testing.T) { ...@@ -115,7 +116,7 @@ func TestParseName(t *testing.T) {
})) }))
} }
s := api.New(nil, nil, tC.res, nil, tC.log, nil).(*api.Server) s := api.New(nil, nil, tC.res, tC.log, nil, api.Options{}).(*api.Server)
t.Run(tC.desc, func(t *testing.T) { t.Run(tC.desc, func(t *testing.T) {
got, err := s.ResolveNameOrAddress(tC.name) got, err := s.ResolveNameOrAddress(tC.name)
......
// Copyright 2020 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 api_test
import (
"io/ioutil"
"net/http"
"testing"
"github.com/ethersphere/bee/pkg/api"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest"
"github.com/ethersphere/bee/pkg/logging"
statestore "github.com/ethersphere/bee/pkg/statestore/mock"
"github.com/ethersphere/bee/pkg/storage/mock"
"github.com/ethersphere/bee/pkg/tags"
)
func TestGatewayMode(t *testing.T) {
logger := logging.New(ioutil.Discard, 0)
client := newTestServer(t, testServerOptions{
Storer: mock.NewStorer(),
Tags: tags.NewTags(statestore.NewStateStore(), logger),
Logger: logger,
GatewayMode: true,
})
forbiddenResponseOption := jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusForbidden),
Code: http.StatusForbidden,
})
t.Run("pinning endpoints", func(t *testing.T) {
path := "/pinning/chunks/0773a91efd6547c754fc1d95fb1c62c7d1b47f959c2caa685dfec8736da95c1c"
jsonhttptest.Request(t, client, http.MethodGet, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodPost, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodDelete, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodGet, "/pinning/chunks", http.StatusForbidden, forbiddenResponseOption)
})
t.Run("tags endpoints", func(t *testing.T) {
path := "/tags/42"
jsonhttptest.Request(t, client, http.MethodGet, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodDelete, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodPatch, path, http.StatusForbidden, forbiddenResponseOption)
jsonhttptest.Request(t, client, http.MethodGet, "/tags", http.StatusForbidden, forbiddenResponseOption)
})
t.Run("pinning", func(t *testing.T) {
headerOption := jsonhttptest.WithRequestHeader(api.SwarmPinHeader, "true")
forbiddenResponseOption := jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
Message: "pinning is disabled",
Code: http.StatusForbidden,
})
jsonhttptest.Request(t, client, http.MethodPost, "/chunks/0773a91efd6547c754fc1d95fb1c62c7d1b47f959c2caa685dfec8736da95c1c", http.StatusOK) // should work without pinning
jsonhttptest.Request(t, client, http.MethodPost, "/chunks/0773a91efd6547c754fc1d95fb1c62c7d1b47f959c2caa685dfec8736da95c1c", http.StatusForbidden, forbiddenResponseOption, headerOption)
jsonhttptest.Request(t, client, http.MethodPost, "/bytes", http.StatusOK) // should work without pinning
jsonhttptest.Request(t, client, http.MethodPost, "/bytes", http.StatusForbidden, forbiddenResponseOption, headerOption)
jsonhttptest.Request(t, client, http.MethodPost, "/files", http.StatusForbidden, forbiddenResponseOption, headerOption)
jsonhttptest.Request(t, client, http.MethodPost, "/dirs", http.StatusForbidden, forbiddenResponseOption, headerOption)
})
t.Run("encryption", func(t *testing.T) {
headerOption := jsonhttptest.WithRequestHeader(api.SwarmEncryptHeader, "true")
forbiddenResponseOption := jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
Message: "encryption is disabled",
Code: http.StatusForbidden,
})
jsonhttptest.Request(t, client, http.MethodPost, "/bytes", http.StatusOK) // should work without pinning
jsonhttptest.Request(t, client, http.MethodPost, "/bytes", http.StatusForbidden, forbiddenResponseOption, headerOption)
jsonhttptest.Request(t, client, http.MethodPost, "/files", http.StatusForbidden, forbiddenResponseOption, headerOption)
jsonhttptest.Request(t, client, http.MethodPost, "/dirs", http.StatusForbidden, forbiddenResponseOption, headerOption)
})
}
...@@ -7,6 +7,7 @@ package api ...@@ -7,6 +7,7 @@ package api
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strings"
"github.com/ethersphere/bee/pkg/jsonhttp" "github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
...@@ -66,29 +67,41 @@ func (s *server) setupRouting() { ...@@ -66,29 +67,41 @@ func (s *server) setupRouting() {
"GET": http.HandlerFunc(s.bzzDownloadHandler), "GET": http.HandlerFunc(s.bzzDownloadHandler),
}) })
handle(router, "/tags", jsonhttp.MethodHandler{ handle(router, "/tags", web.ChainHandlers(
"POST": web.ChainHandlers( s.gatewayModeForbidEndpointHandler,
jsonhttp.NewMaxBodyBytesHandler(1024), web.FinalHandler(jsonhttp.MethodHandler{
web.FinalHandlerFunc(s.createTag), "POST": web.ChainHandlers(
), jsonhttp.NewMaxBodyBytesHandler(1024),
}) web.FinalHandlerFunc(s.createTag),
handle(router, "/tags/{id}", jsonhttp.MethodHandler{ ),
"GET": http.HandlerFunc(s.getTag), })),
"DELETE": http.HandlerFunc(s.deleteTag), )
"PATCH": web.ChainHandlers( handle(router, "/tags/{id}", web.ChainHandlers(
jsonhttp.NewMaxBodyBytesHandler(1024), s.gatewayModeForbidEndpointHandler,
web.FinalHandlerFunc(s.doneSplit), web.FinalHandler(jsonhttp.MethodHandler{
), "GET": http.HandlerFunc(s.getTag),
}) "DELETE": http.HandlerFunc(s.deleteTag),
"PATCH": web.ChainHandlers(
jsonhttp.NewMaxBodyBytesHandler(1024),
web.FinalHandlerFunc(s.doneSplit),
),
})),
)
handle(router, "/pinning/chunks/{address}", jsonhttp.MethodHandler{ handle(router, "/pinning/chunks/{address}", web.ChainHandlers(
"GET": http.HandlerFunc(s.getPinnedChunk), s.gatewayModeForbidEndpointHandler,
"POST": http.HandlerFunc(s.pinChunk), web.FinalHandler(jsonhttp.MethodHandler{
"DELETE": http.HandlerFunc(s.unpinChunk), "GET": http.HandlerFunc(s.getPinnedChunk),
}) "POST": http.HandlerFunc(s.pinChunk),
handle(router, "/pinning/chunks", jsonhttp.MethodHandler{ "DELETE": http.HandlerFunc(s.unpinChunk),
"GET": http.HandlerFunc(s.listPinnedChunks), })),
}) )
handle(router, "/pinning/chunks", web.ChainHandlers(
s.gatewayModeForbidEndpointHandler,
web.FinalHandler(jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.listPinnedChunks),
})),
)
s.Handler = web.ChainHandlers( s.Handler = web.ChainHandlers(
logging.NewHTTPAccessLogHandler(s.Logger, logrus.InfoLevel, "api access"), logging.NewHTTPAccessLogHandler(s.Logger, logrus.InfoLevel, "api access"),
...@@ -107,6 +120,7 @@ func (s *server) setupRouting() { ...@@ -107,6 +120,7 @@ func (s *server) setupRouting() {
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
}) })
}, },
s.gatewayModeForbidHeadersHandler,
web.FinalHandler(router), web.FinalHandler(router),
) )
} }
...@@ -119,3 +133,32 @@ func containsOrigin(s string, l []string) (ok bool) { ...@@ -119,3 +133,32 @@ func containsOrigin(s string, l []string) (ok bool) {
} }
return false return false
} }
func (s *server) gatewayModeForbidEndpointHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if s.GatewayMode {
s.Logger.Tracef("gateway mode: forbidden %s", r.URL.String())
jsonhttp.Forbidden(w, nil)
return
}
h.ServeHTTP(w, r)
})
}
func (s *server) gatewayModeForbidHeadersHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if s.GatewayMode {
if strings.ToLower(r.Header.Get(SwarmPinHeader)) == "true" {
s.Logger.Tracef("gateway mode: forbidden pinning %s", r.URL.String())
jsonhttp.Forbidden(w, "pinning is disabled")
return
}
if strings.ToLower(r.Header.Get(SwarmEncryptHeader)) == "true" {
s.Logger.Tracef("gateway mode: forbidden encryption %s", r.URL.String())
jsonhttp.Forbidden(w, "encryption is disabled")
return
}
}
h.ServeHTTP(w, r)
})
}
...@@ -92,6 +92,7 @@ type Options struct { ...@@ -92,6 +92,7 @@ type Options struct {
PaymentThreshold uint64 PaymentThreshold uint64
PaymentTolerance uint64 PaymentTolerance uint64
ResolverConnectionCfgs []*resolver.ConnectionConfig ResolverConnectionCfgs []*resolver.ConnectionConfig
GatewayMode bool
} }
func NewBee(addr string, swarmAddress swarm.Address, keystore keystore.Service, swarmPrivateKey *ecdsa.PrivateKey, networkID uint64, logger logging.Logger, o Options) (*Bee, error) { func NewBee(addr string, swarmAddress swarm.Address, keystore keystore.Service, swarmPrivateKey *ecdsa.PrivateKey, networkID uint64, logger logging.Logger, o Options) (*Bee, error) {
...@@ -301,7 +302,10 @@ func NewBee(addr string, swarmAddress swarm.Address, keystore keystore.Service, ...@@ -301,7 +302,10 @@ func NewBee(addr string, swarmAddress swarm.Address, keystore keystore.Service,
var apiService api.Service var apiService api.Service
if o.APIAddr != "" { if o.APIAddr != "" {
// API server // API server
apiService = api.New(tagg, ns, multiResolver, o.CORSAllowedOrigins, logger, tracer) apiService = api.New(tagg, ns, multiResolver, logger, tracer, api.Options{
CORSAllowedOrigins: o.CORSAllowedOrigins,
GatewayMode: o.GatewayMode,
})
apiListener, err := net.Listen("tcp", o.APIAddr) apiListener, err := net.Listen("tcp", o.APIAddr)
if err != nil { if err != nil {
return nil, fmt.Errorf("api listener: %w", err) return nil, fmt.Errorf("api listener: %w", err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment