Skip to content

Commit

Permalink
feat: add stm annotations/增加STM注解 (#103)
Browse files Browse the repository at this point in the history
feat: STM annotations
  • Loading branch information
zl03jsj authored Sep 26, 2022
1 parent f1d92dc commit 2839136
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 24 deletions.
5 changes: 3 additions & 2 deletions build/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/filecoin-project/venus-wallet/storage/strategy"
"github.com/filecoin-project/venus-wallet/storage/wallet"
"github.com/filecoin-project/venus-wallet/wallet_event"
"github.com/gbrlsnchs/jwt/v3"
"github.com/ipfs-force-community/venus-gateway/types"
"go.uber.org/fx"

Expand Down Expand Up @@ -84,9 +85,9 @@ func WalletOpt(repo filemgr.Repo, walletPwd string) Option {
)
}

func CommonOpt(alg *common.APIAlg) Option {
func CommonOpt(alg *jwt.HMACSHA) Option {
return Options(
Override(new(*common.APIAlg), alg),
Override(new(*jwt.HMACSHA), alg),
Override(new(common.ICommon), From(new(common.Common))),
)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ var RunCmd = &cli.Command{
}

// TODO: properly parse api endpoint (or make it a URL)
return ServeRPC(fullAPI, stop, endpoint)
return ServeRPC(fullAPI, stop, endpoint, nil)
},
}
2 changes: 1 addition & 1 deletion cmd/mock/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func main() {
log.Println("Pre-preparation completed")
// TODO: properly parse api endpoint (or make it a URL)
// Use serveRPC method to perform local CLI debugging
err = cmd.ServeRPC(fullAPI, stop, endpoint)
err = cmd.ServeRPC(fullAPI, stop, endpoint, nil)
if err != nil {
log.Fatal(err)
}
Expand Down
8 changes: 5 additions & 3 deletions cmd/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ func CorsMiddleWare(next http.Handler) http.Handler {
})
}

// Start the interface service and bind the address
func ServeRPC(a api.IFullAPI, stop build.StopFunc, addr string) error {
// ServeRPC Start the interface service and bind the address
func ServeRPC(a api.IFullAPI, stop build.StopFunc, addr string, sigChan chan os.Signal) error {
rpcServer := jsonrpc.NewServer()
rpcServer.Register("Filecoin", permissionedFullAPI(a))
ah := &Handler{
Expand All @@ -58,7 +58,9 @@ func ServeRPC(a api.IFullAPI, stop build.StopFunc, addr string) error {
return fmt.Errorf("could not listen: %w", err)
}
srv := &http.Server{Handler: http.DefaultServeMux}
sigChan := make(chan os.Signal, 2)
if sigChan == nil {
sigChan = make(chan os.Signal, 2)
}
go func() {
<-sigChan
if err := srv.Shutdown(context.TODO()); err != nil {
Expand Down
8 changes: 3 additions & 5 deletions common/api_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ import (

type ICommon = api.ICommon

type APIAlg jwt.HMACSHA

var _ ICommon = &Common{}

type Common struct {
fx.In
APISecret *APIAlg
APISecret *jwt.HMACSHA
}

type jwtPayload struct {
Expand All @@ -30,7 +28,7 @@ type jwtPayload struct {

func (a *Common) 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 {
if _, err := jwt.Verify([]byte(token), a.APISecret, &payload); err != nil {
return nil, fmt.Errorf("JWT Verification failed: %w", err)
}
return payload.Allow, nil
Expand All @@ -40,7 +38,7 @@ func (a *Common) AuthNew(ctx context.Context, perms []auth.Permission) ([]byte,
p := jwtPayload{
Allow: perms, // TODO: consider checking validity
}
return jwt.Sign(&p, (*jwt.HMACSHA)(a.APISecret))
return jwt.Sign(&p, a.APISecret)
}

func (a *Common) Version(context.Context) (types.Version, error) {
Expand Down
71 changes: 71 additions & 0 deletions common/api_common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//stm: #unit
package common

import (
"context"
"encoding/hex"
"reflect"
"testing"

"github.com/filecoin-project/go-jsonrpc/auth"
"github.com/filecoin-project/venus-wallet/filemgr"
"github.com/gbrlsnchs/jwt/v3"
"github.com/stretchr/testify/require"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)

func TestCommon_AuthVerify(t *testing.T) {
//stm: @VENUSWALLET_API_COMMON_AUTH_VERIFY_001, @VENUSWALLET_API_COMMON_AUTH_NEW_001
t.Parallel()
var c Common

cng, err := filemgr.RandJWTConfig()
require.NoError(t, err)
sec, err := hex.DecodeString(cng.Secret)
require.NoError(t, err)

app := fxtest.New(t,
fx.Provide(func() *jwt.HMACSHA { return jwt.NewHS256(sec) }),
fx.Populate(&c),
)
defer app.RequireStart().RequireStop()

type args struct {
token string
}

type testCase struct {
args args
want []auth.Permission
wantErr bool
}

tests := map[string]*testCase{
"invalid-token-verify": {args: args{"invalid-token"}, want: nil, wantErr: true},
}

ctx := context.Background()

validTokenCase := &testCase{want: []auth.Permission{"admin", "sign", "write"}, wantErr: false}
token, err := c.AuthNew(ctx, validTokenCase.want)
require.NoError(t, err)
validTokenCase.args.token = string(token)

tests["valid-token-verify"] = validTokenCase

for tName, tt := range tests {
t.Run(tName, func(t *testing.T) {
got, err := c.AuthVerify(ctx, tt.args.token)

if (err != nil) != tt.wantErr {
t.Errorf("AuthVerify() error = %v, wantErr %v", err, tt.wantErr)
return
}

if !reflect.DeepEqual(got, tt.want) {
t.Errorf("AuthVerify() got = %v, want %v", got, tt.want)
}
})
}
}
5 changes: 2 additions & 3 deletions filemgr/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"path/filepath"
"strings"

"github.com/filecoin-project/venus-wallet/common"
"github.com/filecoin-project/venus-wallet/config"
"github.com/filecoin-project/venus-wallet/crypto/aes"
jwt "github.com/gbrlsnchs/jwt/v3"
Expand Down Expand Up @@ -59,12 +58,12 @@ func NewFS(path string, op *OverrideParams) (Repo, error) {
}
return fs, nil
}
func (fsr *FsRepo) APISecret() (*common.APIAlg, error) {
func (fsr *FsRepo) APISecret() (*jwt.HMACSHA, error) {
sec, err := hex.DecodeString(fsr.cnf.JWT.Secret)
if err != nil {
return nil, err
}
return (*common.APIAlg)(jwt.NewHS256(sec)), nil
return jwt.NewHS256(sec), nil
}
func (fsr *FsRepo) init() error {
exist, err := fsr.exists()
Expand Down
19 changes: 16 additions & 3 deletions filemgr/fs_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
//stm: #unit
package filemgr

import (
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/require"
"gotest.tools/assert"
)

func TestNewFS(t *testing.T) {
//stm: @VENUSWALLET_FILEMGR_FS_NEW_001
fsPath, err := ioutil.TempDir("", "venus-repo-")
defer os.RemoveAll(fsPath)
if err != nil {
Expand All @@ -18,9 +21,19 @@ func TestNewFS(t *testing.T) {
fs, err := NewFS(fsPath, &OverrideParams{
API: targetAPI,
})
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
require.NotNil(t, fs)

//stm: @VENUSWALLET_FILEMGR_FS_API_SECRET_001,
secr, err := fs.APISecret()
require.NoError(t, err)
require.NotNil(t, secr)

//stm: @VENUSWALLET_FILEMGR_FS_API_STRATEGY_TOKEN_001
token, err := fs.APIStrategyToken("password")
require.NoError(t, err)
require.NotEqual(t, token, "")

curAPI, err := fs.APIEndpoint()
if err != nil {
t.Fatal()
Expand Down
4 changes: 2 additions & 2 deletions filemgr/interface.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package filemgr

import (
"github.com/filecoin-project/venus-wallet/common"
"github.com/filecoin-project/venus-wallet/config"
"github.com/gbrlsnchs/jwt/v3"
)

// file system
Expand All @@ -13,7 +13,7 @@ type Repo interface {
// APIToken returns JWT API Token for use in operations that require auth
APIToken() ([]byte, error)

APISecret() (*common.APIAlg, error)
APISecret() (*jwt.HMACSHA, error)

// APIStrategyToken cli pwd convert root token
APIStrategyToken(password string) (string, error)
Expand Down
4 changes: 0 additions & 4 deletions filemgr/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ func randSecret() (*jwtSecret, error) {
}, nil
}

/*func (js *jwtSecret) alg() *api.APIAlg {
return (*api.APIAlg)(jwt.NewHS256(js.key))
}*/

// Random generation of JWT config
func RandJWTConfig() (*config.JWTConfig, error) {
js, err := randSecret()
Expand Down
123 changes: 123 additions & 0 deletions integration_test/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package integration

import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"syscall"
"time"

"github.com/filecoin-project/venus-wallet/api"
"github.com/filecoin-project/venus-wallet/build"
"github.com/filecoin-project/venus-wallet/cmd"
"github.com/filecoin-project/venus-wallet/core"
"github.com/filecoin-project/venus-wallet/filemgr"
"github.com/filecoin-project/venus-wallet/middleware"
"github.com/filecoin-project/venus-wallet/version"
logging "github.com/ipfs/go-log/v2"
"github.com/multiformats/go-multiaddr"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
)

var log = logging.Logger("wallet_instance")

type WalletInst struct {
repo filemgr.Repo
repoDir string

stopChan chan error
sigChan chan os.Signal
}

func (inst *WalletInst) Start() (string, error) {
secret, err := inst.repo.APISecret()
if err != nil {
return "", err
}

var fullAPI api.IFullAPI
var appStopFn build.StopFunc

ctx, _ := tag.New(context.Background(), tag.Insert(middleware.Version, version.BuildVersion))

if appStopFn, err = build.New(ctx, build.FullAPIOpt(&fullAPI),
build.WalletOpt(inst.repo, ""),
build.CommonOpt(secret)); err != nil {
return "", err
}

// Register all metric views
if err = view.Register(
middleware.DefaultViews...,
); err != nil {
return "", fmt.Errorf("can't register the view: %v", err)
}
stats.Record(ctx, middleware.VenusInfo.M(1))

endPoint, err := inst.repo.APIEndpoint()
if err != nil {
return "", fmt.Errorf("get api endpoint failed:%w", err)
}

ma, err := multiaddr.NewMultiaddr(endPoint)
if err != nil {
return "", fmt.Errorf("new multi-address failed:%w", err)
}

url, err := ToURL(ma)
if err != nil {
return "", fmt.Errorf("convert multi-addr:%s to url failed:%w", endPoint, err)
}

go func() {
err := cmd.ServeRPC(fullAPI, appStopFn, endPoint, inst.sigChan)
inst.stopChan <- err
}()

return url.String(), inst.checkService()
}

func (inst *WalletInst) checkService() error {
select {
case err := <-inst.stopChan:
return err
case <-time.After(time.Second):
log.Info("no signal from stopping channel, after 1 second waitting...")
}
return nil
}

func (inst *WalletInst) StopAndWait() error {
inst.sigChan <- syscall.SIGINT
for {
if err := inst.checkService(); err != nil {
// server close is not an error
if strings.ContainsAny(err.Error(), "server closed") {
return nil
}
return err
}
}
}

func NewWalletInst() (*WalletInst, error) {
dir, err := ioutil.TempDir("", "venus_wallet_")
if err != nil {
return nil, err

}
repo, err := filemgr.NewFS(dir, nil)
if err != nil {
return nil, err
}
core.WalletStrategyLevel = repo.Config().Strategy.Level
return &WalletInst{
repo: repo,
sigChan: make(chan os.Signal, 1),
stopChan: make(chan error, 1),
repoDir: dir}, nil
}
Loading

0 comments on commit 2839136

Please sign in to comment.