From 814730abed7ef9cebba1b1d095e1c55bf0423162 Mon Sep 17 00:00:00 2001 From: Sean Hillmeyer Date: Tue, 18 Apr 2023 17:15:45 -0700 Subject: [PATCH 1/5] Added if statement to the local login method to allow it to bypass the Azure AD auto-login configuration using the /login/local url before navigating to the original url. --- pkg/kiosk/local_login.go | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/pkg/kiosk/local_login.go b/pkg/kiosk/local_login.go index 8400ba2..e677d2c 100644 --- a/pkg/kiosk/local_login.go +++ b/pkg/kiosk/local_login.go @@ -5,6 +5,7 @@ import ( "log" "os" "time" + "strings" "github.com/chromedp/chromedp" "github.com/chromedp/chromedp/kb" @@ -48,14 +49,36 @@ func GrafanaKioskLocal(cfg *Config, messages chan string) { // Give browser time to load next page (this can be prone to failure, explore different options vs sleeping) time.Sleep(2000 * time.Millisecond) - if err := chromedp.Run(taskCtx, - chromedp.Navigate(generatedURL), - chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), - ); err != nil { - panic(err) + if cfg.GOAUTH.AutoLogin { + // if AutoLogin is set, get the base URL and append the local login bypass before navigating to the full url + startIndex := strings.Index(cfg.Target.URL, "://") + 3 + endIndex := strings.Index(cfg.Target.URL[startIndex:], "/") + startIndex + baseUrl := cfg.Target.URL[:endIndex] + bypassUrl := baseUrl + "/login/local" + + log.Println("Bypassing Azure AD autoLogin at ", bypassUrl) + + if err := chromedp.Run(taskCtx, + chromedp.Navigate(bypassUrl), + chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), + chromedp.WaitVisible(`navbar-menu-portal-container`, chromedp.ByID), + chromedp.Navigate(generatedURL), + ); err != nil { + panic(err) + } + } else { + if err := chromedp.Run(taskCtx, + chromedp.Navigate(generatedURL), + chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), + ); err != nil { + panic(err) + } } + // blocking wait for { messageFromChrome := <-messages From 38aa59c8ddba0dc8c17c69161d39affdba105790 Mon Sep 17 00:00:00 2001 From: Sean Hillmeyer Date: Tue, 18 Apr 2023 17:30:33 -0700 Subject: [PATCH 2/5] Corrected misuse of spaces in place of tabs --- pkg/kiosk/local_login.go | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pkg/kiosk/local_login.go b/pkg/kiosk/local_login.go index e677d2c..e21534a 100644 --- a/pkg/kiosk/local_login.go +++ b/pkg/kiosk/local_login.go @@ -5,7 +5,7 @@ import ( "log" "os" "time" - "strings" + "strings" "github.com/chromedp/chromedp" "github.com/chromedp/chromedp/kb" @@ -49,34 +49,34 @@ func GrafanaKioskLocal(cfg *Config, messages chan string) { // Give browser time to load next page (this can be prone to failure, explore different options vs sleeping) time.Sleep(2000 * time.Millisecond) - if cfg.GOAUTH.AutoLogin { - // if AutoLogin is set, get the base URL and append the local login bypass before navigating to the full url - startIndex := strings.Index(cfg.Target.URL, "://") + 3 - endIndex := strings.Index(cfg.Target.URL[startIndex:], "/") + startIndex - baseUrl := cfg.Target.URL[:endIndex] - bypassUrl := baseUrl + "/login/local" - - log.Println("Bypassing Azure AD autoLogin at ", bypassUrl) - + if cfg.GOAUTH.AutoLogin { + // if AutoLogin is set, get the base URL and append the local login bypass before navigating to the full url + startIndex := strings.Index(cfg.Target.URL, "://") + 3 + endIndex := strings.Index(cfg.Target.URL[startIndex:], "/") + startIndex + baseUrl := cfg.Target.URL[:endIndex] + bypassUrl := baseUrl + "/login/local" + + log.Println("Bypassing Azure AD autoLogin at ", bypassUrl) + if err := chromedp.Run(taskCtx, chromedp.Navigate(bypassUrl), - chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), - chromedp.WaitVisible(`navbar-menu-portal-container`, chromedp.ByID), - chromedp.Navigate(generatedURL), + chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), + chromedp.WaitVisible(`navbar-menu-portal-container`, chromedp.ByID), + chromedp.Navigate(generatedURL), ); err != nil { panic(err) } } else { - if err := chromedp.Run(taskCtx, - chromedp.Navigate(generatedURL), - chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), - chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), - ); err != nil { - panic(err) - } + if err := chromedp.Run(taskCtx, + chromedp.Navigate(generatedURL), + chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), + chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), + ); err != nil { + panic(err) + } } // blocking wait From b894fa3fbd6395cb9ad379aada2b1a6be9efa07a Mon Sep 17 00:00:00 2001 From: Sean Hillmeyer Date: Tue, 18 Apr 2023 17:44:53 -0700 Subject: [PATCH 3/5] Correct Url to URL per sugesstions by gofmt. --- pkg/kiosk/local_login.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/kiosk/local_login.go b/pkg/kiosk/local_login.go index e21534a..0b4fadb 100644 --- a/pkg/kiosk/local_login.go +++ b/pkg/kiosk/local_login.go @@ -53,13 +53,13 @@ func GrafanaKioskLocal(cfg *Config, messages chan string) { // if AutoLogin is set, get the base URL and append the local login bypass before navigating to the full url startIndex := strings.Index(cfg.Target.URL, "://") + 3 endIndex := strings.Index(cfg.Target.URL[startIndex:], "/") + startIndex - baseUrl := cfg.Target.URL[:endIndex] - bypassUrl := baseUrl + "/login/local" + baseURL := cfg.Target.URL[:endIndex] + bypassURL := baseURL + "/login/local" - log.Println("Bypassing Azure AD autoLogin at ", bypassUrl) + log.Println("Bypassing Azure AD autoLogin at ", bypassURL) if err := chromedp.Run(taskCtx, - chromedp.Navigate(bypassUrl), + chromedp.Navigate(bypassURL), chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), From 5e6b557961056ab9815aa457fc5bdb73ef83bb5c Mon Sep 17 00:00:00 2001 From: Sean Hillmeyer Date: Thu, 11 May 2023 13:38:45 -0700 Subject: [PATCH 4/5] Updated docs with additional info about bypassing OAuth using local logins and the auto-login=true flag. --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b47bbb..e61f92e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This provides a utility to quickly standup a kiosk on devices like a Raspberry P The utitilty provides these options: - Login - - to a Grafana server (local account) + - to a Grafana server (local account or bypass OAuth) - to a Grafana server with anonymous-mode enabled (same method used on [play.grafana.org](https://play.grafana.org)) - to a Grafana Cloud instance - to a Grafana server with OAuth enabled @@ -74,6 +74,7 @@ NOTE: Flags with parameters should use an "equals" idtoken audience -auto-login oauth_auto_login is enabled in grafana config + (set this flag along with the "local" login-method to bypass OAuth via the /login/local url and use a local grafana user/pass before continuing to the target URL) -autofit Fit panels to screen (default true) -c string @@ -213,6 +214,12 @@ If you are using a self-signed certificate, you can remove the certificate error ./bin/grafana-kiosk -URL=https://localhost:3000 -login-method=local -username=admin -password=admin -kiosk-mode=tv -ignore-certificate-errors ``` +This will login to a grafana server, configured for AzureAD OAuth and has Oauth_auto_login is enabled, bypassing OAuth and using a manually setup local username and password. + +```bash +./bin/grafana-kiosk -URL=https://localhost:3000 -login-method=local -username=admin -password=admin -auto-login=true -kiosk-mode=tv +``` + ### Grafana Server with Anonymous access enabled This will take the browser to the default dashboard on play.grafana.org in fullscreen kiosk mode (no login needed): From 9b2508e06d670cb38670b6d155dd2c3f3ff966ce Mon Sep 17 00:00:00 2001 From: Sean Hillmeyer Date: Thu, 20 Jul 2023 14:43:31 -0700 Subject: [PATCH 5/5] Updated the element we're waiting to see after a successful bypassed login to use the 'User avatar' instead of the nav bar since that's changed in the new Grafana update --- pkg/kiosk/local_login.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kiosk/local_login.go b/pkg/kiosk/local_login.go index 0b4fadb..836f3b8 100644 --- a/pkg/kiosk/local_login.go +++ b/pkg/kiosk/local_login.go @@ -63,7 +63,7 @@ func GrafanaKioskLocal(cfg *Config, messages chan string) { chromedp.WaitVisible(`//input[@name="user"]`, chromedp.BySearch), chromedp.SendKeys(`//input[@name="user"]`, cfg.Target.Username, chromedp.BySearch), chromedp.SendKeys(`//input[@name="password"]`, cfg.Target.Password+kb.Enter, chromedp.BySearch), - chromedp.WaitVisible(`navbar-menu-portal-container`, chromedp.ByID), + chromedp.WaitVisible(`//img[@alt="User avatar"]`, chromedp.BySearch), chromedp.Navigate(generatedURL), ); err != nil { panic(err)