-
Notifications
You must be signed in to change notification settings - Fork 537
/
jwts.go
135 lines (117 loc) · 3.82 KB
/
jwts.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package logic
import (
"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 startup
func SetJWTSecret() {
currentSecret, jwtErr := FetchJWTSecret()
if jwtErr != nil {
newValue := RandomString(64)
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 out
func 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
}
// CreateUserJWT - creates a user jwt token
func CreateUserJWT(username string, issuperadmin, isadmin bool) (response string, err error) {
expirationTime := time.Now().Add(servercfg.GetServerConfig().JwtValidityDuration)
claims := &models.UserClaims{
UserName: username,
IsSuperAdmin: issuperadmin,
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 Header
func VerifyJWT(bearerToken string) (username string, issuperadmin, isadmin bool, err error) {
token := ""
tokenSplit := strings.Split(bearerToken, " ")
if len(tokenSplit) > 1 {
token = tokenSplit[1]
} else {
return "", false, false, errors.New("invalid auth header")
}
return VerifyUserToken(token)
}
// VerifyUserToken func will used to Verify the JWT Token while using APIS
func VerifyUserToken(tokenString string) (username string, issuperadmin, isadmin bool, err error) {
claims := &models.UserClaims{}
if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
return MasterUser, true, 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 "", false, false, err
}
if user.UserName != "" {
return user.UserName, user.IsSuperAdmin, user.IsAdmin, nil
}
err = errors.New("user does not exist")
}
return "", false, false, err
}
// VerifyHostToken - [hosts] Only
func 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
}