auth: Store token in repo

This commit is contained in:
Łukasz Magiera
2019-07-24 00:38:52 +02:00
parent 309ecc4052
commit a88be8d1df
11 changed files with 107 additions and 23 deletions
+20 -6
View File
@@ -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
View File
@@ -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)
}
+22
View File
@@ -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
+7
View File
@@ -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
View File
@@ -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