2024-08-12 11:00:25 +02:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
2025-02-05 18:08:01 +01:00
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/common"
|
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/service"
|
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/utils/cookie"
|
2024-08-12 11:00:25 +02:00
|
|
|
)
|
|
|
|
|
|
2024-08-17 21:57:14 +02:00
|
|
|
type JwtAuthMiddleware struct {
|
2025-04-18 10:38:50 -05:00
|
|
|
userService *service.UserService
|
|
|
|
|
jwtService *service.JwtService
|
2024-08-17 21:57:14 +02:00
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:38:50 -05:00
|
|
|
func NewJwtAuthMiddleware(jwtService *service.JwtService, userService *service.UserService) *JwtAuthMiddleware {
|
|
|
|
|
return &JwtAuthMiddleware{jwtService: jwtService, userService: userService}
|
2024-08-17 21:57:14 +02:00
|
|
|
}
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2025-03-11 14:16:42 -05:00
|
|
|
func (m *JwtAuthMiddleware) Add(adminRequired bool) gin.HandlerFunc {
|
2024-08-17 21:57:14 +02:00
|
|
|
return func(c *gin.Context) {
|
2025-03-11 14:16:42 -05:00
|
|
|
userID, isAdmin, err := m.Verify(c, adminRequired)
|
|
|
|
|
if err != nil {
|
2024-08-12 11:00:25 +02:00
|
|
|
c.Abort()
|
2025-03-27 16:48:36 +01:00
|
|
|
_ = c.Error(err)
|
2024-08-12 11:00:25 +02:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-11 14:16:42 -05:00
|
|
|
c.Set("userID", userID)
|
|
|
|
|
c.Set("userIsAdmin", isAdmin)
|
|
|
|
|
c.Next()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-27 10:20:39 -07:00
|
|
|
func (m *JwtAuthMiddleware) Verify(c *gin.Context, adminRequired bool) (subject string, isAdmin bool, err error) {
|
2025-03-11 14:16:42 -05:00
|
|
|
// Extract the token from the cookie
|
2025-03-27 10:20:39 -07:00
|
|
|
accessToken, err := c.Cookie(cookie.AccessTokenCookieName)
|
2025-03-11 14:16:42 -05:00
|
|
|
if err != nil {
|
|
|
|
|
// Try to extract the token from the Authorization header if it's not in the cookie
|
2025-03-27 10:20:39 -07:00
|
|
|
var ok bool
|
|
|
|
|
_, accessToken, ok = strings.Cut(c.GetHeader("Authorization"), " ")
|
|
|
|
|
if !ok || accessToken == "" {
|
2025-03-11 14:16:42 -05:00
|
|
|
return "", false, &common.NotSignedInError{}
|
2024-08-12 11:00:25 +02:00
|
|
|
}
|
2025-03-11 14:16:42 -05:00
|
|
|
}
|
2024-08-12 11:00:25 +02:00
|
|
|
|
2025-03-27 10:20:39 -07:00
|
|
|
token, err := m.jwtService.VerifyAccessToken(accessToken)
|
2025-03-11 14:16:42 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return "", false, &common.NotSignedInError{}
|
2024-08-12 11:00:25 +02:00
|
|
|
}
|
2025-03-11 14:16:42 -05:00
|
|
|
|
2025-03-27 10:20:39 -07:00
|
|
|
subject, ok := token.Subject()
|
|
|
|
|
if !ok {
|
|
|
|
|
_ = c.Error(&common.TokenInvalidError{})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 10:38:50 -05:00
|
|
|
user, err := m.userService.GetUser(c, subject)
|
2025-03-27 10:20:39 -07:00
|
|
|
if err != nil {
|
2025-04-18 10:38:50 -05:00
|
|
|
return "", false, &common.NotSignedInError{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if user.Disabled {
|
|
|
|
|
return "", false, &common.UserDisabledError{}
|
2025-03-27 10:20:39 -07:00
|
|
|
}
|
2025-04-18 10:38:50 -05:00
|
|
|
|
|
|
|
|
if adminRequired && !user.IsAdmin {
|
2025-03-11 14:16:42 -05:00
|
|
|
return "", false, &common.MissingPermissionError{}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-27 10:20:39 -07:00
|
|
|
return subject, isAdmin, nil
|
2024-08-12 11:00:25 +02:00
|
|
|
}
|