mirror of
https://github.com/get-drexa/drive.git
synced 2025-11-30 21:41:39 +00:00
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"errors"
|
|
"log/slog"
|
|
"strings"
|
|
|
|
"github.com/get-drexa/drexa/internal/httperr"
|
|
"github.com/get-drexa/drexa/internal/user"
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
const authenticatedUserKey = "authenticatedUser"
|
|
|
|
// NewBearerAuthMiddleware is a middleware that authenticates a request using a bearer token.
|
|
// To obtain the authenticated user in subsequent handlers, see AuthenticatedUser.
|
|
func NewBearerAuthMiddleware(s *Service, db *bun.DB) fiber.Handler {
|
|
return func(c *fiber.Ctx) error {
|
|
authHeader := c.Get("Authorization")
|
|
if authHeader == "" {
|
|
slog.Info("no auth header")
|
|
return c.SendStatus(fiber.StatusUnauthorized)
|
|
}
|
|
|
|
parts := strings.Split(authHeader, " ")
|
|
if len(parts) != 2 || parts[0] != "Bearer" {
|
|
slog.Info("invalid auth header")
|
|
return c.SendStatus(fiber.StatusUnauthorized)
|
|
}
|
|
|
|
token := parts[1]
|
|
u, err := s.AuthenticateWithAccessToken(c.Context(), db, token)
|
|
if err != nil {
|
|
var e *InvalidAccessTokenError
|
|
if errors.As(err, &e) {
|
|
slog.Info("invalid access token")
|
|
return c.SendStatus(fiber.StatusUnauthorized)
|
|
}
|
|
|
|
var nf *user.NotFoundError
|
|
if errors.As(err, &nf) {
|
|
slog.Info("user not found")
|
|
return c.SendStatus(fiber.StatusUnauthorized)
|
|
}
|
|
|
|
return httperr.Internal(err)
|
|
}
|
|
|
|
c.Locals(authenticatedUserKey, u)
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// AuthenticatedUser returns the authenticated user from the given fiber context.
|
|
// Returns ErrUnauthenticatedRequest if not authenticated.
|
|
func AuthenticatedUser(c *fiber.Ctx) (*user.User, error) {
|
|
if u, ok := c.Locals(authenticatedUserKey).(*user.User); ok {
|
|
return u, nil
|
|
}
|
|
return nil, ErrUnauthenticatedRequest
|
|
}
|