Commit e574147b by Leonard Gram Committed by Torkel Ödegaard

Auth: SAML login button. (#17932)

* Auth: SAML login button.

* Fixed ts issue
parent c5b63658
...@@ -30,6 +30,7 @@ export class GrafanaBootConfig { ...@@ -30,6 +30,7 @@ export class GrafanaBootConfig {
authProxyEnabled = false; authProxyEnabled = false;
exploreEnabled = false; exploreEnabled = false;
ldapEnabled = false; ldapEnabled = false;
samlEnabled = false;
oauth: any; oauth: any;
disableUserSignUp = false; disableUserSignUp = false;
loginHint: any; loginHint: any;
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/login" "github.com/grafana/grafana/pkg/login"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
) )
...@@ -21,7 +21,7 @@ const ( ...@@ -21,7 +21,7 @@ const (
LoginErrorCookieName = "login_error" LoginErrorCookieName = "login_error"
) )
func (hs *HTTPServer) LoginView(c *m.ReqContext) { func (hs *HTTPServer) LoginView(c *models.ReqContext) {
viewData, err := hs.setIndexViewData(c) viewData, err := hs.setIndexViewData(c)
if err != nil { if err != nil {
c.Handle(500, "Failed to get settings", err) c.Handle(500, "Failed to get settings", err)
...@@ -38,6 +38,7 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) { ...@@ -38,6 +38,7 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) {
viewData.Settings["loginHint"] = setting.LoginHint viewData.Settings["loginHint"] = setting.LoginHint
viewData.Settings["passwordHint"] = setting.PasswordHint viewData.Settings["passwordHint"] = setting.PasswordHint
viewData.Settings["disableLoginForm"] = setting.DisableLoginForm viewData.Settings["disableLoginForm"] = setting.DisableLoginForm
viewData.Settings["samlEnabled"] = isSamlEnabled()
if loginError, ok := tryGetEncryptedCookie(c, LoginErrorCookieName); ok { if loginError, ok := tryGetEncryptedCookie(c, LoginErrorCookieName); ok {
deleteCookie(c, LoginErrorCookieName) deleteCookie(c, LoginErrorCookieName)
...@@ -62,7 +63,16 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) { ...@@ -62,7 +63,16 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) {
c.Redirect(setting.AppSubUrl + "/") c.Redirect(setting.AppSubUrl + "/")
} }
func tryOAuthAutoLogin(c *m.ReqContext) bool { func isSamlEnabled() bool {
enabledCmd := models.IsSAMLEnabledCommand{}
if err := bus.Dispatch(&enabledCmd); err != nil {
return false
}
return enabledCmd.Result
}
func tryOAuthAutoLogin(c *models.ReqContext) bool {
if !setting.OAuthAutoLogin { if !setting.OAuthAutoLogin {
return false return false
} }
...@@ -80,7 +90,7 @@ func tryOAuthAutoLogin(c *m.ReqContext) bool { ...@@ -80,7 +90,7 @@ func tryOAuthAutoLogin(c *m.ReqContext) bool {
return false return false
} }
func (hs *HTTPServer) LoginAPIPing(c *m.ReqContext) Response { func (hs *HTTPServer) LoginAPIPing(c *models.ReqContext) Response {
if c.IsSignedIn || c.IsAnonymous { if c.IsSignedIn || c.IsAnonymous {
return JSON(200, "Logged in") return JSON(200, "Logged in")
} }
...@@ -88,12 +98,12 @@ func (hs *HTTPServer) LoginAPIPing(c *m.ReqContext) Response { ...@@ -88,12 +98,12 @@ func (hs *HTTPServer) LoginAPIPing(c *m.ReqContext) Response {
return Error(401, "Unauthorized", nil) return Error(401, "Unauthorized", nil)
} }
func (hs *HTTPServer) LoginPost(c *m.ReqContext, cmd dtos.LoginCommand) Response { func (hs *HTTPServer) LoginPost(c *models.ReqContext, cmd dtos.LoginCommand) Response {
if setting.DisableLoginForm { if setting.DisableLoginForm {
return Error(401, "Login is disabled", nil) return Error(401, "Login is disabled", nil)
} }
authQuery := &m.LoginUserQuery{ authQuery := &models.LoginUserQuery{
ReqContext: c, ReqContext: c,
Username: cmd.User, Username: cmd.User,
Password: cmd.Password, Password: cmd.Password,
...@@ -129,7 +139,7 @@ func (hs *HTTPServer) LoginPost(c *m.ReqContext, cmd dtos.LoginCommand) Response ...@@ -129,7 +139,7 @@ func (hs *HTTPServer) LoginPost(c *m.ReqContext, cmd dtos.LoginCommand) Response
return JSON(200, result) return JSON(200, result)
} }
func (hs *HTTPServer) loginUserWithUser(user *m.User, c *m.ReqContext) { func (hs *HTTPServer) loginUserWithUser(user *models.User, c *models.ReqContext) {
if user == nil { if user == nil {
hs.log.Error("user login with nil user") hs.log.Error("user login with nil user")
} }
...@@ -142,8 +152,8 @@ func (hs *HTTPServer) loginUserWithUser(user *m.User, c *m.ReqContext) { ...@@ -142,8 +152,8 @@ func (hs *HTTPServer) loginUserWithUser(user *m.User, c *m.ReqContext) {
middleware.WriteSessionCookie(c, userToken.UnhashedToken, hs.Cfg.LoginMaxLifetimeDays) middleware.WriteSessionCookie(c, userToken.UnhashedToken, hs.Cfg.LoginMaxLifetimeDays)
} }
func (hs *HTTPServer) Logout(c *m.ReqContext) { func (hs *HTTPServer) Logout(c *models.ReqContext) {
if err := hs.AuthTokenService.RevokeToken(c.Req.Context(), c.UserToken); err != nil && err != m.ErrUserTokenNotFound { if err := hs.AuthTokenService.RevokeToken(c.Req.Context(), c.UserToken); err != nil && err != models.ErrUserTokenNotFound {
hs.log.Error("failed to revoke auth token", "error", err) hs.log.Error("failed to revoke auth token", "error", err)
} }
...@@ -157,7 +167,7 @@ func (hs *HTTPServer) Logout(c *m.ReqContext) { ...@@ -157,7 +167,7 @@ func (hs *HTTPServer) Logout(c *m.ReqContext) {
} }
} }
func tryGetEncryptedCookie(ctx *m.ReqContext, cookieName string) (string, bool) { func tryGetEncryptedCookie(ctx *models.ReqContext, cookieName string) (string, bool) {
cookie := ctx.GetCookie(cookieName) cookie := ctx.GetCookie(cookieName)
if cookie == "" { if cookie == "" {
return "", false return "", false
...@@ -172,11 +182,11 @@ func tryGetEncryptedCookie(ctx *m.ReqContext, cookieName string) (string, bool) ...@@ -172,11 +182,11 @@ func tryGetEncryptedCookie(ctx *m.ReqContext, cookieName string) (string, bool)
return string(decryptedError), err == nil return string(decryptedError), err == nil
} }
func deleteCookie(ctx *m.ReqContext, cookieName string) { func deleteCookie(ctx *models.ReqContext, cookieName string) {
ctx.SetCookie(cookieName, "", -1, setting.AppSubUrl+"/") ctx.SetCookie(cookieName, "", -1, setting.AppSubUrl+"/")
} }
func (hs *HTTPServer) trySetEncryptedCookie(ctx *m.ReqContext, cookieName string, value string, maxAge int) error { func (hs *HTTPServer) trySetEncryptedCookie(ctx *models.ReqContext, cookieName string, value string, maxAge int) error {
encryptedError, err := util.Encrypt([]byte(value), setting.SecretKey) encryptedError, err := util.Encrypt([]byte(value), setting.SecretKey)
if err != nil { if err != nil {
return err return err
......
package models
type IsSAMLEnabledCommand struct {
Result bool
}
...@@ -20,6 +20,7 @@ export class LoginCtrl { ...@@ -20,6 +20,7 @@ export class LoginCtrl {
$scope.oauthEnabled = _.keys(config.oauth).length > 0; $scope.oauthEnabled = _.keys(config.oauth).length > 0;
$scope.ldapEnabled = config.ldapEnabled; $scope.ldapEnabled = config.ldapEnabled;
$scope.authProxyEnabled = config.authProxyEnabled; $scope.authProxyEnabled = config.authProxyEnabled;
$scope.samlEnabled = config.samlEnabled;
$scope.disableLoginForm = config.disableLoginForm; $scope.disableLoginForm = config.disableLoginForm;
$scope.disableUserSignUp = config.disableUserSignUp; $scope.disableUserSignUp = config.disableUserSignUp;
......
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<i class="btn-service-icon fa fa-sign-in"></i> <i class="btn-service-icon fa fa-sign-in"></i>
Sign in with {{oauth.generic_oauth.name}} Sign in with {{oauth.generic_oauth.name}}
</a> </a>
<a class="btn btn-medium btn-service btn-service--github login-btn" href="login/saml" target="_self" ng-if="samlEnabled">
<i class="btn-service-icon fa fa-key"></i>
Sign in with SAML
</a>
</div> </div>
<div class="login-signup-box" ng-show="!disableUserSignUp"> <div class="login-signup-box" ng-show="!disableUserSignUp">
<div class="login-signup-title p-r-1"> <div class="login-signup-title p-r-1">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment