package api
import (
"fmt"
"strings"
"time"
"immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/db"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)
// Static secret.
var JWT_SECRET []byte
type JwtClaims struct {
Authorized bool `json:"authorized"`
Subject int64 `json:"sub,omitempty"`
jwt.StandardClaims
}
func SetJwtSecretKey(secret string) {
JWT_SECRET = []byte(secret)
}
func VerifyJwtToken(token string) (JwtClaims, error) {
if len(JWT_SECRET) == 0 {
return JwtClaims{}, fmt.Errorf("not initialized jwt secret")
}
t, err := jwt.ParseWithClaims(token, &JwtClaims{}, func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])
}
return JWT_SECRET, nil
})
claims, ok := t.Claims.(*JwtClaims)
if !ok || !t.Valid || err != nil {
return JwtClaims{}, fmt.Errorf("invalid token (err: %v, claimsok: %v)", err, ok)
}
return *claims, nil
}
func SignJwt(claims JwtClaims) (string, error) {
if len(JWT_SECRET) == 0 {
return "", fmt.Errorf("not initialized jwt secret")
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims)
return token.SignedString(JWT_SECRET)
}
func CreateJwtToken(userId int64) (string, error) {
claims := JwtClaims{
false,
userId,
jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
},
}
return SignJwt(claims)
}
func GetBearerToken(header string) (string, error) {
const prefix = "Bearer "
if !strings.HasPrefix(header, prefix) {
return "", fmt.Errorf("invalid authorization token")
}
return header[len(prefix):], nil
}
func JwtAuth(c *gin.Context) *Error {
token, err := GetBearerToken(c.GetHeader("Authorization"))
if err != nil {
return &Error{NotAuthorized, "not authorized", err}
}
claims, err := VerifyJwtToken(token)
if err != nil {
return &Error{NotAuthorized, "not authorized", err}
}
user, err := db.GetUserById(claims.Subject)
if err != nil {
return &Error{NotAuthorized, "not authorized", err}
}
c.Set("user", *user)
c.Set("claims", claims)
return nil
}
func GetClaims(c *gin.Context) JwtClaims {
claims, _ := c.Get("claims")
return claims.(JwtClaims)
}