jwts.go 6.1 KB

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