diff --git a/api/api_storage.go b/api/api_storage.go index e9e409a7f..197bc71de 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -14,6 +14,7 @@ import ( "github.com/filecoin-project/go-fil-markets/piecestore" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/storagemarket" + "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin/v8/market" "github.com/filecoin-project/go-state-types/builtin/v8/miner" @@ -161,6 +162,8 @@ type StorageMiner interface { StorageLocal(ctx context.Context) (map[storiface.ID]string, error) //perm:admin StorageStat(ctx context.Context, id storiface.ID) (fsutil.FsStat, error) //perm:admin + StorageAuthVerify(ctx context.Context, token string) ([]auth.Permission, error) //perm:read + MarketImportDealData(ctx context.Context, propcid cid.Cid, path string) error //perm:write MarketListDeals(ctx context.Context) ([]*MarketDeal, error) //perm:read MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) //perm:read diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 7df6036c9..401a37ec2 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -854,6 +854,8 @@ type StorageMinerStruct struct { StorageAttach func(p0 context.Context, p1 storiface.StorageInfo, p2 fsutil.FsStat) error `perm:"admin"` + StorageAuthVerify func(p0 context.Context, p1 string) ([]auth.Permission, error) `perm:"read"` + StorageBestAlloc func(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) `perm:"admin"` StorageDeclareSector func(p0 context.Context, p1 storiface.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error `perm:"admin"` @@ -5041,6 +5043,17 @@ func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 storiface.Storag return ErrNotSupported } +func (s *StorageMinerStruct) StorageAuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + if s.Internal.StorageAuthVerify == nil { + return *new([]auth.Permission), ErrNotSupported + } + return s.Internal.StorageAuthVerify(p0, p1) +} + +func (s *StorageMinerStub) StorageAuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + return *new([]auth.Permission), ErrNotSupported +} + func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]storiface.StorageInfo, error) { if s.Internal.StorageBestAlloc == nil { return *new([]storiface.StorageInfo), ErrNotSupported diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 80ccfdb95..8ff1c06f4 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index f3ac74b04..e91b9161d 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 6d69891cb..e0537ab24 100644 Binary files a/build/openrpc/miner.json.gz and b/build/openrpc/miner.json.gz differ diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index 61a220bdb..4a724cbe9 100644 Binary files a/build/openrpc/worker.json.gz and b/build/openrpc/worker.json.gz differ diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 3fffdb2b8..e565ff1ab 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -157,6 +157,7 @@ * [Storage](#Storage) * [StorageAddLocal](#StorageAddLocal) * [StorageAttach](#StorageAttach) + * [StorageAuthVerify](#StorageAuthVerify) * [StorageBestAlloc](#StorageBestAlloc) * [StorageDeclareSector](#StorageDeclareSector) * [StorageDropSector](#StorageDropSector) @@ -3307,6 +3308,25 @@ Inputs: Response: `{}` +### StorageAuthVerify + + +Perms: read + +Inputs: +```json +[ + "string value" +] +``` + +Response: +```json +[ + "write" +] +``` + ### StorageBestAlloc diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 3b753bf82..3b4e1e23e 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -44,6 +44,7 @@ import ( mktsdagstore "github.com/filecoin-project/lotus/markets/dagstore" "github.com/filecoin-project/lotus/markets/storageadapter" "github.com/filecoin-project/lotus/miner" + "github.com/filecoin-project/lotus/node/modules" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/storage" "github.com/filecoin-project/lotus/storage/ctladdr" @@ -97,6 +98,9 @@ type StorageMinerAPI struct { Epp gen.WinningPoStProver `optional:"true"` DS dtypes.MetadataDS + // StorageService is populated when we're not the main storage node (e.g. we're a markets node) + StorageService modules.MinerStorageService `optional:"true"` + ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc `optional:"true"` SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc `optional:"true"` ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc `optional:"true"` @@ -119,6 +123,14 @@ type StorageMinerAPI struct { var _ api.StorageMiner = &StorageMinerAPI{} +func (sm *StorageMinerAPI) StorageAuthVerify(ctx context.Context, token string) ([]auth.Permission, error) { + if sm.StorageService != nil { + return sm.StorageService.AuthVerify(ctx, token) + } + + return sm.AuthVerify(ctx, token) +} + func (sm *StorageMinerAPI) ServeRemote(perm bool) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { if perm == true { diff --git a/node/rpc.go b/node/rpc.go index a67b997e3..bee540500 100644 --- a/node/rpc.go +++ b/node/rpc.go @@ -124,8 +124,6 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server // MinerHandler returns a miner handler, to be mounted as-is on the server. func MinerHandler(a api.StorageMiner, permissioned bool) (http.Handler, error) { - m := mux.NewRouter() - mapi := proxy.MetricedStorMinerAPI(a) if permissioned { mapi = api.PermissionedStorMinerAPI(mapi) @@ -136,23 +134,45 @@ func MinerHandler(a api.StorageMiner, permissioned bool) (http.Handler, error) { rpcServer.Register("Filecoin", mapi) rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover") - m.Handle("/rpc/v0", rpcServer) - m.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) - m.PathPrefix("/remote").HandlerFunc(a.(*impl.StorageMinerAPI).ServeRemote(permissioned)) + rootMux := mux.NewRouter() - // debugging - m.Handle("/debug/metrics", metrics.Exporter()) - m.PathPrefix("/").Handler(http.DefaultServeMux) // pprof + // remote storage + { + m := mux.NewRouter() + m.PathPrefix("/remote").HandlerFunc(a.(*impl.StorageMinerAPI).ServeRemote(permissioned)) - if !permissioned { - return m, nil + var hnd http.Handler = m + if permissioned { + hnd = &auth.Handler{ + Verify: a.StorageAuthVerify, + Next: m.ServeHTTP, + } + } + + rootMux.PathPrefix("/remote").Handler(hnd) } - ah := &auth.Handler{ - Verify: a.AuthVerify, - Next: m.ServeHTTP, + // local APIs + { + m := mux.NewRouter() + m.Handle("/rpc/v0", rpcServer) + m.Handle("/rpc/streams/v0/push/{uuid}", readerHandler) + // debugging + m.Handle("/debug/metrics", metrics.Exporter()) + m.PathPrefix("/").Handler(http.DefaultServeMux) // pprof + + var hnd http.Handler = m + if permissioned { + hnd = &auth.Handler{ + Verify: a.AuthVerify, + Next: m.ServeHTTP, + } + } + + rootMux.PathPrefix("/").Handler(hnd) } - return ah, nil + + return rootMux, nil } func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Request) {