Skip to content

Commit

Permalink
Merge pull request Versent#193 from munkyboy/fix-186
Browse files Browse the repository at this point in the history
account for absolute URLs in login pages
  • Loading branch information
wolfeidau authored Jul 10, 2018
2 parents f4fdebe + 0a1b87a commit 3e1f4f9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 12 deletions.
11 changes: 11 additions & 0 deletions pkg/provider/pingfed/example/loginpage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Example Login Page</title>
</head>
<body>
<form action="/relative/login">
<input type="submit" value="submit"/>
</form>
</body>
</html>
11 changes: 11 additions & 0 deletions pkg/provider/pingfed/example/loginpage_absolute.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Example Login Page</title>
</head>
<body>
<form action="https://other.example.com/login">
<input type="submit" value="submit"/>
</form>
</body>
</html>
37 changes: 25 additions & 12 deletions pkg/provider/pingfed/pingfed.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,21 +283,12 @@ func (ac *Client) getLoginForm(loginDetails *creds.LoginDetails) (string, url.Va
updateLoginFormData(authForm, s, loginDetails)
})

authSubmitURL := ""

doc.Find("form").Each(func(i int, s *goquery.Selection) {
action, ok := s.Attr("action")
if !ok {
return
}
authSubmitURL = action
})

if authSubmitURL == "" {
authSubmitURL, err := extractAuthSubmitURL(loginDetails.URL, doc)
if err != nil {
return "", nil, fmt.Errorf("unable to locate IDP authentication form submit URL")
}

return fmt.Sprintf("%s%s", loginDetails.URL, authSubmitURL), authForm, nil
return authSubmitURL, authForm, nil
}

func updateLoginFormData(authForm url.Values, s *goquery.Selection, user *creds.LoginDetails) {
Expand All @@ -321,6 +312,28 @@ func updateLoginFormData(authForm url.Values, s *goquery.Selection, user *creds.
}
}

func extractAuthSubmitURL(baseURL string, doc *goquery.Document) (authSubmitURL string, err error){
doc.Find("form").Each(func(i int, s *goquery.Selection) {
action, ok := s.Attr("action")
if !ok {
return
}
authSubmitURL = action
})

if authSubmitURL == "" {
err = fmt.Errorf("unable to locate IDP authentication form submit URL")
return
}

// account for relative action URI
if url, urlErr := url.ParseRequestURI(authSubmitURL); urlErr == nil && !url.IsAbs() {
authSubmitURL = fmt.Sprintf("%s%s", baseURL, authSubmitURL)
}

return
}

func extractFormData(res *http.Response) (url.Values, string, error) {
formData := url.Values{}
var actionURL string
Expand Down
22 changes: 22 additions & 0 deletions pkg/provider/pingfed/pingfed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,25 @@ func TestExtractMfaFormData(t *testing.T) {
require.Equal(t, "https://authenticator.pingone.com/pingid/ppm/auth/poll", actionURL)
require.Equal(t, url.Values{"csrfToken": []string{"fc80998c-34d8-4dd2-925c-3b3be8a0dee8"}}, mfaForm)
}

var extractAuthSubmitURLTests = []struct {
f string // input html file
expected string // expected url
}{
{"example/loginpage.html", "https://example.com/relative/login"},
{"example/loginpage_absolute.html", "https://other.example.com/login"},
}

func TestExtractAuthSubmitURL(t *testing.T) {
for _, tt := range extractAuthSubmitURLTests {
data, err := ioutil.ReadFile(tt.f)
require.Nil(t, err)

doc, err := goquery.NewDocumentFromReader(bytes.NewReader(data))
require.Nil(t, err)

url, err := extractAuthSubmitURL("https://example.com", doc)
require.Nil(t, err)
require.Equal(t, tt.expected, url)
}
}

0 comments on commit 3e1f4f9

Please sign in to comment.