Files
restxlsx/internal/auth/auth.go
T
2026-06-10 13:01:57 +02:00

84 lines
1.8 KiB
Go

package auth
import (
"context"
"net/http"
)
type roleKey struct{}
type Role int
const (
RoleReader Role = iota
RoleWriter
RoleAdmin
)
func ParseRole(s string) Role {
switch s {
case "admin":
return RoleAdmin
case "writer":
return RoleWriter
default:
return RoleReader
}
}
func (r Role) CanRead() bool { return true }
func (r Role) CanWrite() bool { return r >= RoleWriter }
func (r Role) CanDDL() bool { return r >= RoleAdmin }
type Handler struct {
role Role
}
func New(roleStr string) *Handler {
return &Handler{role: ParseRole(roleStr)}
}
func (h *Handler) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), roleKey{}, h.role)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func RoleFromContext(ctx context.Context) Role {
if r, ok := ctx.Value(roleKey{}).(Role); ok {
return r
}
return RoleReader
}
func RequireWrite(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !RoleFromContext(r.Context()).CanWrite() {
http.Error(w, `{"error":"forbidden: write access required"}`, http.StatusForbidden)
return
}
next(w, r)
}
}
func RequireDDL(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !RoleFromContext(r.Context()).CanDDL() {
http.Error(w, `{"error":"forbidden: admin access required"}`, http.StatusForbidden)
return
}
next(w, r)
}
}
func RequireWriteMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !RoleFromContext(r.Context()).CanWrite() {
http.Error(w, `{"error":"forbidden: write access required"}`, http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}