Merge pull request #1808 from filecoin-project/feat/extract-jsonrpc-auth
Extract auth utils to go-jsonrpc
This commit is contained in:
commit
6831ca9e03
@ -4,17 +4,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/libp2p/go-libp2p-core/network"
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
)
|
|
||||||
|
|
||||||
type Permission string
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
)
|
||||||
|
|
||||||
type Common interface {
|
type Common interface {
|
||||||
// Auth
|
// Auth
|
||||||
AuthVerify(ctx context.Context, token string) ([]Permission, error)
|
AuthVerify(ctx context.Context, token string) ([]auth.Permission, error)
|
||||||
AuthNew(ctx context.Context, perms []Permission) ([]byte, error)
|
AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error)
|
||||||
|
|
||||||
// network
|
// network
|
||||||
|
|
||||||
|
@ -1,111 +1,38 @@
|
|||||||
package apistruct
|
package apistruct
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type permKey int
|
|
||||||
|
|
||||||
var permCtxKey permKey
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// When changing these, update docs/API.md too
|
// When changing these, update docs/API.md too
|
||||||
|
|
||||||
PermRead api.Permission = "read" // default
|
PermRead auth.Permission = "read" // default
|
||||||
PermWrite api.Permission = "write"
|
PermWrite auth.Permission = "write"
|
||||||
PermSign api.Permission = "sign" // Use wallet keys for signing
|
PermSign auth.Permission = "sign" // Use wallet keys for signing
|
||||||
PermAdmin api.Permission = "admin" // Manage permissions
|
PermAdmin auth.Permission = "admin" // Manage permissions
|
||||||
)
|
)
|
||||||
|
|
||||||
var AllPermissions = []api.Permission{PermRead, PermWrite, PermSign, PermAdmin}
|
var AllPermissions = []auth.Permission{PermRead, PermWrite, PermSign, PermAdmin}
|
||||||
var defaultPerms = []api.Permission{PermRead}
|
var DefaultPerms = []auth.Permission{PermRead}
|
||||||
|
|
||||||
func WithPerm(ctx context.Context, perms []api.Permission) context.Context {
|
|
||||||
return context.WithValue(ctx, permCtxKey, perms)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PermissionedStorMinerAPI(a api.StorageMiner) api.StorageMiner {
|
func PermissionedStorMinerAPI(a api.StorageMiner) api.StorageMiner {
|
||||||
var out StorageMinerStruct
|
var out StorageMinerStruct
|
||||||
permissionedAny(a, &out.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
permissionedAny(a, &out.CommonStruct.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal)
|
||||||
return &out
|
return &out
|
||||||
}
|
}
|
||||||
|
|
||||||
func PermissionedFullAPI(a api.FullNode) api.FullNode {
|
func PermissionedFullAPI(a api.FullNode) api.FullNode {
|
||||||
var out FullNodeStruct
|
var out FullNodeStruct
|
||||||
permissionedAny(a, &out.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
permissionedAny(a, &out.CommonStruct.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.CommonStruct.Internal)
|
||||||
return &out
|
return &out
|
||||||
}
|
}
|
||||||
|
|
||||||
func PermissionedWorkerAPI(a api.WorkerApi) api.WorkerApi {
|
func PermissionedWorkerAPI(a api.WorkerApi) api.WorkerApi {
|
||||||
var out WorkerStruct
|
var out WorkerStruct
|
||||||
permissionedAny(a, &out.Internal)
|
auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal)
|
||||||
return &out
|
return &out
|
||||||
}
|
}
|
||||||
|
|
||||||
func HasPerm(ctx context.Context, perm api.Permission) bool {
|
|
||||||
callerPerms, ok := ctx.Value(permCtxKey).([]api.Permission)
|
|
||||||
if !ok {
|
|
||||||
callerPerms = defaultPerms
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, callerPerm := range callerPerms {
|
|
||||||
if callerPerm == perm {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func permissionedAny(in interface{}, out interface{}) {
|
|
||||||
rint := reflect.ValueOf(out).Elem()
|
|
||||||
ra := reflect.ValueOf(in)
|
|
||||||
|
|
||||||
for f := 0; f < rint.NumField(); f++ {
|
|
||||||
field := rint.Type().Field(f)
|
|
||||||
requiredPerm := api.Permission(field.Tag.Get("perm"))
|
|
||||||
if requiredPerm == "" {
|
|
||||||
panic("missing 'perm' tag on " + field.Name) // ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate perm tag
|
|
||||||
ok := false
|
|
||||||
for _, perm := range AllPermissions {
|
|
||||||
if requiredPerm == perm {
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
panic("unknown 'perm' tag on " + field.Name) // ok
|
|
||||||
}
|
|
||||||
|
|
||||||
fn := ra.MethodByName(field.Name)
|
|
||||||
|
|
||||||
rint.Field(f).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) {
|
|
||||||
ctx := args[0].Interface().(context.Context)
|
|
||||||
if HasPerm(ctx, requiredPerm) {
|
|
||||||
return fn.Call(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := xerrors.Errorf("missing permission to invoke '%s' (need '%s')", field.Name, requiredPerm)
|
|
||||||
rerr := reflect.ValueOf(&err).Elem()
|
|
||||||
|
|
||||||
if field.Type.NumOut() == 2 {
|
|
||||||
return []reflect.Value{
|
|
||||||
reflect.Zero(field.Type.Out(0)),
|
|
||||||
rerr,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return []reflect.Value{rerr}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/sector-storage/sealtasks"
|
"github.com/filecoin-project/sector-storage/sealtasks"
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/sector-storage/storiface"
|
"github.com/filecoin-project/sector-storage/storiface"
|
||||||
@ -30,8 +32,8 @@ var _ = AllPermissions
|
|||||||
|
|
||||||
type CommonStruct struct {
|
type CommonStruct struct {
|
||||||
Internal struct {
|
Internal struct {
|
||||||
AuthVerify func(ctx context.Context, token string) ([]api.Permission, error) `perm:"read"`
|
AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"read"`
|
||||||
AuthNew func(ctx context.Context, perms []api.Permission) ([]byte, error) `perm:"admin"`
|
AuthNew func(ctx context.Context, perms []auth.Permission) ([]byte, error) `perm:"admin"`
|
||||||
|
|
||||||
NetConnectedness func(context.Context, peer.ID) (network.Connectedness, error) `perm:"read"`
|
NetConnectedness func(context.Context, peer.ID) (network.Connectedness, error) `perm:"read"`
|
||||||
NetPeers func(context.Context) ([]peer.AddrInfo, error) `perm:"read"`
|
NetPeers func(context.Context) ([]peer.AddrInfo, error) `perm:"read"`
|
||||||
@ -240,11 +242,11 @@ type WorkerStruct struct {
|
|||||||
|
|
||||||
// CommonStruct
|
// CommonStruct
|
||||||
|
|
||||||
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]api.Permission, error) {
|
func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) {
|
||||||
return c.Internal.AuthVerify(ctx, token)
|
return c.Internal.AuthVerify(ctx, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommonStruct) AuthNew(ctx context.Context, perms []api.Permission) ([]byte, error) {
|
func (c *CommonStruct) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) {
|
||||||
return c.Internal.AuthNew(ctx, perms)
|
return c.Internal.AuthNew(ctx, perms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -29,11 +30,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var ExampleValues = map[reflect.Type]interface{}{
|
var ExampleValues = map[reflect.Type]interface{}{
|
||||||
reflect.TypeOf(api.Permission("")): api.Permission("write"),
|
reflect.TypeOf(auth.Permission("")): auth.Permission("write"),
|
||||||
reflect.TypeOf(""): "string value",
|
reflect.TypeOf(""): "string value",
|
||||||
reflect.TypeOf(uint64(42)): uint64(42),
|
reflect.TypeOf(uint64(42)): uint64(42),
|
||||||
reflect.TypeOf(byte(7)): byte(7),
|
reflect.TypeOf(byte(7)): byte(7),
|
||||||
reflect.TypeOf([]byte{}): []byte("byte array"),
|
reflect.TypeOf([]byte{}): []byte("byte array"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func addExample(v interface{}) {
|
func addExample(v interface{}) {
|
||||||
|
@ -6,7 +6,8 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
)
|
)
|
||||||
@ -46,7 +47,7 @@ var authCreateAdminToken = &cli.Command{
|
|||||||
perm := cctx.String("perm")
|
perm := cctx.String("perm")
|
||||||
idx := 0
|
idx := 0
|
||||||
for i, p := range apistruct.AllPermissions {
|
for i, p := range apistruct.AllPermissions {
|
||||||
if api.Permission(perm) == p {
|
if auth.Permission(perm) == p {
|
||||||
idx = i + 1
|
idx = i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +95,7 @@ var authApiInfoToken = &cli.Command{
|
|||||||
perm := cctx.String("perm")
|
perm := cctx.String("perm")
|
||||||
idx := 0
|
idx := 0
|
||||||
for i, p := range apistruct.AllPermissions {
|
for i, p := range apistruct.AllPermissions {
|
||||||
if api.Permission(perm) == p {
|
if auth.Permission(perm) == p {
|
||||||
idx = i + 1
|
idx = i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
|
|
||||||
@ -23,7 +24,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
"github.com/filecoin-project/lotus/lib/auth"
|
|
||||||
"github.com/filecoin-project/lotus/lib/lotuslog"
|
"github.com/filecoin-project/lotus/lib/lotuslog"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
"github.com/filecoin-project/sector-storage"
|
"github.com/filecoin-project/sector-storage"
|
||||||
|
@ -8,18 +8,19 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
|
||||||
mux "github.com/gorilla/mux"
|
mux "github.com/gorilla/mux"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
manet "github.com/multiformats/go-multiaddr-net"
|
manet "github.com/multiformats/go-multiaddr-net"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
"github.com/filecoin-project/lotus/lib/auth"
|
|
||||||
"github.com/filecoin-project/lotus/lib/ulimit"
|
"github.com/filecoin-project/lotus/lib/ulimit"
|
||||||
"github.com/filecoin-project/lotus/node"
|
"github.com/filecoin-project/lotus/node"
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
|
@ -18,10 +18,10 @@ import (
|
|||||||
"contrib.go.opencensus.io/exporter/prometheus"
|
"contrib.go.opencensus.io/exporter/prometheus"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
"github.com/filecoin-project/lotus/lib/auth"
|
|
||||||
"github.com/filecoin-project/lotus/node"
|
"github.com/filecoin-project/lotus/node"
|
||||||
"github.com/filecoin-project/lotus/node/impl"
|
"github.com/filecoin-project/lotus/node/impl"
|
||||||
)
|
)
|
||||||
@ -83,7 +83,7 @@ func handleImport(a *impl.FullNodeAPI) func(w http.ResponseWriter, r *http.Reque
|
|||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !apistruct.HasPerm(r.Context(), apistruct.PermWrite) {
|
if !auth.HasPerm(r.Context(), nil, apistruct.PermWrite) {
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
|
json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
|
||||||
return
|
return
|
||||||
|
2
go.mod
2
go.mod
@ -23,7 +23,7 @@ require (
|
|||||||
github.com/filecoin-project/go-data-transfer v0.3.0
|
github.com/filecoin-project/go-data-transfer v0.3.0
|
||||||
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5
|
github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5
|
||||||
github.com/filecoin-project/go-fil-markets v0.2.3
|
github.com/filecoin-project/go-fil-markets v0.2.3
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.0
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6
|
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e
|
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200505180321-973f8949ea8e
|
||||||
github.com/filecoin-project/go-statestore v0.1.0
|
github.com/filecoin-project/go-statestore v0.1.0
|
||||||
|
4
go.sum
4
go.sum
@ -164,8 +164,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200208005934-2b8bd03caca5/go
|
|||||||
github.com/filecoin-project/go-fil-markets v0.0.0-20200114015428-74d100f305f8/go.mod h1:c8NTjvFVy1Ud02mmGDjOiMeawY2t6ALfrrdvAB01FQc=
|
github.com/filecoin-project/go-fil-markets v0.0.0-20200114015428-74d100f305f8/go.mod h1:c8NTjvFVy1Ud02mmGDjOiMeawY2t6ALfrrdvAB01FQc=
|
||||||
github.com/filecoin-project/go-fil-markets v0.2.3 h1:00exBcwysQVEx7wvzcdVz9ZT3HLMXKmbQNIz9ktyeO8=
|
github.com/filecoin-project/go-fil-markets v0.2.3 h1:00exBcwysQVEx7wvzcdVz9ZT3HLMXKmbQNIz9ktyeO8=
|
||||||
github.com/filecoin-project/go-fil-markets v0.2.3/go.mod h1:LI3VFHse33aU0djAmFQ8+Hg39i0J8ibAoppGu6TbgkA=
|
github.com/filecoin-project/go-fil-markets v0.2.3/go.mod h1:LI3VFHse33aU0djAmFQ8+Hg39i0J8ibAoppGu6TbgkA=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.0 h1:NBHruefnWWfbizxFMnStXlXKEAxEno3DrM0iLd8SuCM=
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4 h1:H8AVYu0MV9m3CSnKMxeILMfh8xJtnqVdXfBF/qbzgu0=
|
||||||
github.com/filecoin-project/go-jsonrpc v0.1.0/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM=
|
github.com/filecoin-project/go-jsonrpc v0.1.1-0.20200520183639-7c6ee2e066b4/go.mod h1:j6zV//WXIIY5kky873Q3iIKt/ViOE8rcijovmpxrXzM=
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
|
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6 h1:92PET+sx1Hb4W/8CgFwGuxaKbttwY+UNspYZTvXY0vs=
|
||||||
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE=
|
github.com/filecoin-project/go-padreader v0.0.0-20200210211231-548257017ca6/go.mod h1:0HgYnrkeSU4lu1p+LEOeDpFsNBssa0OGGriWdA4hvaE=
|
||||||
github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU=
|
github.com/filecoin-project/go-paramfetch v0.0.0-20200102181131-b20d579f2878/go.mod h1:40kI2Gv16mwcRsHptI3OAV4nlOEU7wVDc4RgMylNFjU=
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
|
||||||
)
|
|
||||||
|
|
||||||
var log = logging.Logger("auth")
|
|
||||||
|
|
||||||
type Handler struct {
|
|
||||||
Verify func(ctx context.Context, token string) ([]api.Permission, error)
|
|
||||||
Next http.HandlerFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
||||||
ctx := r.Context()
|
|
||||||
|
|
||||||
token := r.Header.Get("Authorization")
|
|
||||||
if token == "" {
|
|
||||||
token = r.FormValue("token")
|
|
||||||
if token != "" {
|
|
||||||
token = "Bearer " + token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if token != "" {
|
|
||||||
if !strings.HasPrefix(token, "Bearer ") {
|
|
||||||
log.Warn("missing Bearer prefix in auth header")
|
|
||||||
w.WriteHeader(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
token = strings.TrimPrefix(token, "Bearer ")
|
|
||||||
|
|
||||||
allow, err := h.Verify(ctx, token)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("JWT Verification failed: %s", err)
|
|
||||||
w.WriteHeader(401)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = apistruct.WithPerm(ctx, allow)
|
|
||||||
}
|
|
||||||
|
|
||||||
h.Next(w, r.WithContext(ctx))
|
|
||||||
}
|
|
@ -3,8 +3,6 @@ package common
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
"github.com/gbrlsnchs/jwt/v3"
|
"github.com/gbrlsnchs/jwt/v3"
|
||||||
@ -16,9 +14,12 @@ import (
|
|||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CommonAPI struct {
|
type CommonAPI struct {
|
||||||
@ -30,10 +31,10 @@ type CommonAPI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type jwtPayload struct {
|
type jwtPayload struct {
|
||||||
Allow []api.Permission
|
Allow []auth.Permission
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]api.Permission, error) {
|
func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) {
|
||||||
var payload jwtPayload
|
var payload jwtPayload
|
||||||
if _, err := jwt.Verify([]byte(token), (*jwt.HMACSHA)(a.APISecret), &payload); err != nil {
|
if _, err := jwt.Verify([]byte(token), (*jwt.HMACSHA)(a.APISecret), &payload); err != nil {
|
||||||
return nil, xerrors.Errorf("JWT Verification failed: %w", err)
|
return nil, xerrors.Errorf("JWT Verification failed: %w", err)
|
||||||
@ -42,7 +43,7 @@ func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]api.Permiss
|
|||||||
return payload.Allow, nil
|
return payload.Allow, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *CommonAPI) AuthNew(ctx context.Context, perms []api.Permission) ([]byte, error) {
|
func (a *CommonAPI) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) {
|
||||||
p := jwtPayload{
|
p := jwtPayload{
|
||||||
Allow: perms, // TODO: consider checking validity
|
Allow: perms, // TODO: consider checking validity
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ package impl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
storage2 "github.com/filecoin-project/specs-storage/storage"
|
storage2 "github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ func (r *remoteWorker) AddPiece(ctx context.Context, sector abi.SectorID, pieceS
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remoteWorker, error) {
|
func connectRemoteWorker(ctx context.Context, fa api.Common, url string) (*remoteWorker, error) {
|
||||||
token, err := fa.AuthNew(ctx, []api.Permission{"admin"})
|
token, err := fa.AuthNew(ctx, []auth.Permission{"admin"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("creating auth token for remote connection: %w", err)
|
return nil, xerrors.Errorf("creating auth token for remote connection: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
sectorstorage "github.com/filecoin-project/sector-storage"
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
@ -43,7 +44,7 @@ type StorageMinerAPI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) {
|
func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) {
|
||||||
if !apistruct.HasPerm(r.Context(), apistruct.PermAdmin) {
|
if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) {
|
||||||
w.WriteHeader(401)
|
w.WriteHeader(401)
|
||||||
json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
|
json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
|
||||||
return
|
return
|
||||||
|
@ -7,19 +7,20 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/api/apistruct"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/lotus/lib/addrutil"
|
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
|
||||||
"github.com/gbrlsnchs/jwt/v3"
|
"github.com/gbrlsnchs/jwt/v3"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/libp2p/go-libp2p-core/peerstore"
|
"github.com/libp2p/go-libp2p-core/peerstore"
|
||||||
record "github.com/libp2p/go-libp2p-record"
|
record "github.com/libp2p/go-libp2p-record"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api/apistruct"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/lib/addrutil"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
)
|
)
|
||||||
|
|
||||||
var log = logging.Logger("modules")
|
var log = logging.Logger("modules")
|
||||||
@ -36,7 +37,7 @@ func RecordValidator(ps peerstore.Peerstore) record.Validator {
|
|||||||
const JWTSecretName = "auth-jwt-private"
|
const JWTSecretName = "auth-jwt-private"
|
||||||
|
|
||||||
type jwtPayload struct {
|
type jwtPayload struct {
|
||||||
Allow []api.Permission
|
Allow []auth.Permission
|
||||||
}
|
}
|
||||||
|
|
||||||
func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, error) {
|
func APISecret(keystore types.KeyStore, lr repo.LockedRepo) (*dtypes.APIAlg, error) {
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
storageimpl "github.com/filecoin-project/go-fil-markets/storagemarket/impl"
|
storageimpl "github.com/filecoin-project/go-fil-markets/storagemarket/impl"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket/impl/requestvalidation"
|
"github.com/filecoin-project/go-fil-markets/storagemarket/impl/requestvalidation"
|
||||||
smnet "github.com/filecoin-project/go-fil-markets/storagemarket/network"
|
smnet "github.com/filecoin-project/go-fil-markets/storagemarket/network"
|
||||||
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||||
"github.com/filecoin-project/go-statestore"
|
"github.com/filecoin-project/go-statestore"
|
||||||
"github.com/filecoin-project/go-storedcounter"
|
"github.com/filecoin-project/go-storedcounter"
|
||||||
@ -359,7 +360,7 @@ func SectorStorage(mctx helpers.MetricsCtx, lc fx.Lifecycle, ls stores.LocalStor
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageAuth, error) {
|
func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageAuth, error) {
|
||||||
token, err := ca.AuthNew(ctx, []lapi.Permission{"admin"})
|
token, err := ca.AuthNew(ctx, []auth.Permission{"admin"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("creating storage auth header: %w", err)
|
return nil, xerrors.Errorf("creating storage auth header: %w", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user