diff --git a/pkg/api/login.go b/pkg/api/login.go index 4ab51b22d5c..559d34ca801 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -353,7 +353,7 @@ func (hs *HTTPServer) trySetEncryptedCookie(ctx *models.ReqContext, cookieName s } func (hs *HTTPServer) redirectWithError(ctx *models.ReqContext, err error, v ...interface{}) { - ctx.Logger.Error(err.Error(), v...) + ctx.Logger.Warn(err.Error(), v...) if err := hs.trySetEncryptedCookie(ctx, loginErrorCookieName, getLoginExternalError(err), 60); err != nil { hs.log.Error("Failed to set encrypted cookie", "err", err) } diff --git a/pkg/login/social/azuread_oauth.go b/pkg/login/social/azuread_oauth.go index 7b35caf2755..81682ffa702 100644 --- a/pkg/login/social/azuread_oauth.go +++ b/pkg/login/social/azuread_oauth.go @@ -72,7 +72,7 @@ func (s *SocialAzureAD) UserInfo(client *http.Client, token *oauth2.Token) (*Bas role, grafanaAdmin := s.extractRoleAndAdmin(&claims) if s.roleAttributeStrict && !role.IsValid() { - return nil, ErrInvalidBasicRole + return nil, &InvalidBasicRoleError{idP: "Azure", assignedRole: string(role)} } logger.Debug("AzureAD OAuth: extracted role", "email", email, "role", role) diff --git a/pkg/login/social/errors.go b/pkg/login/social/errors.go index 2624050a717..c0a71bb01e7 100644 --- a/pkg/login/social/errors.go +++ b/pkg/login/social/errors.go @@ -1,9 +1,30 @@ package social -import "errors" +import ( + "errors" + "fmt" +) var ( - ErrIDTokenNotFound = errors.New("id_token not found") - ErrInvalidBasicRole = errors.New("user does not have a valid basic role") - ErrEmailNotFound = errors.New("error getting user info: no email found in access token") + ErrIDTokenNotFound = errors.New("id_token not found") + ErrEmailNotFound = errors.New("error getting user info: no email found in access token") ) + +type InvalidBasicRoleError struct { + idP string + assignedRole string +} + +func (e *InvalidBasicRoleError) Error() string { + withFallback := func(v, fallback string) string { + if v == "" { + return fallback + } + return v + } + return fmt.Sprintf("Integration requires a valid org role assigned in %s. Assigned role: %s", withFallback(e.idP, "idP"), withFallback(e.assignedRole, "\" \"")) +} + +func (e *InvalidBasicRoleError) Unwrap() error { + return &Error{e.Error()} +} diff --git a/pkg/login/social/generic_oauth.go b/pkg/login/social/generic_oauth.go index 3ebc43b738f..dd7b8376a69 100644 --- a/pkg/login/social/generic_oauth.go +++ b/pkg/login/social/generic_oauth.go @@ -169,7 +169,7 @@ func (s *SocialGenericOAuth) UserInfo(client *http.Client, token *oauth2.Token) } if s.roleAttributeStrict && !userInfo.Role.IsValid() { - return nil, ErrInvalidBasicRole + return nil, &InvalidBasicRoleError{assignedRole: string(userInfo.Role)} } if userInfo.Email == "" { diff --git a/pkg/login/social/github_oauth.go b/pkg/login/social/github_oauth.go index c36c95b1ea8..1636a5918ff 100644 --- a/pkg/login/social/github_oauth.go +++ b/pkg/login/social/github_oauth.go @@ -203,7 +203,7 @@ func (s *SocialGithub) UserInfo(client *http.Client, token *oauth2.Token) (*Basi role, grafanaAdmin := s.extractRoleAndAdmin(response.Body, teams, true) if s.roleAttributeStrict && !role.IsValid() { - return nil, ErrInvalidBasicRole + return nil, &InvalidBasicRoleError{idP: "Github", assignedRole: string(role)} } var isGrafanaAdmin *bool = nil diff --git a/pkg/login/social/gitlab_oauth.go b/pkg/login/social/gitlab_oauth.go index a9b7eb5d862..abb12ed46a0 100644 --- a/pkg/login/social/gitlab_oauth.go +++ b/pkg/login/social/gitlab_oauth.go @@ -115,7 +115,7 @@ func (s *SocialGitlab) UserInfo(client *http.Client, _ *oauth2.Token) (*BasicUse role, grafanaAdmin := s.extractRoleAndAdmin(response.Body, groups, true) if s.roleAttributeStrict && !role.IsValid() { - return nil, ErrInvalidBasicRole + return nil, &InvalidBasicRoleError{idP: "Gitlab", assignedRole: string(role)} } var isGrafanaAdmin *bool = nil diff --git a/pkg/login/social/gitlab_oauth_test.go b/pkg/login/social/gitlab_oauth_test.go index 989523f480d..e95b4ed326e 100644 --- a/pkg/login/social/gitlab_oauth_test.go +++ b/pkg/login/social/gitlab_oauth_test.go @@ -99,7 +99,7 @@ func TestSocialGitlab_UserInfo(t *testing.T) { UserRespBody: editorUserRespBody, GroupsRespBody: "[" + strings.Join([]string{}, ",") + "]", RoleAttributePath: gitlabAttrPath, - ExpectedError: ErrInvalidBasicRole, + ExpectedError: &InvalidBasicRoleError{idP: "Gitlab"}, }, { // Edge case, no match, no strict mode and no fallback => User has an empty role Name: "Fallback with no default will create a user with an empty role", @@ -117,7 +117,7 @@ func TestSocialGitlab_UserInfo(t *testing.T) { UserRespBody: editorUserRespBody, GroupsRespBody: "[" + strings.Join([]string{editorGroup}, ",") + "]", RoleAttributePath: "", - ExpectedError: ErrInvalidBasicRole, + ExpectedError: &InvalidBasicRoleError{idP: "Gitlab"}, }, } diff --git a/pkg/login/social/okta_oauth.go b/pkg/login/social/okta_oauth.go index f70c7c8d0db..a7863518915 100644 --- a/pkg/login/social/okta_oauth.go +++ b/pkg/login/social/okta_oauth.go @@ -82,7 +82,7 @@ func (s *SocialOkta) UserInfo(client *http.Client, token *oauth2.Token) (*BasicU role, grafanaAdmin := s.extractRoleAndAdmin(data.rawJSON, groups, true) if s.roleAttributeStrict && !role.IsValid() { - return nil, ErrInvalidBasicRole + return nil, &InvalidBasicRoleError{idP: "Okta", assignedRole: string(role)} } var isGrafanaAdmin *bool = nil