Skip to content

Commit

Permalink
prevent usage of routeSelectors in a gateway AuthPolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
guicassolato committed Oct 19, 2023
1 parent 1f17905 commit a73ab1d
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 0 deletions.
39 changes: 39 additions & 0 deletions api/v1beta2/authpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,48 @@ func (ap *AuthPolicy) Validate() error {
if ap.Spec.TargetRef.Namespace != nil && string(*ap.Spec.TargetRef.Namespace) != ap.Namespace {
return fmt.Errorf("invalid targetRef.Namespace %s. Currently only supporting references to the same namespace", *ap.Spec.TargetRef.Namespace)
}

// prevents usage of routeSelectors in a gateway AuthPolicy
if ap.Spec.TargetRef.Kind == ("Gateway") {
containRouteSelectors := func(config map[string]RouteSelectorsGetter) bool {
if config == nil {
return false
}
for _, config := range config {
if len(config.GetRouteSelectors()) > 0 {
return true
}
}
return false
}
configs := []map[string]RouteSelectorsGetter{
{"": ap.Spec},
toRouteSelectorGetterMap(ap.Spec.AuthScheme.Authentication),
toRouteSelectorGetterMap(ap.Spec.AuthScheme.Metadata),
toRouteSelectorGetterMap(ap.Spec.AuthScheme.Authorization),
toRouteSelectorGetterMap(ap.Spec.AuthScheme.Callbacks),
}
if r := ap.Spec.AuthScheme.Response; r != nil {
configs = append(configs, toRouteSelectorGetterMap(r.Success.Headers), toRouteSelectorGetterMap(r.Success.DynamicMetadata))
}
for _, config := range configs {
if containRouteSelectors(config) {
return fmt.Errorf("route selectors not supported when targeting a Gateway")
}
}
}

return nil
}

func toRouteSelectorGetterMap[T RouteSelectorsGetter](m map[string]T) map[string]RouteSelectorsGetter {
result := make(map[string]RouteSelectorsGetter)
for k, v := range m {
result[k] = v
}
return result
}

func (ap *AuthPolicy) GetTargetRef() gatewayapiv1alpha2.PolicyTargetReference {
return ap.Spec.TargetRef
}
Expand Down
161 changes: 161 additions & 0 deletions api/v1beta2/authpolicy_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

authorinoapi "github.com/kuadrant/authorino/api/v1beta2"
"github.com/kuadrant/kuadrant-operator/pkg/common"
)

Expand Down Expand Up @@ -239,6 +240,166 @@ func TestAuthPolicyGetRulesHostnames(t *testing.T) {
}
}

func TestAuthPolicyValidate(t *testing.T) {
testCases := []struct {
name string
policy *AuthPolicy
valid bool
message string
}{
{
name: "valid policy targeting a httproute",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "gateway.networking.k8s.io",
Kind: "HTTPRoute",
Name: "my-route",
},
},
},
valid: true,
},
{
name: "valid policy targeting a gateway",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "gateway.networking.k8s.io",
Kind: "Gateway",
Name: "my-gw",
},
},
},
valid: true,
},
{
name: "invalig targetRef group",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "not-gateway.networking.k8s.io.group",
Kind: "HTTPRoute",
Name: "my-non-gwapi-route",
},
},
},
message: "invalid targetRef.Group not-gateway.networking.k8s.io.group. The only supported group is gateway.networking.k8s.io",
},
{
name: "invalid targetRef kind",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "gateway.networking.k8s.io",
Kind: "TCPRoute",
Name: "my-tcp-route",
},
},
},
message: "invalid targetRef.Kind TCPRoute. The only supported kinds are HTTPRoute and Gateway",
},
{
name: "invalid usage of top-level route selectors with a gateway targetRef",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "gateway.networking.k8s.io",
Kind: "Gateway",
Name: "my-gw",
},
RouteSelectors: []RouteSelector{
{
Hostnames: []gatewayapiv1beta1.Hostname{"*.foo.io"},
Matches: []gatewayapiv1beta1.HTTPRouteMatch{
{
Path: &gatewayapiv1beta1.HTTPPathMatch{
Value: ptr.To("/foo"),
},
},
},
},
},
},
},
message: "route selectors not supported when targeting a Gateway",
},
{
name: "invalid usage of config-level route selectors with a gateway targetRef",
policy: &AuthPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "my-policy",
Namespace: "my-namespace",
},
Spec: AuthPolicySpec{
TargetRef: gatewayapiv1alpha2.PolicyTargetReference{
Group: "gateway.networking.k8s.io",
Kind: "Gateway",
Name: "my-gw",
},
AuthScheme: AuthSchemeSpec{
Authentication: map[string]AuthenticationSpec{
"my-rule": {
AuthenticationSpec: authorinoapi.AuthenticationSpec{
AuthenticationMethodSpec: authorinoapi.AuthenticationMethodSpec{
AnonymousAccess: &authorinoapi.AnonymousAccessSpec{},
},
},
CommonAuthRuleSpec: CommonAuthRuleSpec{
RouteSelectors: []RouteSelector{
{
Hostnames: []gatewayapiv1beta1.Hostname{"*.foo.io"},
Matches: []gatewayapiv1beta1.HTTPRouteMatch{
{
Path: &gatewayapiv1beta1.HTTPPathMatch{
Value: ptr.To("/foo"),
},
},
},
},
},
},
},
},
},
},
},
message: "route selectors not supported when targeting a Gateway",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := tc.policy.Validate()
if tc.valid && result != nil {
t.Errorf("Expected policy to be valid, got %t", result)
}
if !tc.valid && result == nil {
t.Error("Expected policy to be invalid, got no validation error")
}
})
}
}

func testBuildRouteSelector() RouteSelector {
return RouteSelector{
Hostnames: []gatewayapiv1beta1.Hostname{"toystore.kuadrant.io"},
Expand Down

0 comments on commit a73ab1d

Please sign in to comment.