mirror of https://github.com/grpc/grpc-go.git
authz: fix regex expression match (#5035)
* Fixes regex expression matching. * Adds tests * Updates FulMatchWithRegex and regex string for presence match. * Add tests for FullMatchWithRegex * Update regex to allow whitespace characters
This commit is contained in:
parent
fd4e3bdc3a
commit
5d90b32d9d
|
|
@ -94,7 +94,8 @@ func getStringMatcher(value string) *v3matcherpb.StringMatcher {
|
||||||
switch {
|
switch {
|
||||||
case value == "*":
|
case value == "*":
|
||||||
return &v3matcherpb.StringMatcher{
|
return &v3matcherpb.StringMatcher{
|
||||||
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{},
|
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{
|
||||||
|
SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
|
||||||
}
|
}
|
||||||
case strings.HasSuffix(value, "*"):
|
case strings.HasSuffix(value, "*"):
|
||||||
prefix := strings.TrimSuffix(value, "*")
|
prefix := strings.TrimSuffix(value, "*")
|
||||||
|
|
@ -117,8 +118,9 @@ func getHeaderMatcher(key, value string) *v3routepb.HeaderMatcher {
|
||||||
switch {
|
switch {
|
||||||
case value == "*":
|
case value == "*":
|
||||||
return &v3routepb.HeaderMatcher{
|
return &v3routepb.HeaderMatcher{
|
||||||
Name: key,
|
Name: key,
|
||||||
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_SafeRegexMatch{},
|
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_SafeRegexMatch{
|
||||||
|
SafeRegexMatch: &v3matcherpb.RegexMatcher{Regex: ".+"}},
|
||||||
}
|
}
|
||||||
case strings.HasSuffix(value, "*"):
|
case strings.HasSuffix(value, "*"):
|
||||||
prefix := strings.TrimSuffix(value, "*")
|
prefix := strings.TrimSuffix(value, "*")
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ func TestTranslatePolicy(t *testing.T) {
|
||||||
Ids: []*v3rbacpb.Principal{
|
Ids: []*v3rbacpb.Principal{
|
||||||
{Identifier: &v3rbacpb.Principal_Authenticated_{
|
{Identifier: &v3rbacpb.Principal_Authenticated_{
|
||||||
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
|
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
|
||||||
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{},
|
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
|
||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -95,8 +95,7 @@ var sdkTests = map[string]struct {
|
||||||
"request": {
|
"request": {
|
||||||
"paths":
|
"paths":
|
||||||
[
|
[
|
||||||
"/grpc.testing.TestService/UnaryCall",
|
"/grpc.testing.TestService/*"
|
||||||
"/grpc.testing.TestService/StreamingInputCall"
|
|
||||||
],
|
],
|
||||||
"headers":
|
"headers":
|
||||||
[
|
[
|
||||||
|
|
@ -122,11 +121,11 @@ var sdkTests = map[string]struct {
|
||||||
"allow_rules":
|
"allow_rules":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "allow_TestServiceCalls",
|
"name": "allow_all",
|
||||||
"request": {
|
"request": {
|
||||||
"paths":
|
"paths":
|
||||||
[
|
[
|
||||||
"/grpc.testing.TestService/*"
|
"*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,11 +133,11 @@ var sdkTests = map[string]struct {
|
||||||
"deny_rules":
|
"deny_rules":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "deny_TestServiceCalls",
|
"name": "deny_all",
|
||||||
"request": {
|
"request": {
|
||||||
"paths":
|
"paths":
|
||||||
[
|
[
|
||||||
"/grpc.testing.TestService/*"
|
"*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -300,6 +299,35 @@ var sdkTests = map[string]struct {
|
||||||
}`,
|
}`,
|
||||||
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
|
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
|
||||||
},
|
},
|
||||||
|
"DeniesRPCRequestNoMatchInAllowFailsPresenceMatch": {
|
||||||
|
authzPolicy: `{
|
||||||
|
"name": "authz",
|
||||||
|
"allow_rules":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "allow_TestServiceCalls",
|
||||||
|
"request": {
|
||||||
|
"paths":
|
||||||
|
[
|
||||||
|
"/grpc.testing.TestService/*"
|
||||||
|
],
|
||||||
|
"headers":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"key": "key-abc",
|
||||||
|
"values":
|
||||||
|
[
|
||||||
|
"*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
|
md: metadata.Pairs("key-abc", ""),
|
||||||
|
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s) TestSDKStaticPolicyEnd2End(t *testing.T) {
|
func (s) TestSDKStaticPolicyEnd2End(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,12 @@ package grpcutil
|
||||||
|
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
// FullMatchWithRegex returns whether the full string matches the regex provided.
|
// FullMatchWithRegex returns whether the full text matches the regex provided.
|
||||||
func FullMatchWithRegex(re *regexp.Regexp, string string) bool {
|
func FullMatchWithRegex(re *regexp.Regexp, text string) bool {
|
||||||
|
if len(text) == 0 {
|
||||||
|
return re.MatchString(text)
|
||||||
|
}
|
||||||
re.Longest()
|
re.Longest()
|
||||||
rem := re.FindString(string)
|
rem := re.FindString(text)
|
||||||
return len(rem) == len(string)
|
return len(rem) == len(text)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,18 @@ func TestFullMatchWithRegex(t *testing.T) {
|
||||||
string: "ab",
|
string: "ab",
|
||||||
want: true,
|
want: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "match all",
|
||||||
|
regexStr: ".*",
|
||||||
|
string: "",
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "matches non-empty strings",
|
||||||
|
regexStr: ".+",
|
||||||
|
string: "",
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue