tavern/web/handler_auth.go

85 lines
2.5 KiB
Go

package web
import (
"context"
"strings"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/gofrs/uuid"
"go.uber.org/zap"
"github.com/ngerakines/tavern/common"
"github.com/ngerakines/tavern/errors"
"github.com/ngerakines/tavern/storage"
)
func (h handler) loggedIn(c *gin.Context, requireUser bool) (gin.H, *storage.User, sessions.Session, bool) {
session := sessions.Default(c)
ctx := c.Request.Context()
trans, transOK := c.Get("trans")
if !transOK {
panic(errors.NewTranslatorNotFoundError(nil))
}
data := gin.H{
"flashes": getFlashes(session),
"Trans": trans,
}
user, err := h.storage.GetUserBySession(ctx, session)
if requireUser && err != nil && errors.Is(err, errors.UserSessionNotFoundError{}) {
h.flashErrorOrFail(c, h.url(), errors.NewAuthenticationRequiredError(err))
return nil, nil, nil, false
} else if err != nil && !errors.Is(err, errors.UserSessionNotFoundError{}) {
h.hardFail(c, err)
return nil, nil, nil, false
}
if user != nil {
data["user"] = user
data["authenticated"] = true
}
return data, user, session, true
}
func (h handler) loggedInAPI(c *gin.Context, requireUser bool) (*storage.User, sessions.Session, bool) {
session := sessions.Default(c)
ctx := c.Request.Context()
user, err := h.storage.GetUserBySession(ctx, session)
if requireUser && err != nil && errors.Is(err, errors.UserSessionNotFoundError{}) {
h.flashErrorOrFail(c, h.url(), errors.NewAuthenticationRequiredError(err))
return nil, nil, false
} else if err != nil && !errors.Is(err, errors.UserSessionNotFoundError{}) {
h.hardFail(c, err)
return nil, nil, false
}
return user, session, true
}
func allow(ctx context.Context, logger *zap.Logger, s storage.Storage, serverScope, localScope uuid.UUID, target string) bool {
var matchSet common.MatcherSet
domain := strings.TrimPrefix(target, "https://")
if i := strings.IndexRune(domain, '/'); i > -1 {
domain = domain[:i]
}
targets := common.NewUniqueStrings().With(target, domain)
txErr := storage.TransactionalStorage(ctx, s, func(tx storage.Storage) error {
acls, err := tx.ListACLsByScopesAndWildTargets(ctx, []uuid.UUID{serverScope, localScope}, targets.Values)
if err != nil {
return err
}
matchSet = acls.ToMatchSet(common.NewUniqueUUIDs().With(serverScope), true)
return nil
})
if txErr != nil {
logger.Warn("unable to verify allow deny", zap.Error(txErr), zap.String("target", target))
return false
}
return matchSet.Allow(domain, target)
}