mirror of
https://github.com/aunefyren/wrapperr
synced 2024-11-10 13:44:12 +00:00
787b00aebc
Different components moved to packages which are imported. More proper and clean compared to previous implementation.
111 lines
3.2 KiB
Go
111 lines
3.2 KiB
Go
package modules
|
|
|
|
import (
|
|
"aunefyren/wrapperr/files"
|
|
"aunefyren/wrapperr/models"
|
|
"errors"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
)
|
|
|
|
// AuthorizeToken validates JWT tokens using the private key.
|
|
func AuthorizeToken(writer http.ResponseWriter, request *http.Request) (*models.Payload, error) {
|
|
|
|
PrivateKey, err := files.GetPrivateKey()
|
|
if err != nil {
|
|
log.Println("Failed to load JWT Token settings. Error: ")
|
|
log.Println(err)
|
|
return &models.Payload{}, errors.New("Failed to load JWT Token settings.")
|
|
}
|
|
|
|
// Check if Authorization header is available
|
|
header := request.Header.Get("Authorization")
|
|
if header == "" || !strings.Contains(header, " ") || !strings.Contains(strings.ToLower(header), "bearer") {
|
|
log.Println("No valid Authorization token found in header during API request.")
|
|
return &models.Payload{}, errors.New("No valid Authorization token found in header.")
|
|
}
|
|
|
|
headerParts := strings.Split(header, " ")
|
|
|
|
if len(headerParts) < 2 {
|
|
log.Println("Failed to parse header. Error: ")
|
|
log.Println(err)
|
|
return &models.Payload{}, errors.New("Failed to parse header.")
|
|
}
|
|
|
|
jwtToken := headerParts[1]
|
|
|
|
payload, err := VerifyToken(PrivateKey, jwtToken)
|
|
if err != nil {
|
|
log.Println("Session token not accepted. Error: ")
|
|
log.Println(err)
|
|
return &models.Payload{}, errors.New("Session token not accepted. Please relog.")
|
|
}
|
|
|
|
return payload, nil
|
|
}
|
|
|
|
// VerifyToken checks if the token is valid or not
|
|
func VerifyToken(PrivateKey string, token string) (*models.Payload, error) {
|
|
keyFunc := func(token *jwt.Token) (interface{}, error) {
|
|
_, ok := token.Method.(*jwt.SigningMethodHMAC)
|
|
if !ok {
|
|
return nil, models.ErrInvalidToken
|
|
}
|
|
return []byte(PrivateKey), nil
|
|
}
|
|
|
|
jwtToken, err := jwt.ParseWithClaims(token, &models.Payload{}, keyFunc)
|
|
if err != nil {
|
|
verr, ok := err.(*jwt.ValidationError)
|
|
if ok && errors.Is(verr.Inner, jwt.ErrTokenExpired) {
|
|
return nil, models.ErrExpiredToken
|
|
}
|
|
return nil, models.ErrInvalidToken
|
|
}
|
|
|
|
payload, ok := jwtToken.Claims.(*models.Payload)
|
|
if !ok {
|
|
return nil, models.ErrInvalidToken
|
|
}
|
|
|
|
return payload, nil
|
|
}
|
|
|
|
// CreateToken creates a new JWT token used to validate a users session. Valid for three days by default.
|
|
func CreateToken(username string, admin bool, authtoken string) (string, error) {
|
|
|
|
PrivateKey, err := files.GetPrivateKey()
|
|
if err != nil {
|
|
log.Println("Failed to load JWT Token settings. Error: ")
|
|
log.Println(err)
|
|
return "", errors.New("Failed to load JWT Token settings.")
|
|
}
|
|
|
|
duration := time.Minute * 60 * 24 * 3
|
|
|
|
token, _, err := CreateTokenTwo(PrivateKey, username, admin, authtoken, duration)
|
|
if err != nil {
|
|
log.Println("Failed to create session token. Error: ")
|
|
log.Println(err)
|
|
return "", errors.New("Failed to create session token.")
|
|
}
|
|
|
|
return token, nil
|
|
}
|
|
|
|
// CreateToken creates a new token for a specific username and duration
|
|
func CreateTokenTwo(PrivateKey string, username string, admin bool, authtoken string, duration time.Duration) (string, *models.Payload, error) {
|
|
payload, err := NewPayload(username, admin, authtoken, duration)
|
|
if err != nil {
|
|
return "", payload, err
|
|
}
|
|
|
|
jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)
|
|
token, err := jwtToken.SignedString([]byte(PrivateKey))
|
|
return token, payload, err
|
|
}
|