Skip to content

Commit 7574f61

Browse files
author
SESA826635
committed
feat: add account lockout and login failure detection for PingFederate provider
1 parent 65195ee commit 7574f61

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

pkg/provider/pingfed/pingfed.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"log"
99
"net/http"
1010
"net/url"
11+
"strings"
1112
"time"
1213

1314
"github.com/PuerkitoBio/goquery"
@@ -74,6 +75,15 @@ func (ac *Client) follow(ctx context.Context, req *http.Request) (string, error)
7475
return "", errors.Wrap(err, "failed to build document from response")
7576
}
7677

78+
// Check for authentication errors first
79+
if msg, ok := docIsLoginFail(doc); ok {
80+
logger.WithField("type", "authentication-error").Debug("doc detect")
81+
return "", fmt.Errorf(msg)
82+
} else if msg, ok := docIsAccountLocked(doc); ok {
83+
logger.WithField("type", "account-locked").Debug("doc detect")
84+
return "", fmt.Errorf(msg)
85+
}
86+
7787
var handler func(context.Context, *goquery.Document, *url.URL) (context.Context, *http.Request, error)
7888

7989
if docIsFormRedirectToTarget(doc, ac.idpAccount.TargetURL) {
@@ -358,6 +368,27 @@ func extractSAMLResponse(doc *goquery.Document) (v string, ok bool) {
358368
return doc.Find("input[name=\"SAMLResponse\"]").Attr("value")
359369
}
360370

371+
// docIsLoginFail checks for login authentication failures
372+
func docIsLoginFail(doc *goquery.Document) (v string, ok bool) {
373+
isLoginFail := doc.Find(".ping-error").Size() >= 1
374+
if isLoginFail {
375+
errorText := doc.Find(".ping-error").Text()
376+
return strings.Join(strings.Fields(errorText), " "), true
377+
}
378+
return "", false
379+
380+
}
381+
382+
// docIsAccountLocked checks if user account is locked or blocked
383+
func docIsAccountLocked(doc *goquery.Document) (v string, ok bool) {
384+
isAccountLocked := doc.Find(".window.settings.blocked").Size() > 0
385+
if isAccountLocked {
386+
errorText := strings.TrimSpace(doc.Find(".window.settings.blocked .error-text .text").Text())
387+
return strings.Join(strings.Fields(errorText), " "), true
388+
}
389+
return "", false
390+
}
391+
361392
// ensures given url is an absolute URL. if not, it will be combined with the base URL
362393
func makeAbsoluteURL(v string, base string) string {
363394
if u, err := url.ParseRequestURI(v); err == nil && !u.IsAbs() {

0 commit comments

Comments
 (0)