package common import ( "context" "time" "github.com/gbrlsnchs/jwt/v3" "github.com/google/uuid" logging "github.com/ipfs/go-log/v2" "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/lotus/api" apitypes "github.com/filecoin-project/lotus/api/types" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/journal/alerting" "github.com/filecoin-project/lotus/node/modules/dtypes" ) var session = uuid.New() type CommonAPI struct { fx.In BuildVersion build.BuildVersion Alerting *alerting.Alerting APISecret *dtypes.APIAlg ShutdownChan dtypes.ShutdownChan Start dtypes.NodeStartTime } type jwtPayload struct { Allow []auth.Permission } func (a *CommonAPI) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) { var payload jwtPayload if _, err := jwt.Verify([]byte(token), (*jwt.HMACSHA)(a.APISecret), &payload); err != nil { return nil, xerrors.Errorf("JWT Verification failed: %w", err) } return payload.Allow, nil } func (a *CommonAPI) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte, error) { p := jwtPayload{ Allow: perms, // TODO: consider checking validity } return jwt.Sign(&p, (*jwt.HMACSHA)(a.APISecret)) } func (a *CommonAPI) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) { return build.OpenRPCDiscoverJSON_Full(), nil } func (a *CommonAPI) Version(context.Context) (api.APIVersion, error) { v, err := api.VersionForType(api.RunningNodeType) if err != nil { return api.APIVersion{}, err } return api.APIVersion{ Version: string(a.BuildVersion), APIVersion: v, BlockDelay: build.BlockDelaySecs, }, nil } func (a *CommonAPI) LogList(context.Context) ([]string, error) { return logging.GetSubsystems(), nil } func (a *CommonAPI) LogSetLevel(ctx context.Context, subsystem, level string) error { return logging.SetLogLevel(subsystem, level) } func (a *CommonAPI) LogAlerts(ctx context.Context) ([]alerting.Alert, error) { return a.Alerting.GetAlerts(), nil } func (a *CommonAPI) Shutdown(ctx context.Context) error { a.ShutdownChan <- struct{}{} return nil } func (a *CommonAPI) Session(ctx context.Context) (uuid.UUID, error) { return session, nil } func (a *CommonAPI) Closing(ctx context.Context) (<-chan struct{}, error) { return make(chan struct{}), nil // relies on jsonrpc closing } func (a *CommonAPI) StartTime(context.Context) (time.Time, error) { return time.Time(a.Start), nil }