Skip to content

Commit

Permalink
added no_auth type, login targets and logout possibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Pouyan Azari committed Jun 19, 2019
1 parent 87f9554 commit 6a4b2c9
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 22 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Change Log

## [0.0.2] 2019-06-19

- Added target as own parameter different from the url
- Added submit_type parameter which can be used for buttons or forms that can be clicked or submitted
- Some fixes in the application it self
- Allow logout to also be initiated, when the xpath exists
- Allow No Auth, when the page does not have any auth

## [0.0.1] 2019-06-18

- First release
45 changes: 37 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ kind of login forms. The following parameters should be set:
| parameter | help |
|----------------|----------------|
| login_type | simple_form |
| target | The target that is searched for to find the config|
| url | The url that login form is included|
| username | The username that should be used for the login|
| password | The password that should be used for the login|
Expand All @@ -86,6 +87,8 @@ The following parameters are optional:
| parameter | help |
|--------------------|----------------|
| expected_text_xpath| The expected text xpath (must be unique), if not given the whole text is searched for the string|
| submit_type | The type of submission that should be used it can be click or submit, default is submit|
| logout_xpath | The xpath that should be used for the logout button|


### Shibboleth
Expand All @@ -98,6 +101,7 @@ be set for the Shibboleth:
| parameter | help |
|----------------|----------------|
| login_type | shibboleth |
| target | The target that is searched for to find the config|
| url | The url that login form is included|
| username | The username that should be used for the login|
| password | The password that should be used for the login|
Expand All @@ -111,6 +115,7 @@ The following parameters are optional:
| password_xpath | The xpath address of the password field (must be unique) for Shibboleth default value is the `//input[@id='password']`|
| submit_xpath | The xpath address of the submit button (must be unique) for Shibboleth default value is the `//button[@class='aai_login_button']`|
| expected_text_xpath| The expected text xpath (must be unique), if not given the whole text is searched for the string|
| submit_type | The type of submission that should be used it can be click or submit, default is submit|

### Basic Auth

Expand All @@ -121,6 +126,7 @@ following parameters should be set for the application:
|----------------|----------------|
| login_type | basic_auth |
| url | The url that login form is included|
| target | The target that is searched for to find the config|
| username | The username that should be used for the login|
| password | The password that should be used for the login|
| expected_text | The text that is expected to be there|
Expand All @@ -141,6 +147,7 @@ should be set:
|----------------|----------------|
| login_type | password_only |
| url | The url that login form is included|
| target | The target that is searched for to find the config|
| password | The password that should be used for the login|
| password_xpath | The xpath address of the password field (must be unique)|
| expected_text | The text that is expected to be there|
Expand All @@ -150,6 +157,8 @@ The following parameters are optional
| parameter | help |
|--------------------|----------------|
| expected_text_xpath| The expected text xpath (must be unique), if not given the whole text is searched for the string|
| submit_type | The type of submission that should be used it can be click or submit, default is submit|
| logout_xpath | The xpath that should be used for the logout button|

### API

Expand All @@ -162,6 +171,7 @@ parameters should be set:
|----------------|----------------|
| login_type | api |
| url | The url that login form is included|
| target | The target that is searched for to find the config|
| password | This could be key, password or token that should be used|
| password_xpath | This is the parameter that should be used for the token or password|
| expected_text | The text that is expected to be there|
Expand All @@ -174,6 +184,25 @@ The following parameters are optional:
| username_xpath | The parameter that is used for the username|
| method | The method that should be used for the call default is POST|

### No Auth

When the page is only protected by IP address firewall or does not
have any authentication, but still should be checked for a given text
this method can be used.

| parameter | help |
|----------------|----------------|
| login_type | no_auth |
| url | The url that login form is included|
| target | The target that is searched for to find the config|
| expected_text | The text that is expected to be there|

These parameters are optional:

| parameter | help |
|--------------------|----------------|
| expected_text_xpath| The expected text xpath (must be unique), if not given the whole text is searched for the string|

## Configuring Prometheus

This exporter works the same way as
Expand Down Expand Up @@ -209,11 +238,10 @@ In `login_targets.json` the following settings would be enough:
"group": "apps",
"host": "hostname",
"ip": "ip_address",
"job": "login_exporter",
"module": "http_2xx"
"job": "login_exporter"
},
"targets": [
"target_url_which_is_defined_in_login.yml_before"
"target_which_is_defined_in_login.yml_before"
]
}
]
Expand All @@ -222,10 +250,11 @@ In `login_targets.json` the following settings would be enough:
## Development

This application is open-source and can be extended. This repository
is mirror of our home owned repository, so the data here can not be
merged. But pull requests are still welcome. It will extract the data
and add them manually to our internal repo. You still can fork this
repository and add your changes too.
is a mirror of our home owned repository, as a result the pull request
here can not be directly merged. But pull requests are still welcome.
I will extract the patch and add it manually to our internal repo, when
it is acceptable patch. You still can fork this repository and add your
changes too.

### Build

Expand All @@ -238,7 +267,7 @@ go get
go build -o ./login_exporter
```

Or If you want to create a binary for several platforms at once, you can
Or if you want to create a binary for several platforms at once, you can
use the `go_build.sh` script.

## Change Log
Expand Down
86 changes: 75 additions & 11 deletions collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type LoginConfigs struct {
/// that is used to read the yaml files.
type SingleLoginConfig struct {
Url string `yaml:"url"`
Target string `yaml:"target"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Certificate string `yaml:"certificate"`
Expand All @@ -41,6 +42,8 @@ type SingleLoginConfig struct {
SSLCheck bool `yaml:"ssl_check"`
Debug bool `yaml:"debug"`
Method string `yaml:"method"`
SubmitType string `yaml:"submit_type"`
LogoutXpath string `yaml:"logout_xpath"`
}

/// getChromeOptions Returns the options for the chrome driver that is used
Expand Down Expand Up @@ -149,7 +152,7 @@ func getLogger() *log.Logger {

/// loginSimpleForm Logs in the simple for using the username, password and the submit button
func loginSimpleForm(page *agouti.Page, urlText string, usernameXpath string, passwordXpath string, submitXpath string,
username string, password string) {
username string, password string, submitType string) {
err := page.Navigate(urlText)
if err != nil {
logger.WithFields(
Expand Down Expand Up @@ -178,7 +181,11 @@ func loginSimpleForm(page *agouti.Page, urlText string, usernameXpath string, pa
}).Warningln(err.Error())
}
submitField := page.FindByXPath(submitXpath)
err = submitField.Submit()
if submitType == "click" {
err = submitField.Click()
} else {
err = submitField.Submit()
}
if err != nil {
logger.WithFields(
log.Fields{
Expand All @@ -190,7 +197,7 @@ func loginSimpleForm(page *agouti.Page, urlText string, usernameXpath string, pa

/// loginShibboleth Logs in the shibboleth system using the given username and password
func loginShibboleth(page *agouti.Page, urlText string, username string, password string, usernameXpath string,
passwordXpath string, submitXpath string) {
passwordXpath string, submitXpath string, submitType string) {
err := page.Navigate(urlText)
if err != nil {
logger.WithFields(
Expand Down Expand Up @@ -222,8 +229,15 @@ func loginShibboleth(page *agouti.Page, urlText string, username string, passwor
"part": "password_field",
}).Warningln(err.Error())
}
if submitType == "" {
submitType = "click"
}
submitField := page.FindByXPath(submitXpath)
err = submitField.Click()
if submitType == "click" {
err = submitField.Click()
} else {
err = submitField.Submit()
}
if err != nil {
logger.WithFields(
log.Fields{
Expand Down Expand Up @@ -300,8 +314,33 @@ func loginBasicAuth(page *agouti.Page, urlText string, username string, password
}
}

// logOut Logs out of the given page using the xpath that is given for the logout.
func logOut(page *agouti.Page, logoutXpath string, submitType string) {
logoutField := page.FindByXPath(logoutXpath)
if submitType == "click" {
err := logoutField.Click()
if err != nil {
logger.WithFields(
log.Fields{
"subsystem": "logout",
"part": "click",
}).Warningln(err.Error())
}
} else {
err := logoutField.Submit()
if err != nil {
logger.WithFields(
log.Fields{
"subsystem": "logout",
"part": "submit",
}).Warningln(err.Error())
}
}
}

/// loginPasswordOnly Logs in the given website with only password and the xpath to find the field
func loginPasswordOnly(page *agouti.Page, urlText string, passwordXPath string, submitXpath string, password string) {
func loginPasswordOnly(page *agouti.Page, urlText string, passwordXPath string, submitXpath string, password string,
submitType string) {
err := page.Navigate(urlText)
if err != nil {
logger.WithFields(
Expand All @@ -320,7 +359,11 @@ func loginPasswordOnly(page *agouti.Page, urlText string, passwordXPath string,
}).Warningln(err.Error())
}
submitField := page.FindByXPath(submitXpath)
err = submitField.Submit()
if submitType == "click" {
err = submitField.Click()
} else {
err = submitField.Submit()
}
if err != nil {
logger.WithFields(
log.Fields{
Expand All @@ -341,6 +384,7 @@ func checkExpected(page *agouti.Page, expectedXPath string, expectedText string)
"subsystem": "check_expected",
"part": "xpath_data",
}).Warningln(err.Error())
return false
}
return expectedFieldText == expectedText
}
Expand All @@ -351,10 +395,23 @@ func checkExpected(page *agouti.Page, expectedXPath string, expectedText string)
"subsystem": "check_expected",
"part": "match_all_data",
}).Warningln(err.Error())
return false
}
return strings.Contains(content, expectedText)
}

/// getNoLogin The no login function that only returns the page without any submissions
func getNoLogin(page *agouti.Page, urlText string) {
err := page.Navigate(urlText)
if err != nil {
logger.WithFields(
log.Fields{
"subsystem": "driver",
"part": "navigation_error",
}).Warningln(err.Error())
}
}

/// checkExpectedResponse Checks if the expected string exists in the http.Response
func checkExpectedResponse(response *http.Response, expectedText string) bool {
content, err := ioutil.ReadAll(response.Body)
Expand Down Expand Up @@ -383,36 +440,43 @@ func getStatus(config SingleLoginConfig) (status bool, elapsed float64) {
err = page.SetPageLoad(timeout * 1000)
}

// Start counting milliseconds
start := time.Now()
switch config.LoginType {
case "simple_form":
loginSimpleForm(page, config.Url, config.UsernameXpath, config.PasswordXpath, config.SubmitXpath,
config.Username, config.Password)
config.Username, config.Password, config.SubmitType)
status = checkExpected(page, config.ExpectedTextXpath, config.ExpectedText)
break
case "shibboleth":
loginShibboleth(page, config.Url, config.Username, config.Password, config.UsernameXpath,
config.PasswordXpath, config.SubmitXpath)
config.PasswordXpath, config.SubmitXpath, config.SubmitType)
status = checkExpected(page, config.ExpectedTextXpath, config.ExpectedText)
break
case "basic_auth":
loginBasicAuth(page, config.Url, config.Username, config.Password)
status = checkExpected(page, config.ExpectedTextXpath, config.ExpectedText)
break
case "password_only":
loginPasswordOnly(page, config.Url, config.PasswordXpath, config.SubmitXpath, config.Password)
loginPasswordOnly(page, config.Url, config.PasswordXpath, config.SubmitXpath, config.Password, config.SubmitType)
status = checkExpected(page, config.ExpectedTextXpath, config.ExpectedText)
break
case "api":
response := loginApi(config.Url, config.UsernameXpath, config.PasswordXpath, config.Username, config.Password,
config.Method)
status = checkExpectedResponse(response, config.ExpectedText)
break
case "no_auth":
getNoLogin(page, config.Url)
status = checkExpected(page, config.ExpectedTextXpath, config.ExpectedText)
break
}
end := time.Now()
elapsed = end.Sub(start).Seconds()
// Stop counting milliseconds

// logout if the value is set
if config.LogoutXpath != "" {
logOut(page, config.LogoutXpath, config.SubmitType)
}

if err == nil {
err = page.CloseWindow()
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func probeHandler(w http.ResponseWriter, r *http.Request, configs LoginConfigs)
/// findTargetInConfig Finds the given target in login configs
func findTargetInConfig(configs LoginConfigs, target string) (SingleLoginConfig, error) {
for _, config := range configs.Configs {
if config.Url == target {
if config.Target == target {
return config, nil
}
}
Expand Down
7 changes: 5 additions & 2 deletions misc/login.yml.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
targets:
- url: ""
- url: "the-url-that-should-be-called"
target: "the-target-that-is-used-to-find-conf"
username: ""
password: ""
certificate: ""
Expand All @@ -11,4 +12,6 @@ targets:
expected_text: ""
ssl_check: no
debug: no
method: "POST"
method: "POST"
submit_type: "click"
logout_xpath: ""

0 comments on commit 6a4b2c9

Please sign in to comment.