mirror of
https://github.com/tinyauthapp/tinyauth.git
synced 2026-09-02 03:23:32 +08:00
rework to keep regex under specific conditions
This commit is contained in:
@@ -9,14 +9,14 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.uber.org/dig"
|
||||||
|
|
||||||
"github.com/tinyauthapp/tinyauth/internal/model"
|
"github.com/tinyauthapp/tinyauth/internal/model"
|
||||||
"github.com/tinyauthapp/tinyauth/internal/service"
|
"github.com/tinyauthapp/tinyauth/internal/service"
|
||||||
"github.com/tinyauthapp/tinyauth/internal/utils"
|
"github.com/tinyauthapp/tinyauth/internal/utils"
|
||||||
"github.com/tinyauthapp/tinyauth/internal/utils/logger"
|
"github.com/tinyauthapp/tinyauth/internal/utils/logger"
|
||||||
"go.uber.org/dig"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/google/go-querystring/query"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthModuleType int
|
type AuthModuleType int
|
||||||
@@ -396,6 +396,10 @@ func (controller *ProxyController) getForwardAuthContext(c *gin.Context) (ProxyC
|
|||||||
return ProxyContext{}, fmt.Errorf("invalid x-forwarded-uri: %w", err)
|
return ProxyContext{}, fmt.Errorf("invalid x-forwarded-uri: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if parsedURI.Path == "" {
|
||||||
|
parsedURI.Path = "/"
|
||||||
|
}
|
||||||
|
|
||||||
proto, ok := controller.getHeader(c, "x-forwarded-proto")
|
proto, ok := controller.getHeader(c, "x-forwarded-proto")
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tinyauthapp/tinyauth/internal/model"
|
"github.com/tinyauthapp/tinyauth/internal/model"
|
||||||
@@ -179,26 +181,38 @@ type AuthEnabledRule struct {
|
|||||||
Log *logger.Logger
|
Log *logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPathRule(paths, path string) bool {
|
func matchPathRule(paths, path string) (bool, error) {
|
||||||
for _, configuredPath := range strings.Split(paths, ",") {
|
for _, configuredPath := range strings.Split(paths, ",") {
|
||||||
configuredPath = strings.TrimSpace(configuredPath)
|
configuredPath = strings.TrimSpace(configuredPath)
|
||||||
|
|
||||||
if configuredPath == "/" {
|
if configuredPath == "/" {
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
configuredPath = strings.TrimRight(configuredPath, "/")
|
|
||||||
|
|
||||||
if configuredPath == "" {
|
if configuredPath == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if path == configuredPath || strings.HasPrefix(path, configuredPath+"/") {
|
// only apply regex if the path starts and ends with a slash, e.g. /regex/
|
||||||
return true
|
if strings.HasPrefix(configuredPath, "/") && strings.HasSuffix(configuredPath, "/") {
|
||||||
|
regex, err := regexp.Compile(configuredPath[1 : len(configuredPath)-1])
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("invalid path regex %q: %w", configuredPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if regex.MatchString(path) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(path, configuredPath) {
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rule *AuthEnabledRule) Evaluate(ctx *ACLContext) Effect {
|
func (rule *AuthEnabledRule) Evaluate(ctx *ACLContext) Effect {
|
||||||
@@ -207,7 +221,11 @@ func (rule *AuthEnabledRule) Evaluate(ctx *ACLContext) Effect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ACLs.Path.Block != "" {
|
if ctx.ACLs.Path.Block != "" {
|
||||||
match := matchPathRule(ctx.ACLs.Path.Block, ctx.Path)
|
match, err := matchPathRule(ctx.ACLs.Path.Block, ctx.Path)
|
||||||
|
if err != nil {
|
||||||
|
rule.Log.App.Warn().Err(err).Msg("Invalid path block rule")
|
||||||
|
return EffectDeny
|
||||||
|
}
|
||||||
|
|
||||||
if !match {
|
if !match {
|
||||||
return EffectAllow
|
return EffectAllow
|
||||||
@@ -215,7 +233,11 @@ func (rule *AuthEnabledRule) Evaluate(ctx *ACLContext) Effect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ACLs.Path.Allow != "" {
|
if ctx.ACLs.Path.Allow != "" {
|
||||||
match := matchPathRule(ctx.ACLs.Path.Allow, ctx.Path)
|
match, err := matchPathRule(ctx.ACLs.Path.Allow, ctx.Path)
|
||||||
|
if err != nil {
|
||||||
|
rule.Log.App.Warn().Err(err).Msg("Invalid path allow rule")
|
||||||
|
return EffectDeny
|
||||||
|
}
|
||||||
|
|
||||||
if match {
|
if match {
|
||||||
return EffectAllow
|
return EffectAllow
|
||||||
|
|||||||
@@ -527,32 +527,22 @@ func TestAuthEnabledRule(t *testing.T) {
|
|||||||
expected: EffectDeny,
|
expected: EffectDeny,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "allows when path does not match block path",
|
name: "allows when path starts with allow path",
|
||||||
ctx: &ACLContext{
|
|
||||||
ACLs: &model.App{
|
|
||||||
Path: model.AppPath{Block: "/admin"},
|
|
||||||
},
|
|
||||||
Path: "/public",
|
|
||||||
},
|
|
||||||
expected: EffectAllow,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "denies when path matches block path",
|
|
||||||
ctx: &ACLContext{
|
|
||||||
ACLs: &model.App{
|
|
||||||
Path: model.AppPath{Block: "/admin"},
|
|
||||||
},
|
|
||||||
Path: "/admin/users",
|
|
||||||
},
|
|
||||||
expected: EffectDeny,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "allows when path matches allow path",
|
|
||||||
ctx: &ACLContext{
|
ctx: &ACLContext{
|
||||||
ACLs: &model.App{
|
ACLs: &model.App{
|
||||||
Path: model.AppPath{Allow: "/public"},
|
Path: model.AppPath{Allow: "/public"},
|
||||||
},
|
},
|
||||||
Path: "/public/index",
|
Path: "/publicity",
|
||||||
|
},
|
||||||
|
expected: EffectAllow,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "allows when path matches allow regex",
|
||||||
|
ctx: &ACLContext{
|
||||||
|
ACLs: &model.App{
|
||||||
|
Path: model.AppPath{Allow: "/^/public-[0-9]+$/"},
|
||||||
|
},
|
||||||
|
Path: "/public-42",
|
||||||
},
|
},
|
||||||
expected: EffectAllow,
|
expected: EffectAllow,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user