Adding peer registration support to JWT (#305)

The management will validate the JWT as it does in the API
 and will register the Peer to the user's account.

New fields were added to grpc messages in management
 and client daemon and its clients were updated

Peer has one new field, UserID, 
that will hold the id of the user that registered it

JWT middleware CheckJWT got a splitter 
and renamed to support validation for non HTTP requests

Added test for adding new Peer with UserID

Lots of tests update because of a new field
This commit is contained in:
Maycon Santos
2022-05-05 20:02:15 +02:00
committed by GitHub
parent fbf778a221
commit fec3132585
24 changed files with 428 additions and 249 deletions

View File

@@ -41,6 +41,8 @@ type Peer struct {
//Name is peer's name (machine name)
Name string
Status *PeerStatus
//The user ID that registered the peer
UserID string
}
//Copy copies Peer object
@@ -52,6 +54,7 @@ func (p *Peer) Copy() *Peer {
Meta: p.Meta,
Name: p.Name,
Status: p.Status,
UserID: p.UserID,
}
}
@@ -233,9 +236,11 @@ func (am *DefaultAccountManager) GetNetworkMap(peerKey string) (*NetworkMap, err
// AddPeer adds a new peer to the Store.
// Each Account has a list of pre-authorised SetupKey and if no Account has a given key err wit ha code codes.Unauthenticated
// will be returned, meaning the key is invalid
// If a User ID is provided, it means that we passed the authentication using JWT, then we look for account by User ID and register the peer
// to it. We also add the User ID to the peer metadata to identify registrant.
// Each new Peer will be assigned a new next net.IP from the Account.Network and Account.Network.LastIP will be updated (IP's are not reused).
// The peer property is just a placeholder for the Peer properties to pass further
func (am *DefaultAccountManager) AddPeer(setupKey string, peer *Peer) (*Peer, error) {
func (am *DefaultAccountManager) AddPeer(setupKey string, userID string, peer *Peer) (*Peer, error) {
am.mux.Lock()
defer am.mux.Unlock()
@@ -244,24 +249,30 @@ func (am *DefaultAccountManager) AddPeer(setupKey string, peer *Peer) (*Peer, er
var account *Account
var err error
var sk *SetupKey
if len(upperKey) == 0 {
// Empty setup key, fail
return nil, status.Errorf(codes.InvalidArgument, "empty setupKey %s", setupKey)
} else {
if len(upperKey) != 0 {
account, err = am.Store.GetAccountBySetupKey(upperKey)
if err != nil {
return nil, status.Errorf(codes.NotFound, "unknown setupKey %s", upperKey)
return nil, status.Errorf(codes.NotFound, "unable to register peer, unable to find account with setupKey %s", upperKey)
}
sk = getAccountSetupKeyByKey(account, upperKey)
if sk == nil {
// shouldn't happen actually
return nil, status.Errorf(codes.NotFound, "unknown setupKey %s", upperKey)
return nil, status.Errorf(codes.NotFound, "unable to register peer, unknown setupKey %s", upperKey)
}
}
if !sk.IsValid() {
return nil, status.Errorf(codes.FailedPrecondition, "setup key was expired or overused %s", upperKey)
if !sk.IsValid() {
return nil, status.Errorf(codes.FailedPrecondition, "unable to register peer, setup key was expired or overused %s", upperKey)
}
} else if len(userID) != 0 {
account, err = am.Store.GetUserAccount(userID)
if err != nil {
return nil, status.Errorf(codes.NotFound, "unable to register peer, unknown user with ID: %s", userID)
}
} else {
// Empty setup key and jwt fail
return nil, status.Errorf(codes.InvalidArgument, "no setup key or user id provided")
}
var takenIps []net.IP
@@ -274,15 +285,18 @@ func (am *DefaultAccountManager) AddPeer(setupKey string, peer *Peer) (*Peer, er
newPeer := &Peer{
Key: peer.Key,
SetupKey: sk.Key,
SetupKey: upperKey,
IP: nextIp,
Meta: peer.Meta,
Name: peer.Name,
UserID: userID,
Status: &PeerStatus{Connected: false, LastSeen: time.Now()},
}
account.Peers[newPeer.Key] = newPeer
account.SetupKeys[sk.Key] = sk.IncrementUsage()
if len(upperKey) != 0 {
account.SetupKeys[sk.Key] = sk.IncrementUsage()
}
account.Network.IncSerial()
err = am.Store.SaveAccount(account)