91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/mattnite/forgejo-tickets/internal/models"
|
|
)
|
|
|
|
const userContextKey = "user"
|
|
|
|
type requestContextKey string
|
|
|
|
const userRequestContextKey requestContextKey = "user"
|
|
|
|
func (s *Service) SessionMiddleware(c *gin.Context) {
|
|
session, err := s.store.Get(c.Request, sessionCookieName)
|
|
if err != nil || session.IsNew {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
userIDStr, ok := session.Values["user_id"].(string)
|
|
if !ok {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
userID, err := uuid.Parse(userIDStr)
|
|
if err != nil {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
var user models.User
|
|
if err := s.db.First(&user, "id = ?", userID).Error; err != nil {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
c.Set(userContextKey, &user)
|
|
// Also store on the request context so the template renderer can access it
|
|
c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), userRequestContextKey, &user))
|
|
c.Next()
|
|
}
|
|
|
|
func RequireAuth(c *gin.Context) {
|
|
if CurrentUser(c) == nil {
|
|
c.Redirect(http.StatusSeeOther, "/login")
|
|
c.Abort()
|
|
return
|
|
}
|
|
c.Next()
|
|
}
|
|
|
|
func RequireAdmin(c *gin.Context) {
|
|
user := CurrentUser(c)
|
|
if user == nil {
|
|
c.Redirect(http.StatusSeeOther, "/login")
|
|
c.Abort()
|
|
return
|
|
}
|
|
if !user.IsAdmin() {
|
|
c.Redirect(http.StatusSeeOther, "/")
|
|
c.Abort()
|
|
return
|
|
}
|
|
c.Next()
|
|
}
|
|
|
|
func CurrentUser(c *gin.Context) *models.User {
|
|
user, exists := c.Get(userContextKey)
|
|
if !exists {
|
|
return nil
|
|
}
|
|
u, ok := user.(*models.User)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return u
|
|
}
|
|
|
|
// CurrentUserFromRequest retrieves the current user from the request context.
|
|
// Used by the template renderer which receives *http.Request instead of *gin.Context.
|
|
func CurrentUserFromRequest(r *http.Request) *models.User {
|
|
user, _ := r.Context().Value(userRequestContextKey).(*models.User)
|
|
return user
|
|
}
|