mirror of https://gitlab.com/ngerakines/tavern.git
85 lines
2.5 KiB
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)
|
|
}
|