servcvgen/jwt.go
2024-09-16 20:34:56 +01:00

183 lines
5.7 KiB
Go

package main
import (
b64 "encoding/base64"
"io/ioutil"
"time"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
gojwt "github.com/golang-jwt/jwt/v4"
log "github.com/sirupsen/logrus"
)
// func makeTokenString(SigningAlgorithm string, username string, cfg *Config) string {
// if SigningAlgorithm == "" {
// SigningAlgorithm = "HS256"
// }
// token := jwt.New(jwt.GetSigningMethod(SigningAlgorithm))
// claims := token.Claims.(jwt.MapClaims)
// claims["identity"] = username
// claims["exp"] = time.Now().Add(time.Hour).Unix()
// claims["orig_iat"] = time.Now().Unix()
// var tokenString string
// if SigningAlgorithm == "RS256" {
// keyData, _ := ioutil.ReadFile(cfg.KeyPem)
// signKey, _ := jwt.ParseRSAPrivateKeyFromPEM(keyData)
// tokenString, _ = token.SignedString(signKey)
// } else {
// tokenString, _ = token.SignedString(key)
// }
// return tokenString
// }
// func makeTokenString(mw *jwt.GinJWTMiddleware,data interface{}) (string,error) {
func makeTokenString(rtenv *RouteEnv,data interface{}) (string,error) {
if rtenv.AuthMiddleware == nil {
return "", nil
}
token := gojwt.New(gojwt.GetSigningMethod(rtenv.AuthMiddleware.SigningAlgorithm))
claims := token.Claims.(gojwt.MapClaims)
if rtenv.AuthMiddleware.PayloadFunc != nil {
for key, value := range rtenv.AuthMiddleware.PayloadFunc(data) {
claims[key] = value
}
}
expire := rtenv.AuthMiddleware.TimeFunc().Add(rtenv.AuthMiddleware.Timeout)
claims["exp"] = expire.Unix()
claims["orig_iat"] = rtenv.AuthMiddleware.TimeFunc().Unix()
var tokenString string
var err error
if rtenv.Cfg.SigningAlgorithm == "RS256" {
// if mw.usingPublicKeyAlgo() {
keyData, _ := ioutil.ReadFile(rtenv.Cfg.JwtKeyPem)
signKey, _ := gojwt.ParseRSAPrivateKeyFromPEM(keyData)
tokenString, err = token.SignedString(signKey)
} else {
tokenString, err = token.SignedString(rtenv.AuthMiddleware.Key)
}
return tokenString, err
}
func getJwt(rtenv *RouteEnv)*jwt.GinJWTMiddleware {
// the jwt middleware
authMiddleware, err := jwt.New(&jwt.GinJWTMiddleware{
Realm: rtenv.Cfg.JwtRealm,
Key: []byte(rtenv.Cfg.JwtKey),
Timeout: time.Duration(rtenv.Cfg.JwtTimeout) * time.Minute,
MaxRefresh: time.Duration(rtenv.Cfg.JwtMaxRefresh) * time.Minute,
IdentityKey: rtenv.Cfg.IdentityKey,
PrivKeyFile: rtenv.Cfg.KeyPem,
PubKeyFile: rtenv.Cfg.CertPem,
PayloadFunc: func(data interface{}) jwt.MapClaims {
if v, ok := data.(*User); ok {
return jwt.MapClaims{
rtenv.Cfg.IdentityKey: v.UserName,
"uuid": v.UUID,
"data": v.Data,
}
}
return jwt.MapClaims{}
},
IdentityHandler: func(c *gin.Context) interface{} {
claims := jwt.ExtractClaims(c)
username := ""
name, okname := claims[rtenv.Cfg.IdentityKey].(string)
if (okname) {
username = name
}
return &User{ UserName: username }
},
Authenticator: func(c *gin.Context) (interface{}, error) {
var loginVals Login
if err := c.ShouldBind(&loginVals); err != nil {
return "", jwt.ErrMissingLoginValues
}
userID := loginVals.Username
password := loginVals.Password
if val, ok := rtenv.Users.Accounts[userID]; ok {
pasw,_ := b64.StdEncoding.DecodeString(password)
pass := string(pasw)
txtdata,err := decrypt(val.Passwd, string(CRYPTKEY))
if err == nil && txtdata == pass {
return &User{
UserName: val.Id,
LastName: "",
FirstName: "",
}, nil
}
}
return nil, jwt.ErrFailedAuthentication
},
Authorizator: func(data interface{}, c *gin.Context) bool {
if v, ok := data.(*User); ok {
if v.UserName == rtenv.Cfg.PubUser {
return true
}
if _, ok := rtenv.Users.Accounts[v.UserName]; ok {
return true
} else {
return false
}
}
return false
},
Unauthorized: func(c *gin.Context, code int, message string) {
c.JSON(code, gin.H{
"code": code,
"message": message,
})
},
// TokenLookup is a string in the form of "<source>:<name>" that is used
// to extract token from the request.
// Optional. Default value "header:Authorization".
// Possible values:
// - "header:<name>"
// - "query:<name>"
// - "cookie:<name>"
// - "param:<name>"
TokenLookup: "header: Authorization, query: token, cookie: jwt",
// TokenLookup: "query:token",
// TokenLookup: "cookie:token",
// TokenHeadName is a string in the header. Default value is "Bearer"
TokenHeadName: "Bearer",
// TimeFunc provides the current time. You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens.
TimeFunc: time.Now,
})
if err != nil {
log.Fatal("JWT Error:" + err.Error())
}
return authMiddleware
}
// func refreshToken(c *gin.Context, rtenv *RouteEnv,data interface{}) (string, time.Time, error) {
// var expire time.Time
// claims, err := rtenv.AuthMiddleware.CheckIfTokenExpire(c)
// if err != nil {
// return "", expire, err
// }
// fmt.Printf("Refresh token: %v\n",claims)
// var token string
// token,err = makeTokenString(rtenv.AuthMiddleware,data)
// expire = time.Now()
// // // set cookie
// // if rtenv.AuthMiddleware.SendCookie {
// // expireCookie := rtenv.AuthMiddleware.TimeFunc().Add(rtenv.AuthMiddleware.CookieMaxAge)
// // maxage := int(expireCookie.Unix() - time.Now().Unix())
// // if rtenv.AuthMiddleware.CookieSameSite != 0 {
// // c.SetSameSite(rtenv.AuthMiddleware.CookieSameSite)
// // }
// // c.SetCookie(
// // rtenv.AuthMiddleware.CookieName,
// // tokenString,
// // maxage,
// // "/",
// // rtenv.AuthMiddleware.CookieDomain,
// // rtenv.AuthMiddleware.SecureCookie,
// // rtenv.AuthMiddleware.CookieHTTPOnly,
// // )
// // }
// return token, expire, nil
// }