Skip to content

Commit

Permalink
tests: add skel for redirect ui matching tests
Browse files Browse the repository at this point in the history
  • Loading branch information
greenpau committed Mar 14, 2024
1 parent 0aa44cf commit 9840d0f
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 71 deletions.
85 changes: 14 additions & 71 deletions pkg/redirects/redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package redirects

import (
"fmt"
"net/url"
"regexp"
"strings"
)
Expand Down Expand Up @@ -45,6 +44,20 @@ type RedirectURIMatchConfig struct {
domainRegex *regexp.Regexp
}

// NewRedirectURIMatchConfig return an instance of *RedirectURIMatchConfig.
func NewRedirectURIMatchConfig(domainMatchType, domain, pathMatchType, path string) (*RedirectURIMatchConfig, error) {
c := &RedirectURIMatchConfig{
PathMatchType: pathMatchType,
Path: path,
DomainMatchType: domainMatchType,
Domain: domain,
}
if err := c.Validate(); err != nil {
return nil, err
}
return c, nil
}

// Validate validates RedirectURIMatchConfig.
func (c *RedirectURIMatchConfig) Validate() error {
switch c.PathMatchType {
Expand Down Expand Up @@ -110,73 +123,3 @@ func (c *RedirectURIMatchConfig) Validate() error {

return nil
}

// Match matches HTTP URL to the bypass configuration.
func Match(u *url.URL, cfgs []*RedirectURIMatchConfig) bool {
pathMatched := false
domainMatched := false

for _, cfg := range cfgs {
switch cfg.pathMatch {
case matchExact:
if cfg.Path == u.Path {
pathMatched = true
}
case matchPartial:
if strings.Contains(u.Path, cfg.Path) {
pathMatched = true
}
case matchPrefix:
if strings.HasPrefix(u.Path, cfg.Path) {
pathMatched = true
}
case matchSuffix:
if strings.HasSuffix(u.Path, cfg.Path) {
pathMatched = true
}
case matchRegex:
if cfg.pathRegex.MatchString(u.Path) {
pathMatched = true
}
}
if pathMatched {
break
}
}
if !pathMatched {
return false
}

for _, cfg := range cfgs {
switch cfg.domainMatch {
case matchExact:
if cfg.Domain == u.Host {
domainMatched = true
}
case matchPartial:
if strings.Contains(u.Host, cfg.Domain) {
domainMatched = true
}
case matchPrefix:
if strings.HasPrefix(u.Host, cfg.Domain) {
domainMatched = true
}
case matchSuffix:
if strings.HasSuffix(u.Host, cfg.Domain) {
domainMatched = true
}
case matchRegex:
if cfg.domainRegex.MatchString(u.Host) {
domainMatched = true
}
}
if domainMatched {
break
}
}
if !domainMatched {
return false
}

return false
}
88 changes: 88 additions & 0 deletions pkg/redirects/redirect_match.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2024 Paul Greenberg [email protected]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package redirects

import (
"net/url"
"strings"
)

// Match matches HTTP URL to the bypass configuration.
func Match(u *url.URL, cfgs []*RedirectURIMatchConfig) bool {
pathMatched := false
domainMatched := false

for _, cfg := range cfgs {
switch cfg.pathMatch {
case matchExact:
if cfg.Path == u.Path {
pathMatched = true
}
case matchPartial:
if strings.Contains(u.Path, cfg.Path) {
pathMatched = true
}
case matchPrefix:
if strings.HasPrefix(u.Path, cfg.Path) {
pathMatched = true
}
case matchSuffix:
if strings.HasSuffix(u.Path, cfg.Path) {
pathMatched = true
}
case matchRegex:
if cfg.pathRegex.MatchString(u.Path) {
pathMatched = true
}
}
if pathMatched {
break
}
}
if !pathMatched {
return false
}
for _, cfg := range cfgs {
switch cfg.domainMatch {
case matchExact:
if cfg.Domain == u.Host {
domainMatched = true
}
case matchPartial:
if strings.Contains(u.Host, cfg.Domain) {
domainMatched = true
}
case matchPrefix:
if strings.HasPrefix(u.Host, cfg.Domain) {
domainMatched = true
}
case matchSuffix:
if strings.HasSuffix(u.Host, cfg.Domain) {
domainMatched = true
}
case matchRegex:
if cfg.domainRegex.MatchString(u.Host) {
domainMatched = true
}
}
if domainMatched {
break
}
}
if !domainMatched {
return false
}
return true
}
103 changes: 103 additions & 0 deletions pkg/redirects/redirect_match_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2024 Paul Greenberg [email protected]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package redirects

import (
"fmt"

"testing"

"github.com/greenpau/go-authcrunch/internal/tests"
)

func TestMatch(t *testing.T) {

testInput1 := "https://authcrunch.com/?redirect_uri=https://authcrunch.com/path/to/login"

testcases := []struct {
name string
config []string
input string
want map[string]interface{}
shouldErr bool
err error
}{
{
name: "test matched exact domain and exact path match",
config: []string{"exact", "authcrunch.com", "exact", "/path/to/login"},
input: testInput1,
want: map[string]interface{}{
"match": true,
"domain": "authcrunch.com",
"path": "/path/to/login",
},
},
// {
// name: "text exact domain and partial path match",
// config: []string{"exact", "authcrunch.com", "partial", "/to/"},
// input: testInput1,
// want: map[string]interface{}{
// "match": true,
// "domain": "authcrunch.com",
// "path": "/path/to/login",
// },
// },
// {
// name: "text exact domain and prefix path match",
// config: []string{"exact", "authcrunch.com", "prefix", "/path/to"},
// input: testInput1,
// want: map[string]interface{}{
// "match": true,
// "domain": "authcrunch.com",
// "path": "/path/to/login",
// },
// },
/*
{
name: "test invalid config",
shouldErr: true,
err: fmt.Errorf("TBD"),
},
*/
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
got := make(map[string]interface{})
msgs := []string{fmt.Sprintf("test name: %s", tc.name)}
msgs = append(msgs, fmt.Sprintf("input:\n%s", tc.input))

c, err := NewRedirectURIMatchConfig(tc.config[0], tc.config[1], tc.config[2], tc.config[3])
if err != nil {
t.Fatal(err)
}

redirURI := ParseRedirectURI(tc.input)
if redirURI == nil {
t.Fatalf("redirect uri not found in the input: %s", tc.input)
}

got["match"] = Match(redirURI, []*RedirectURIMatchConfig{c})
got["domain"] = redirURI.Host
got["path"] = redirURI.Path

// got, err := Parse(tc.input)
if tests.EvalErrWithLog(t, err, "Match", tc.shouldErr, tc.err, msgs) {
return
}

tests.EvalObjectsWithLog(t, "Output", tc.want, got, msgs)
})
}
}
38 changes: 38 additions & 0 deletions pkg/redirects/redirect_parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2024 Paul Greenberg [email protected]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package redirects

import (
"net/url"
"strings"
)

// ParseRedirectURI parses redirect_uri from URL string.
func ParseRedirectURI(s string) *url.URL {
parsedURL, err := url.Parse(s)
if err != nil {
return nil
}
queryParams := parsedURL.Query()
rawRedirectURI := queryParams.Get("redirect_uri")
if strings.HasPrefix(rawRedirectURI, "/") {
return nil
}
parsedRedirectURI, err := url.Parse(rawRedirectURI)
if err != nil {
return nil
}
return parsedRedirectURI
}
Loading

0 comments on commit 9840d0f

Please sign in to comment.