mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-11-03 13:33:32 +00:00
feat: adds nonce check for oidc token exchange
- feat: adds filters support on conversations list - refactor middlewares.go - Adds new paginate.go for generating filtered paginated SQL queries this removes sql generation code from the conversations package. - rename some components - removes hardcoded `/uploads/`
This commit is contained in:
@@ -4,33 +4,59 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/abhinavxd/artemis/internal/envelope"
|
||||
umodels "github.com/abhinavxd/artemis/internal/user/models"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/zerodha/fastglue"
|
||||
)
|
||||
|
||||
// authMiddleware does session validation, CSRF checking, and permission enforcement.
|
||||
func authMiddleware(handler fastglue.FastRequestHandler, object, action string) fastglue.FastRequestHandler {
|
||||
// reqAuth makes sure the user is logged in.
|
||||
func reqAuth(handler fastglue.FastRequestHandler) fastglue.FastRequestHandler {
|
||||
return func(r *fastglue.Request) error {
|
||||
app := r.Context.(*App)
|
||||
var (
|
||||
app = r.Context.(*App)
|
||||
)
|
||||
|
||||
// Validate session and fetch user.
|
||||
userSession, err := app.auth.ValidateSession(r)
|
||||
if err != nil || userSession.ID <= 0 {
|
||||
app.lo.Error("error validating session", "error", err)
|
||||
return r.SendErrorEnvelope(http.StatusUnauthorized, "Invalid or expired session", nil, envelope.PermissionError)
|
||||
}
|
||||
|
||||
// Set user in the request context.
|
||||
user, err := app.user.Get(userSession.ID)
|
||||
if err != nil {
|
||||
return sendErrorEnvelope(r, err)
|
||||
}
|
||||
r.RequestCtx.SetUserValue("user", user)
|
||||
|
||||
return handler(r)
|
||||
}
|
||||
}
|
||||
|
||||
// reqAuthAndPerm does session validation, CSRF, and permission enforcement.
|
||||
func reqAuthAndPerm(handler fastglue.FastRequestHandler, object, action string) fastglue.FastRequestHandler {
|
||||
return func(r *fastglue.Request) error {
|
||||
var (
|
||||
app = r.Context.(*App)
|
||||
cookieToken = string(r.RequestCtx.Request.Header.Cookie("csrf_token"))
|
||||
hdrToken = string(r.RequestCtx.Request.Header.Peek("X-CSRFTOKEN"))
|
||||
)
|
||||
|
||||
if cookieToken == "" || hdrToken == "" || cookieToken != hdrToken {
|
||||
app.lo.Error("csrf token mismatch", "cookie_token", cookieToken, "header_token", hdrToken)
|
||||
return r.SendErrorEnvelope(http.StatusForbidden, "Invalid CSRF token", nil, envelope.PermissionError)
|
||||
}
|
||||
|
||||
// Validate session and fetch user.
|
||||
userSession, err := app.auth.ValidateSession(r)
|
||||
if err != nil || userSession.ID <= 0 {
|
||||
app.lo.Error("error validating session", "error", err)
|
||||
return r.SendErrorEnvelope(http.StatusUnauthorized, "Invalid or expired session", nil, envelope.PermissionError)
|
||||
}
|
||||
|
||||
user, err := app.user.Get(userSession.ID)
|
||||
if err != nil {
|
||||
return r.SendErrorEnvelope(http.StatusInternalServerError, "Something went wrong", nil, envelope.GeneralError)
|
||||
}
|
||||
|
||||
// CSRF check.
|
||||
cookieToken := string(r.RequestCtx.Request.Header.Cookie("csrf_token"))
|
||||
hdrToken := string(r.RequestCtx.Request.Header.Peek("X-CSRFTOKEN"))
|
||||
if cookieToken == "" || hdrToken == "" || cookieToken != hdrToken {
|
||||
return r.SendErrorEnvelope(http.StatusForbidden, "Invalid CSRF token", nil, envelope.PermissionError)
|
||||
return sendErrorEnvelope(r, err)
|
||||
}
|
||||
|
||||
// Permission enforcement.
|
||||
@@ -47,24 +73,25 @@ func authMiddleware(handler fastglue.FastRequestHandler, object, action string)
|
||||
// Set user in the request context.
|
||||
r.RequestCtx.SetUserValue("user", user)
|
||||
|
||||
// Proceed to the next handler.
|
||||
return handler(r)
|
||||
}
|
||||
}
|
||||
|
||||
// getUserFromContext retrieves the authenticated user from the request context.
|
||||
func getUserFromContext(r *fastglue.Request) (umodels.User, bool) {
|
||||
user, ok := r.RequestCtx.UserValue("user").(umodels.User)
|
||||
return user, ok
|
||||
}
|
||||
|
||||
// authenticatedPage ensures the user is logged in; otherwise, redirects to the login page.
|
||||
func authenticatedPage(handler fastglue.FastRequestHandler) fastglue.FastRequestHandler {
|
||||
return func(r *fastglue.Request) error {
|
||||
user, ok := getUserFromContext(r)
|
||||
if ok && user.ID > 0 {
|
||||
app := r.Context.(*App)
|
||||
|
||||
// Validate session.
|
||||
user, err := app.auth.ValidateSession(r)
|
||||
if err != nil {
|
||||
app.lo.Error("error validating session", "error", err)
|
||||
return r.SendErrorEnvelope(http.StatusUnauthorized, "Invalid or expired session", nil, envelope.PermissionError)
|
||||
}
|
||||
if user.ID > 0 {
|
||||
return handler(r)
|
||||
}
|
||||
|
||||
nextURI := r.RequestCtx.QueryArgs().Peek("next")
|
||||
if len(nextURI) == 0 {
|
||||
nextURI = r.RequestCtx.RequestURI()
|
||||
@@ -78,7 +105,15 @@ func authenticatedPage(handler fastglue.FastRequestHandler) fastglue.FastRequest
|
||||
// notAuthenticatedPage allows access only if the user is not authenticated; otherwise, redirects to the dashboard.
|
||||
func notAuthenticatedPage(handler fastglue.FastRequestHandler) fastglue.FastRequestHandler {
|
||||
return func(r *fastglue.Request) error {
|
||||
user, _ := getUserFromContext(r)
|
||||
app := r.Context.(*App)
|
||||
|
||||
// Validate session.
|
||||
user, err := app.auth.ValidateSession(r)
|
||||
if err != nil {
|
||||
app.lo.Error("error validating session", "error", err)
|
||||
return r.SendErrorEnvelope(http.StatusUnauthorized, "Invalid or expired session", nil, envelope.PermissionError)
|
||||
}
|
||||
|
||||
if user.ID != 0 {
|
||||
nextURI := string(r.RequestCtx.QueryArgs().Peek("next"))
|
||||
if nextURI == "" {
|
||||
|
||||
Reference in New Issue
Block a user