| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | package logicimport (	"errors"	"fmt"	"strings"	"time"	"github.com/golang-jwt/jwt/v4"	"github.com/gravitl/netmaker/logger"	"github.com/gravitl/netmaker/models"	"github.com/gravitl/netmaker/servercfg")var jwtSecretKey []byte// SetJWTSecret - sets the jwt secret on server startupfunc SetJWTSecret() {	currentSecret, jwtErr := FetchJWTSecret()	if jwtErr != nil {		newValue, err := GenerateCryptoString(64)		if err != nil {			logger.FatalLog("something went wrong when generating JWT signature")		}		jwtSecretKey = []byte(newValue) // 512 bit random password		if err := StoreJWTSecret(string(jwtSecretKey)); err != nil {			logger.FatalLog("something went wrong when configuring JWT authentication")		}	} else {		jwtSecretKey = []byte(currentSecret)	}}// CreateJWT func will used to create the JWT while signing in and signing outfunc CreateJWT(uuid string, macAddress string, network string) (response string, err error) {	expirationTime := time.Now().Add(5 * time.Minute)	claims := &models.Claims{		ID:         uuid,		Network:    network,		MacAddress: macAddress,		RegisteredClaims: jwt.RegisteredClaims{			Issuer:    "Netmaker",			Subject:   fmt.Sprintf("node|%s", uuid),			IssuedAt:  jwt.NewNumericDate(time.Now()),			ExpiresAt: jwt.NewNumericDate(expirationTime),		},	}	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)	tokenString, err := token.SignedString(jwtSecretKey)	if err == nil {		return tokenString, nil	}	return "", err}// CreateProUserJWT - creates a user jwt tokenfunc CreateProUserJWT(username string, networks, groups []string, isadmin bool) (response string, err error) {	expirationTime := time.Now().Add(60 * 12 * time.Minute)	claims := &models.UserClaims{		UserName: username,		Networks: networks,		IsAdmin:  isadmin,		Groups:   groups,		RegisteredClaims: jwt.RegisteredClaims{			Issuer:    "Netmaker",			Subject:   fmt.Sprintf("user|%s", username),			IssuedAt:  jwt.NewNumericDate(time.Now()),			ExpiresAt: jwt.NewNumericDate(expirationTime),		},	}	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)	tokenString, err := token.SignedString(jwtSecretKey)	if err == nil {		return tokenString, nil	}	return "", err}// CreateUserJWT - creates a user jwt tokenfunc CreateUserJWT(username string, networks []string, isadmin bool) (response string, err error) {	expirationTime := time.Now().Add(60 * 12 * time.Minute)	claims := &models.UserClaims{		UserName: username,		Networks: networks,		IsAdmin:  isadmin,		RegisteredClaims: jwt.RegisteredClaims{			Issuer:    "Netmaker",			Subject:   fmt.Sprintf("user|%s", username),			IssuedAt:  jwt.NewNumericDate(time.Now()),			ExpiresAt: jwt.NewNumericDate(expirationTime),		},	}	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)	tokenString, err := token.SignedString(jwtSecretKey)	if err == nil {		return tokenString, nil	}	return "", err}// VerifyJWT verifies Auth Headerfunc VerifyJWT(bearerToken string) (username string, networks []string, isadmin bool, err error) {	token := ""	tokenSplit := strings.Split(bearerToken, " ")	if len(tokenSplit) > 1 {		token = tokenSplit[1]	} else {		return "", nil, false, errors.New("invalid auth header")	}	return VerifyUserToken(token)}// VerifyUserToken func will used to Verify the JWT Token while using APISfunc VerifyUserToken(tokenString string) (username string, networks []string, isadmin bool, err error) {	claims := &models.UserClaims{}	if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {		return "masteradministrator", nil, true, nil	}	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {		return jwtSecretKey, nil	})	if token != nil && token.Valid {		var user *models.User		// check that user exists		user, err = GetUser(claims.UserName)		if err != nil {			return "", nil, false, err		}		if user.UserName != "" {			return claims.UserName, claims.Networks, claims.IsAdmin, nil		}		err = errors.New("user does not exist")	}	return "", nil, false, err}// VerifyHostToken - [hosts] Onlyfunc VerifyHostToken(tokenString string) (hostID string, mac string, network string, err error) {	claims := &models.Claims{}	// this may be a stupid way of serving up a master key	// TODO: look into a different method. Encryption?	if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {		return "mastermac", "", "", nil	}	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {		return jwtSecretKey, nil	})	if token != nil {		return claims.ID, claims.MacAddress, claims.Network, nil	}	return "", "", "", err}
 |