jwts.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package logic
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "time"
  8. "github.com/golang-jwt/jwt/v4"
  9. "github.com/gravitl/netmaker/db"
  10. "github.com/gravitl/netmaker/logger"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/schema"
  13. "github.com/gravitl/netmaker/servercfg"
  14. )
  15. var jwtSecretKey []byte
  16. // SetJWTSecret - sets the jwt secret on server startup
  17. func SetJWTSecret() {
  18. currentSecret, jwtErr := FetchJWTSecret()
  19. if jwtErr != nil {
  20. newValue := RandomString(64)
  21. jwtSecretKey = []byte(newValue) // 512 bit random password
  22. if err := StoreJWTSecret(string(jwtSecretKey)); err != nil {
  23. logger.FatalLog("something went wrong when configuring JWT authentication")
  24. }
  25. } else {
  26. jwtSecretKey = []byte(currentSecret)
  27. }
  28. }
  29. // CreateJWT func will used to create the JWT while signing in and signing out
  30. func CreateJWT(uuid string, macAddress string, network string) (response string, err error) {
  31. expirationTime := time.Now().Add(15 * time.Minute)
  32. claims := &models.Claims{
  33. ID: uuid,
  34. Network: network,
  35. MacAddress: macAddress,
  36. RegisteredClaims: jwt.RegisteredClaims{
  37. Issuer: "Netmaker",
  38. Subject: fmt.Sprintf("node|%s", uuid),
  39. IssuedAt: jwt.NewNumericDate(time.Now()),
  40. ExpiresAt: jwt.NewNumericDate(expirationTime),
  41. },
  42. }
  43. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  44. tokenString, err := token.SignedString(jwtSecretKey)
  45. if err == nil {
  46. return tokenString, nil
  47. }
  48. return "", err
  49. }
  50. // CreateUserJWT - creates a user jwt token
  51. func CreateUserAccessJwtToken(username string, role models.UserRoleID, d time.Time, tokenID string) (response string, err error) {
  52. claims := &models.UserClaims{
  53. UserName: username,
  54. Role: role,
  55. TokenType: models.AccessTokenType,
  56. Api: servercfg.GetAPIHost(),
  57. RacAutoDisable: GetRacAutoDisable() && (role != models.SuperAdminRole && role != models.AdminRole),
  58. RegisteredClaims: jwt.RegisteredClaims{
  59. Issuer: "Netmaker",
  60. Subject: fmt.Sprintf("user|%s", username),
  61. IssuedAt: jwt.NewNumericDate(time.Now()),
  62. ExpiresAt: jwt.NewNumericDate(d),
  63. ID: tokenID,
  64. },
  65. }
  66. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  67. tokenString, err := token.SignedString(jwtSecretKey)
  68. if err == nil {
  69. return tokenString, nil
  70. }
  71. return "", err
  72. }
  73. // CreateUserJWT - creates a user jwt token
  74. func CreateUserJWT(username string, role models.UserRoleID) (response string, err error) {
  75. settings := GetServerSettings()
  76. expirationTime := time.Now().Add(time.Duration(settings.JwtValidityDuration) * time.Minute)
  77. claims := &models.UserClaims{
  78. UserName: username,
  79. Role: role,
  80. TokenType: models.UserIDTokenType,
  81. RacAutoDisable: settings.RacAutoDisable && (role != models.SuperAdminRole && role != models.AdminRole),
  82. RegisteredClaims: jwt.RegisteredClaims{
  83. Issuer: "Netmaker",
  84. Subject: fmt.Sprintf("user|%s", username),
  85. IssuedAt: jwt.NewNumericDate(time.Now()),
  86. ExpiresAt: jwt.NewNumericDate(expirationTime),
  87. },
  88. }
  89. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  90. tokenString, err := token.SignedString(jwtSecretKey)
  91. if err == nil {
  92. return tokenString, nil
  93. }
  94. return "", err
  95. }
  96. func GetUserNameFromToken(authtoken string) (username string, err error) {
  97. claims := &models.UserClaims{}
  98. var tokenSplit = strings.Split(authtoken, " ")
  99. var tokenString = ""
  100. if len(tokenSplit) < 2 {
  101. return "", Unauthorized_Err
  102. } else {
  103. tokenString = tokenSplit[1]
  104. }
  105. if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
  106. return MasterUser, nil
  107. }
  108. token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
  109. return jwtSecretKey, nil
  110. })
  111. if err != nil {
  112. return "", Unauthorized_Err
  113. }
  114. if claims.TokenType == models.AccessTokenType {
  115. jti := claims.ID
  116. if jti != "" {
  117. a := schema.UserAccessToken{ID: jti}
  118. // check if access token is active
  119. err := a.Get(db.WithContext(context.TODO()))
  120. if err != nil {
  121. err = errors.New("token revoked")
  122. return "", err
  123. }
  124. a.LastUsed = time.Now().UTC()
  125. a.Update(db.WithContext(context.TODO()))
  126. }
  127. }
  128. if token != nil && token.Valid {
  129. var user *models.User
  130. // check that user exists
  131. user, err = GetUser(claims.UserName)
  132. if err != nil {
  133. return "", err
  134. }
  135. if user.UserName != "" {
  136. return user.UserName, nil
  137. }
  138. if user.PlatformRoleID != claims.Role {
  139. return "", Unauthorized_Err
  140. }
  141. err = errors.New("user does not exist")
  142. } else {
  143. err = Unauthorized_Err
  144. }
  145. return "", err
  146. }
  147. // VerifyUserToken func will used to Verify the JWT Token while using APIS
  148. func VerifyUserToken(tokenString string) (username string, issuperadmin, isadmin bool, err error) {
  149. claims := &models.UserClaims{}
  150. if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
  151. return MasterUser, true, true, nil
  152. }
  153. token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
  154. return jwtSecretKey, nil
  155. })
  156. if claims.TokenType == models.AccessTokenType {
  157. jti := claims.ID
  158. if jti != "" {
  159. a := schema.UserAccessToken{ID: jti}
  160. // check if access token is active
  161. err := a.Get(db.WithContext(context.TODO()))
  162. if err != nil {
  163. err = errors.New("token revoked")
  164. return "", false, false, err
  165. }
  166. a.LastUsed = time.Now().UTC()
  167. a.Update(db.WithContext(context.TODO()))
  168. }
  169. }
  170. if token != nil && token.Valid {
  171. var user *models.User
  172. // check that user exists
  173. user, err = GetUser(claims.UserName)
  174. if err != nil {
  175. return "", false, false, err
  176. }
  177. if user.UserName != "" {
  178. return user.UserName, user.PlatformRoleID == models.SuperAdminRole,
  179. user.PlatformRoleID == models.AdminRole, nil
  180. }
  181. err = errors.New("user does not exist")
  182. }
  183. return "", false, false, err
  184. }
  185. // VerifyHostToken - [hosts] Only
  186. func VerifyHostToken(tokenString string) (hostID string, mac string, network string, err error) {
  187. claims := &models.Claims{}
  188. // this may be a stupid way of serving up a master key
  189. // TODO: look into a different method. Encryption?
  190. if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
  191. return "mastermac", "", "", nil
  192. }
  193. token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
  194. return jwtSecretKey, nil
  195. })
  196. if token != nil {
  197. return claims.ID, claims.MacAddress, claims.Network, nil
  198. }
  199. return "", "", "", err
  200. }