mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
133 lines
3.4 KiB
Go
133 lines
3.4 KiB
Go
|
|
package middleware
|
||
|
|
|
||
|
|
import (
|
||
|
|
"log/slog"
|
||
|
|
"net/http"
|
||
|
|
|
||
|
|
"github.com/SigNoz/signoz/pkg/authz"
|
||
|
|
"github.com/SigNoz/signoz/pkg/http/render"
|
||
|
|
"github.com/SigNoz/signoz/pkg/types/authtypes"
|
||
|
|
"github.com/gorilla/mux"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
authzDeniedMessage string = "::AUTHZ-DENIED::"
|
||
|
|
)
|
||
|
|
|
||
|
|
type AuthZ struct {
|
||
|
|
logger *slog.Logger
|
||
|
|
authzService authz.AuthZ
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewAuthZ(logger *slog.Logger) *AuthZ {
|
||
|
|
if logger == nil {
|
||
|
|
panic("cannot build authz middleware, logger is empty")
|
||
|
|
}
|
||
|
|
|
||
|
|
return &AuthZ{logger: logger}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (middleware *AuthZ) ViewAccess(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
claims, err := authtypes.ClaimsFromContext(req.Context())
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := claims.IsViewer(); err != nil {
|
||
|
|
middleware.logger.WarnContext(req.Context(), authzDeniedMessage, "claims", claims)
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func (middleware *AuthZ) EditAccess(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
claims, err := authtypes.ClaimsFromContext(req.Context())
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := claims.IsEditor(); err != nil {
|
||
|
|
middleware.logger.WarnContext(req.Context(), authzDeniedMessage, "claims", claims)
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func (middleware *AuthZ) AdminAccess(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
claims, err := authtypes.ClaimsFromContext(req.Context())
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := claims.IsAdmin(); err != nil {
|
||
|
|
middleware.logger.WarnContext(req.Context(), authzDeniedMessage, "claims", claims)
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func (middleware *AuthZ) SelfAccess(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
claims, err := authtypes.ClaimsFromContext(req.Context())
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
id := mux.Vars(req)["id"]
|
||
|
|
if err := claims.IsSelfAccess(id); err != nil {
|
||
|
|
middleware.logger.WarnContext(req.Context(), authzDeniedMessage, "claims", claims)
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func (middleware *AuthZ) OpenAccess(next http.HandlerFunc) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check middleware accepts the relation, typeable, parentTypeable (for direct access + group relations) and a callback function to derive selector and parentSelectors on per request basis.
|
||
|
|
func (middleware *AuthZ) Check(next http.HandlerFunc, relation authtypes.Relation, translation authtypes.Relation, typeable authtypes.Typeable, parentTypeable authtypes.Typeable, cb authtypes.SelectorCallbackFn) http.HandlerFunc {
|
||
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||
|
|
claims, err := authtypes.ClaimsFromContext(req.Context())
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
selector, parentSelectors, err := cb(req)
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
err = middleware.authzService.CheckWithTupleCreation(req.Context(), claims, relation, typeable, selector, parentTypeable, parentSelectors...)
|
||
|
|
if err != nil {
|
||
|
|
render.Error(rw, err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
next(rw, req)
|
||
|
|
})
|
||
|
|
}
|