Skip to content

Commit

Permalink
fix: permission check
Browse files Browse the repository at this point in the history
  • Loading branch information
simlecode committed Oct 18, 2023
1 parent 3f9c20c commit 423248b
Showing 1 changed file with 63 additions and 2 deletions.
65 changes: 63 additions & 2 deletions node/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"net/http"
_ "net/http/pprof"
"reflect"
"runtime"
"strconv"
"time"
Expand All @@ -23,6 +24,7 @@ import (

"github.com/filecoin-project/go-jsonrpc"
"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/ipfs-force-community/sophon-auth/core"
"github.com/ipfs-force-community/sophon-auth/jwtclient"

"github.com/filecoin-project/lotus/api"
Expand Down Expand Up @@ -108,7 +110,9 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, authEndpoint, authToke

fnapi := proxy.MetricedFullAPI(a)
if permissioned {
fnapi = api.PermissionedFullAPI(fnapi)
// fnapi = api.PermissionedFullAPI(fnapi)
var out api.FullNodeStruct
PermissionProxy(fnapi, &out)
}

var v0 v0api.FullNode = &(struct{ v0api.FullNode }{&v0api.WrapperV1Full{FullNode: fnapi}})
Expand Down Expand Up @@ -335,5 +339,62 @@ func (w *WrapClient) Verify(ctx context.Context, token string) (auth.Permission,
return "", nil
}

return permissions[0], nil
return permissions[len(permissions)-1], nil
}

// PermissionProxy the scheduler between API and internal business
// nolint
func PermissionProxy(in interface{}, out interface{}) {
ra := reflect.ValueOf(in)
outs := api.GetInternalStructs(out)
allPermissions := core.AdaptOldStrategy(core.PermAdmin)
for _, out := range outs {
rint := reflect.ValueOf(out).Elem()
for i := 0; i < ra.NumMethod(); i++ {
methodName := ra.Type().Method(i).Name
field, exists := rint.Type().FieldByName(methodName)
if !exists {
continue
}

requiredPerm := field.Tag.Get("perm")
if requiredPerm == "" {
panic("missing 'perm' tag on " + field.Name) // ok
}

var found bool
for _, perm := range allPermissions {
if perm == requiredPerm {
found = true
}
}
if !found {
panic("unknown 'perm' tag on " + field.Name)
}

fn := ra.Method(i)
rint.FieldByName(methodName).Set(reflect.MakeFunc(field.Type, func(args []reflect.Value) (results []reflect.Value) {
ctx := args[0].Interface().(context.Context)
errNum := 0
if !core.HasPerm(ctx, []core.Permission{core.PermRead}, requiredPerm) {
errNum++
goto ABORT
}
return fn.Call(args)
ABORT:
err := fmt.Errorf("missing permission to invoke '%s'", methodName)
if errNum&1 == 1 {
err = fmt.Errorf("%s (need '%s')", err, requiredPerm)
}
rerr := reflect.ValueOf(&err).Elem()
if fn.Type().NumOut() == 2 {
return []reflect.Value{
reflect.Zero(fn.Type().Out(0)),
rerr,
}
}
return []reflect.Value{rerr}
}))
}
}
}

0 comments on commit 423248b

Please sign in to comment.