Files

76 lines
1.8 KiB
Go

package middleware
import (
"context"
"net/http"
"strings"
"github.com/panelhosting/panel/internal/authsvc"
"github.com/panelhosting/panel/internal/config"
"github.com/panelhosting/panel/internal/models"
)
type ctxKey int
const userKey ctxKey = 1
func UserFromContext(ctx context.Context) (*models.User, bool) {
u, ok := ctx.Value(userKey).(*models.User)
return u, ok
}
type Auth struct {
auth *authsvc.Service
cfg *config.Config
}
func NewAuth(auth *authsvc.Service, cfg *config.Config) *Auth {
return &Auth{auth: auth, cfg: cfg}
}
func (a *Auth) Require(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
token := tokenFromRequest(r, a.cfg.SessionCookieName)
user, err := a.auth.UserByToken(r.Context(), token)
if err != nil {
writeUnauthorized(w)
return
}
ctx := context.WithValue(r.Context(), userKey, user)
next(w, r.WithContext(ctx))
}
}
func (a *Auth) Optional(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
token := tokenFromRequest(r, a.cfg.SessionCookieName)
user, err := a.auth.UserByToken(r.Context(), token)
if err == nil {
ctx := context.WithValue(r.Context(), userKey, user)
r = r.WithContext(ctx)
}
next(w, r)
}
}
func tokenFromRequest(r *http.Request, cookieName string) string {
if c, err := r.Cookie(cookieName); err == nil && c.Value != "" {
return c.Value
}
h := r.Header.Get("Authorization")
if strings.HasPrefix(h, "Bearer ") {
return strings.TrimPrefix(h, "Bearer ")
}
return ""
}
func writeUnauthorized(w http.ResponseWriter) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte(`{"error":"unauthorized"}`))
}
func IsAdmin(user *models.User) bool {
return user.Role == models.RoleSuperAdmin || user.Role == models.RoleAdmin
}