Files
drive/apps/backend/internal/auth/middleware.go

64 lines
1.7 KiB
Go
Raw Permalink Normal View History

2025-11-26 01:09:42 +00:00
package auth
import (
"errors"
2025-11-30 19:19:33 +00:00
"log/slog"
2025-11-26 01:09:42 +00:00
"strings"
2025-11-30 19:19:33 +00:00
"github.com/get-drexa/drexa/internal/httperr"
2025-11-26 01:09:42 +00:00
"github.com/get-drexa/drexa/internal/user"
"github.com/gofiber/fiber/v2"
"github.com/uptrace/bun"
2025-11-26 01:09:42 +00:00
)
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 {
2025-11-26 01:09:42 +00:00
return func(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
if authHeader == "" {
2025-11-30 19:19:33 +00:00
slog.Info("no auth header")
2025-11-26 01:09:42 +00:00
return c.SendStatus(fiber.StatusUnauthorized)
}
parts := strings.Split(authHeader, " ")
if len(parts) != 2 || parts[0] != "Bearer" {
2025-11-30 19:19:33 +00:00
slog.Info("invalid auth header")
2025-11-26 01:09:42 +00:00
return c.SendStatus(fiber.StatusUnauthorized)
}
token := parts[1]
u, err := s.AuthenticateWithAccessToken(c.Context(), db, token)
2025-11-26 01:09:42 +00:00
if err != nil {
var e *InvalidAccessTokenError
if errors.As(err, &e) {
2025-11-30 19:19:33 +00:00
slog.Info("invalid access token")
2025-11-26 01:09:42 +00:00
return c.SendStatus(fiber.StatusUnauthorized)
}
var nf *user.NotFoundError
if errors.As(err, &nf) {
2025-11-30 19:19:33 +00:00
slog.Info("user not found")
2025-11-26 01:09:42 +00:00
return c.SendStatus(fiber.StatusUnauthorized)
}
2025-11-30 19:19:33 +00:00
return httperr.Internal(err)
2025-11-26 01:09:42 +00:00
}
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
}