jwts.go 6.1 KB

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