customer/internal/utils/authenticator.go

63 lines
1.3 KiB
Go

package utils
import (
"fmt"
"github.com/gofiber/fiber/v2"
"strings"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
)
const (
prefix = "Bearer "
)
func NewAuthenticator(jwtUtil *JWT) fiber.Handler {
return func(c *fiber.Ctx) error {
if jwtUtil == nil {
return fiber.NewError(fiber.StatusInternalServerError, errors.ErrInvalidArgs.Error())
}
err := authenticate(jwtUtil, c)
if err != nil {
return fiber.NewError(fiber.StatusUnauthorized, err.Error())
}
return c.Next()
}
}
func authenticate(jwtUtil *JWT, c *fiber.Ctx) error {
if c.Path() == "/account/pipe" {
return c.Next()
}
jws, err := parseJWSFromRequest(c)
if err != nil {
return err
}
userID, validateErr := jwtUtil.Validate(jws)
if validateErr != nil {
return validateErr
}
c.Locals(models.AuthJWTDecodedUserIDKey, userID)
c.Locals(models.AuthJWTDecodedAccessTokenKey, jws)
return nil
}
func parseJWSFromRequest(c *fiber.Ctx) (string, error) {
header := c.Get("Authorization")
if header == "" || !strings.HasPrefix(header, prefix) {
return "", errors.New(
fmt.Errorf("failed to parse jws from request header: %s", header),
errors.ErrNoAccess,
)
}
return strings.TrimPrefix(header, prefix), nil
}