From 914e0bf87e21579e804cdd9eb03ad9fe5f1fcf63 Mon Sep 17 00:00:00 2001 From: Jo Date: Mon, 17 Jul 2023 16:35:59 +0200 Subject: [PATCH] Auth: Surface organization membership error (#71750) surface organization membership error --- pkg/api/login.go | 18 +++++++++++++++++- pkg/login/social/github_oauth.go | 17 +++++++++++++---- pkg/login/social/grafana_com_oauth.go | 4 +++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/pkg/api/login.go b/pkg/api/login.go index 61726000d78..be79011fa27 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -427,10 +427,26 @@ func getLoginExternalError(err error) string { return createTokenErr.ExternalErr } + // unwrap until we get to the error message gfErr := &errutil.Error{} if errors.As(err, gfErr) { - return gfErr.Public().Message + return getFirstPublicErrorMessage(gfErr) } return err.Error() } + +// Get the first public error message from an error chain. +func getFirstPublicErrorMessage(err *errutil.Error) string { + errPublic := err.Public() + if err.PublicMessage != "" { + return errPublic.Message + } + + underlyingErr := &errutil.Error{} + if err.Underlying != nil && errors.As(err.Underlying, underlyingErr) { + return getFirstPublicErrorMessage(underlyingErr) + } + + return errPublic.Message +} diff --git a/pkg/login/social/github_oauth.go b/pkg/login/social/github_oauth.go index 85a1c996e08..50be3a7b2a4 100644 --- a/pkg/login/social/github_oauth.go +++ b/pkg/login/social/github_oauth.go @@ -12,6 +12,7 @@ import ( "golang.org/x/oauth2" "github.com/grafana/grafana/pkg/models/roletype" + "github.com/grafana/grafana/pkg/util/errutil" ) type SocialGithub struct { @@ -32,8 +33,14 @@ type GithubTeam struct { } var ( - ErrMissingTeamMembership = Error{"user not a member of one of the required teams"} - ErrMissingOrganizationMembership = Error{"user not a member of one of the required organizations"} + ErrMissingTeamMembership = errutil.NewBase(errutil.StatusUnauthorized, + "auth.missing_team", + errutil.WithPublicMessage( + "User is not a member of one of the required teams. Please contact identity provider administrator.")) + ErrMissingOrganizationMembership = errutil.NewBase(errutil.StatusUnauthorized, + "auth.missing_organization", + errutil.WithPublicMessage( + "User is not a member of one of the required organizations. Please contact identity provider administrator.")) ) func (s *SocialGithub) IsTeamMember(ctx context.Context, client *http.Client) bool { @@ -243,11 +250,13 @@ func (s *SocialGithub) UserInfo(ctx context.Context, client *http.Client, token organizationsUrl := fmt.Sprintf(s.apiUrl + "/orgs?per_page=100") if !s.IsTeamMember(ctx, client) { - return nil, ErrMissingTeamMembership + return nil, ErrMissingTeamMembership.Errorf("User is not a member of any of the allowed teams: %v", s.teamIds) } if !s.IsOrganizationMember(ctx, client, organizationsUrl) { - return nil, ErrMissingOrganizationMembership + return nil, ErrMissingOrganizationMembership.Errorf( + "User is not a member of any of the allowed organizations: %v", + s.allowedOrganizations) } if userInfo.Email == "" { diff --git a/pkg/login/social/grafana_com_oauth.go b/pkg/login/social/grafana_com_oauth.go index 77272b1aa3c..a4899b4e745 100644 --- a/pkg/login/social/grafana_com_oauth.go +++ b/pkg/login/social/grafana_com_oauth.go @@ -79,7 +79,9 @@ func (s *SocialGrafanaCom) UserInfo(ctx context.Context, client *http.Client, _ } if !s.IsOrganizationMember(data.Orgs) { - return nil, ErrMissingOrganizationMembership + return nil, ErrMissingOrganizationMembership.Errorf( + "User is not a member of any of the allowed organizations: %v. Returned Organizations: %v", + s.allowedOrganizations, data.Orgs) } return userInfo, nil