feat(auth): add RequireAdmin middleware to enforce admin access control

This commit is contained in:
Nik Afiq 2025-12-11 23:16:30 +09:00
parent ff5c5f1b1d
commit 889f072390
2 changed files with 23 additions and 1 deletions

View File

@ -34,7 +34,7 @@ func NewRouter(svc episode.UseCases, verifier auth.TokenVerifier, authEnabled bo
if authEnabled && verifier != nil {
protected := v1.Group("/")
protected.Use(AuthMiddleware(verifier))
protected.Use(AuthMiddleware(verifier), RequireAdmin())
protected.DELETE("/shows", deleteShowsHandler(svc))
protected.POST("/archive", moveToArchiveHandler(svc))
} else {

View File

@ -4,6 +4,7 @@ import (
"net/http"
"strings"
fbauth "firebase.google.com/go/v4/auth"
"watch-party-backend/internal/auth"
"github.com/gin-gonic/gin"
@ -31,3 +32,24 @@ func AuthMiddleware(verifier auth.TokenVerifier) gin.HandlerFunc {
c.Next()
}
}
// RequireAdmin enforces a custom claim "admin": true on the Firebase token.
func RequireAdmin() gin.HandlerFunc {
return func(c *gin.Context) {
val, ok := c.Get("firebaseToken")
if !ok {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
return
}
token, ok := val.(*fbauth.Token)
if !ok {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
return
}
if isAdmin, ok := token.Claims["admin"].(bool); !ok || !isAdmin {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "forbidden"})
return
}
c.Next()
}
}