From d43b34a5102745098773e81e50054c68ba413a34 Mon Sep 17 00:00:00 2001 From: friedpope Date: Wed, 29 Nov 2023 07:26:16 -0700 Subject: [PATCH] AzureAD Auto-Login Local Override (#107) * 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. * Corrected misuse of spaces in place of tabs * Correct Url to URL per sugesstions by gofmt. * Updated docs with additional info about bypassing OAuth using local logins and the auto-login=true flag. * 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 --- README.md | 9 ++++++++- pkg/kiosk/local_login.go | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 8 deletions(-) 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): diff --git a/pkg/kiosk/local_login.go b/pkg/kiosk/local_login.go index 8400ba2..836f3b8 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(`//img[@alt="User avatar"]`, chromedp.BySearch), + 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