auth: Store token in repo
This commit is contained in:
+20
-6
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
"github.com/filecoin-project/go-lotus/miner"
|
||||
"github.com/filecoin-project/go-lotus/node/client"
|
||||
"github.com/filecoin-project/go-lotus/node/repo"
|
||||
|
||||
"github.com/gbrlsnchs/jwt/v3"
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -26,12 +27,13 @@ var log = logging.Logger("node")
|
||||
type API struct {
|
||||
client.LocalStorage
|
||||
|
||||
Host host.Host
|
||||
Chain *chain.ChainStore
|
||||
PubSub *pubsub.PubSub
|
||||
Mpool *chain.MessagePool
|
||||
Wallet *chain.Wallet
|
||||
Host host.Host
|
||||
Chain *chain.ChainStore
|
||||
PubSub *pubsub.PubSub
|
||||
Mpool *chain.MessagePool
|
||||
Wallet *chain.Wallet
|
||||
Keystore types.KeyStore
|
||||
Repo repo.LockedRepo
|
||||
}
|
||||
|
||||
const JWTSecretName = "auth-jwt-private"
|
||||
@@ -68,7 +70,19 @@ func (a *API) AuthNew(ctx context.Context, perms []string) ([]byte, error) {
|
||||
return nil, xerrors.Errorf("writing API secret: %w", err)
|
||||
}
|
||||
|
||||
// TODO: put cli token in repo
|
||||
// TODO: make this configurable
|
||||
p := jwtPayload{
|
||||
Allow: api.AllPermissions,
|
||||
}
|
||||
|
||||
cliToken, err := jwt.Sign(&p, jwt.NewHS256(key.PrivateKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := a.Repo.SetAPIToken(cliToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
p := jwtPayload{
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ func rpcBuilder(t *testing.T, n int) []api.API {
|
||||
testServ := httptest.NewServer(rpcServer) // todo: close
|
||||
|
||||
var err error
|
||||
out[i], err = client.NewRPC("ws://" + testServ.Listener.Addr().String())
|
||||
out[i], err = client.NewRPC("ws://"+testServ.Listener.Addr().String(), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
|
||||
const (
|
||||
fsAPI = "api"
|
||||
fsAPIToken = "token"
|
||||
fsConfig = "config.toml"
|
||||
fsDatastore = "datastore"
|
||||
fsLibp2pKey = "libp2p.priv"
|
||||
@@ -109,6 +110,20 @@ func (fsr *FsRepo) APIEndpoint() (multiaddr.Multiaddr, error) {
|
||||
return apima, nil
|
||||
}
|
||||
|
||||
func (fsr *FsRepo) APIToken() ([]byte, error) {
|
||||
p := filepath.Join(fsr.path, fsAPIToken)
|
||||
f, err := os.Open(p)
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return nil, ErrNoAPIEndpoint
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close() //nolint: errcheck // Read only op
|
||||
|
||||
return ioutil.ReadAll(f)
|
||||
}
|
||||
|
||||
// Lock acquires exclusive lock on this repo
|
||||
func (fsr *FsRepo) Lock() (LockedRepo, error) {
|
||||
locked, err := fslock.Locked(fsr.path, fsLock)
|
||||
@@ -245,6 +260,13 @@ func (fsr *fsLockedRepo) SetAPIEndpoint(ma multiaddr.Multiaddr) error {
|
||||
return ioutil.WriteFile(fsr.join(fsAPI), []byte(ma.String()), 0644)
|
||||
}
|
||||
|
||||
func (fsr *fsLockedRepo) SetAPIToken(token []byte) error {
|
||||
if err := fsr.stillValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(fsr.join(fsAPIToken), token, 0600)
|
||||
}
|
||||
|
||||
func (fsr *fsLockedRepo) KeyStore() (types.KeyStore, error) {
|
||||
if err := fsr.stillValid(); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
var (
|
||||
ErrNoAPIEndpoint = errors.New("API not running (no endpoint)")
|
||||
ErrNoAPIToken = errors.New("API token not set")
|
||||
ErrRepoAlreadyLocked = errors.New("repo is already locked")
|
||||
ErrClosedRepo = errors.New("repo is no longer open")
|
||||
|
||||
@@ -24,6 +25,9 @@ type Repo interface {
|
||||
// APIEndpoint returns multiaddress for communication with Lotus API
|
||||
APIEndpoint() (multiaddr.Multiaddr, error)
|
||||
|
||||
// APIToken returns JWT API Token for use in operations that require auth
|
||||
APIToken() ([]byte, error)
|
||||
|
||||
// Lock locks the repo for exclusive use.
|
||||
Lock() (LockedRepo, error)
|
||||
}
|
||||
@@ -45,6 +49,9 @@ type LockedRepo interface {
|
||||
// so it can be read by API clients
|
||||
SetAPIEndpoint(multiaddr.Multiaddr) error
|
||||
|
||||
// SetAPIToken sets JWT API Token for CLI
|
||||
SetAPIToken([]byte) error
|
||||
|
||||
// KeyStore returns store of private keys for Filecoin transactions
|
||||
KeyStore() (types.KeyStore, error)
|
||||
|
||||
|
||||
+21
-1
@@ -18,7 +18,8 @@ import (
|
||||
type MemRepo struct {
|
||||
api struct {
|
||||
sync.Mutex
|
||||
ma multiaddr.Multiaddr
|
||||
ma multiaddr.Multiaddr
|
||||
token []byte
|
||||
}
|
||||
|
||||
repoLock chan struct{}
|
||||
@@ -102,6 +103,15 @@ func (mem *MemRepo) APIEndpoint() (multiaddr.Multiaddr, error) {
|
||||
return mem.api.ma, nil
|
||||
}
|
||||
|
||||
func (mem *MemRepo) APIToken() ([]byte, error) {
|
||||
mem.api.Lock()
|
||||
defer mem.api.Unlock()
|
||||
if mem.api.ma == nil {
|
||||
return nil, ErrNoAPIToken
|
||||
}
|
||||
return mem.api.token, nil
|
||||
}
|
||||
|
||||
func (mem *MemRepo) Lock() (LockedRepo, error) {
|
||||
select {
|
||||
case mem.repoLock <- struct{}{}:
|
||||
@@ -177,6 +187,16 @@ func (lmem *lockedMemRepo) SetAPIEndpoint(ma multiaddr.Multiaddr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lmem *lockedMemRepo) SetAPIToken(token []byte) error {
|
||||
if err := lmem.checkToken(); err != nil {
|
||||
return err
|
||||
}
|
||||
lmem.mem.api.Lock()
|
||||
lmem.mem.api.token = token
|
||||
lmem.mem.api.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lmem *lockedMemRepo) KeyStore() (types.KeyStore, error) {
|
||||
if err := lmem.checkToken(); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user