mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AuthN: Login error handling (#64239)
* Social: Fix type so it appears in error responses * AuthN: construct errutil.Error from social.Error * login: Check for errutil.Error and use public message * Login: redirectURLWithErrorCookie for authn errors Co-authored-by: Jo <joao.guerreiro@grafana.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -42,11 +43,16 @@ var (
|
||||
errOAuthInvalidState = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.state.invalid", errutil.WithPublicMessage("Provided state does not match stored state"))
|
||||
|
||||
errOAuthTokenExchange = errutil.NewBase(errutil.StatusInternal, "auth.oauth.token.exchange", errutil.WithPublicMessage("Failed to get token from provider"))
|
||||
errOAuthUserInfo = errutil.NewBase(errutil.StatusInternal, "auth.oauth.userinfo.error")
|
||||
|
||||
errOAuthMissingRequiredEmail = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.missing")
|
||||
errOAuthEmailNotAllowed = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.not-allowed")
|
||||
errOAuthMissingRequiredEmail = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.missing", errutil.WithPublicMessage("Provider didn't return an email address"))
|
||||
errOAuthEmailNotAllowed = errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.email.not-allowed", errutil.WithPublicMessage("Required email domain not fulfilled"))
|
||||
)
|
||||
|
||||
func fromSocialErr(err *social.Error) error {
|
||||
return errutil.NewBase(errutil.StatusUnauthorized, "auth.oauth.userinfo.failed", errutil.WithPublicMessage(err.Error())).Errorf("%w", err)
|
||||
}
|
||||
|
||||
var _ authn.RedirectClient = new(OAuth)
|
||||
|
||||
func ProvideOAuth(
|
||||
@@ -106,13 +112,17 @@ func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Iden
|
||||
// exchange auth code to a valid token
|
||||
token, err := c.connector.Exchange(clientCtx, r.HTTPRequest.URL.Query().Get("code"), opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errOAuthTokenExchange.Errorf("failed to exchange code to token: %w", err)
|
||||
}
|
||||
token.TokenType = "Bearer"
|
||||
|
||||
userInfo, err := c.connector.UserInfo(c.connector.Client(clientCtx, token), token)
|
||||
if err != nil {
|
||||
return nil, errOAuthTokenExchange.Errorf("failed to exchange code to token: %w", err)
|
||||
var sErr *social.Error
|
||||
if errors.As(err, &sErr) {
|
||||
return nil, fromSocialErr(sErr)
|
||||
}
|
||||
return nil, errOAuthUserInfo.Errorf("failed to get user info: %w", err)
|
||||
}
|
||||
|
||||
if userInfo.Email == "" {
|
||||
|
||||
Reference in New Issue
Block a user