Chore: Configure SkipOrgRoleSync from OAuthInfo for OAuth connectors (#79443)
* Configure SkipOrgRoleSync from OAuthInfo * Remove skipOrgRoleSync from socialbase and connectors * Add test to socialimpl.ProvideService * Deprecate AuthSettings' fields * clean up misleading init of frontendsettings.Auth
This commit is contained in:
@@ -163,11 +163,8 @@ func (hs *HTTPServer) AdminUpdateUserPermissions(c *contextmodel.ReqContext) res
|
||||
|
||||
getAuthQuery := login.GetAuthInfoQuery{UserId: userID}
|
||||
if authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &getAuthQuery); err == nil && authInfo != nil {
|
||||
oAuthAndAllowAssignGrafanaAdmin := false
|
||||
if oauthInfo := hs.SocialService.GetOAuthInfoProvider(strings.TrimPrefix(authInfo.AuthModule, "oauth_")); oauthInfo != nil {
|
||||
oAuthAndAllowAssignGrafanaAdmin = oauthInfo.AllowAssignGrafanaAdmin
|
||||
}
|
||||
if login.IsGrafanaAdminExternallySynced(hs.Cfg, authInfo.AuthModule, oAuthAndAllowAssignGrafanaAdmin) {
|
||||
oauthInfo := hs.SocialService.GetOAuthInfoProvider(authInfo.AuthModule)
|
||||
if login.IsGrafanaAdminExternallySynced(hs.Cfg, oauthInfo, authInfo.AuthModule) {
|
||||
return response.Error(http.StatusForbidden, "Cannot change Grafana Admin role for externally synced user", nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,9 +318,7 @@ func Test_AdminUpdateUserPermissions(t *testing.T) {
|
||||
|
||||
switch tc.authModule {
|
||||
case login.GenericOAuthModule:
|
||||
socialService.ExpectedAuthInfoProvider = &social.OAuthInfo{AllowAssignGrafanaAdmin: tc.allowAssignGrafanaAdmin, Enabled: tc.authEnabled}
|
||||
cfg.GenericOAuthAuthEnabled = tc.authEnabled
|
||||
cfg.GenericOAuthSkipOrgRoleSync = tc.skipOrgRoleSync
|
||||
socialService.ExpectedAuthInfoProvider = &social.OAuthInfo{AllowAssignGrafanaAdmin: tc.allowAssignGrafanaAdmin, Enabled: tc.authEnabled, SkipOrgRoleSync: tc.skipOrgRoleSync}
|
||||
case login.JWTModule:
|
||||
cfg.JWTAuthEnabled = tc.authEnabled
|
||||
cfg.JWTAuthSkipOrgRoleSync = tc.skipOrgRoleSync
|
||||
|
||||
@@ -6,18 +6,29 @@ import (
|
||||
)
|
||||
|
||||
type FrontendSettingsAuthDTO struct {
|
||||
OAuthSkipOrgRoleUpdateSync bool `json:"OAuthSkipOrgRoleUpdateSync"`
|
||||
SAMLSkipOrgRoleSync bool `json:"SAMLSkipOrgRoleSync"`
|
||||
LDAPSkipOrgRoleSync bool `json:"LDAPSkipOrgRoleSync"`
|
||||
GoogleSkipOrgRoleSync bool `json:"GoogleSkipOrgRoleSync"`
|
||||
AuthProxyEnableLoginToken bool `json:"AuthProxyEnableLoginToken"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
OAuthSkipOrgRoleUpdateSync bool `json:"OAuthSkipOrgRoleUpdateSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
SAMLSkipOrgRoleSync bool `json:"SAMLSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
LDAPSkipOrgRoleSync bool `json:"LDAPSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
GoogleSkipOrgRoleSync bool `json:"GoogleSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
GenericOAuthSkipOrgRoleSync bool `json:"GenericOAuthSkipOrgRoleSync"`
|
||||
JWTAuthSkipOrgRoleSync bool `json:"JWTAuthSkipOrgRoleSync"`
|
||||
GrafanaComSkipOrgRoleSync bool `json:"GrafanaComSkipOrgRoleSync"`
|
||||
AzureADSkipOrgRoleSync bool `json:"AzureADSkipOrgRoleSync"`
|
||||
GithubSkipOrgRoleSync bool `json:"GithubSkipOrgRoleSync"`
|
||||
GitLabSkipOrgRoleSync bool `json:"GitLabSkipOrgRoleSync"`
|
||||
OktaSkipOrgRoleSync bool `json:"OktaSkipOrgRoleSync"`
|
||||
AuthProxyEnableLoginToken bool `json:"AuthProxyEnableLoginToken"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
JWTAuthSkipOrgRoleSync bool `json:"JWTAuthSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
GrafanaComSkipOrgRoleSync bool `json:"GrafanaComSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
AzureADSkipOrgRoleSync bool `json:"AzureADSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
GithubSkipOrgRoleSync bool `json:"GithubSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
GitLabSkipOrgRoleSync bool `json:"GitLabSkipOrgRoleSync"`
|
||||
// Deprecated: this is no longer used and will be removed in Grafana 11
|
||||
OktaSkipOrgRoleSync bool `json:"OktaSkipOrgRoleSync"`
|
||||
}
|
||||
|
||||
type FrontendSettingsBuildInfoDTO struct {
|
||||
|
||||
+25
-15
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
@@ -159,21 +160,6 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
PublicDashboardAccessToken: c.PublicDashboardAccessToken,
|
||||
SharedWithMeFolderUID: folder.SharedWithMeFolderUID,
|
||||
|
||||
Auth: dtos.FrontendSettingsAuthDTO{
|
||||
OAuthSkipOrgRoleUpdateSync: hs.Cfg.OAuthSkipOrgRoleUpdateSync,
|
||||
SAMLSkipOrgRoleSync: hs.Cfg.SAMLSkipOrgRoleSync,
|
||||
LDAPSkipOrgRoleSync: hs.Cfg.LDAPSkipOrgRoleSync,
|
||||
GoogleSkipOrgRoleSync: hs.Cfg.GoogleSkipOrgRoleSync,
|
||||
JWTAuthSkipOrgRoleSync: hs.Cfg.JWTAuthSkipOrgRoleSync,
|
||||
GrafanaComSkipOrgRoleSync: hs.Cfg.GrafanaComSkipOrgRoleSync,
|
||||
GenericOAuthSkipOrgRoleSync: hs.Cfg.GenericOAuthSkipOrgRoleSync,
|
||||
AzureADSkipOrgRoleSync: hs.Cfg.AzureADSkipOrgRoleSync,
|
||||
GithubSkipOrgRoleSync: hs.Cfg.GitHubSkipOrgRoleSync,
|
||||
GitLabSkipOrgRoleSync: hs.Cfg.GitLabSkipOrgRoleSync,
|
||||
OktaSkipOrgRoleSync: hs.Cfg.OktaSkipOrgRoleSync,
|
||||
AuthProxyEnableLoginToken: hs.Cfg.AuthProxyEnableLoginToken,
|
||||
},
|
||||
|
||||
BuildInfo: dtos.FrontendSettingsBuildInfoDTO{
|
||||
HideVersion: hideVersion,
|
||||
Version: version,
|
||||
@@ -261,6 +247,30 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
frontendSettings.AlertingEnabled = *setting.AlertingEnabled
|
||||
}
|
||||
|
||||
// It returns false if the provider is not enabled or the skip org role sync is false.
|
||||
parseSkipOrgRoleSyncEnabled := func(info *social.OAuthInfo) bool {
|
||||
if info == nil {
|
||||
return false
|
||||
}
|
||||
return info.SkipOrgRoleSync
|
||||
}
|
||||
|
||||
oauthProviders := hs.SocialService.GetOAuthInfoProviders()
|
||||
frontendSettings.Auth = dtos.FrontendSettingsAuthDTO{
|
||||
AuthProxyEnableLoginToken: hs.Cfg.AuthProxyEnableLoginToken,
|
||||
OAuthSkipOrgRoleUpdateSync: hs.Cfg.OAuthSkipOrgRoleUpdateSync,
|
||||
SAMLSkipOrgRoleSync: hs.Cfg.SAMLSkipOrgRoleSync,
|
||||
LDAPSkipOrgRoleSync: hs.Cfg.LDAPSkipOrgRoleSync,
|
||||
JWTAuthSkipOrgRoleSync: hs.Cfg.JWTAuthSkipOrgRoleSync,
|
||||
GoogleSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.GoogleProviderName]),
|
||||
GrafanaComSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.GrafanaComProviderName]),
|
||||
GenericOAuthSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.GenericOAuthProviderName]),
|
||||
AzureADSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.AzureADProviderName]),
|
||||
GithubSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.GitHubProviderName]),
|
||||
GitLabSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.GitlabProviderName]),
|
||||
OktaSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.OktaProviderName]),
|
||||
}
|
||||
|
||||
if hs.pluginsCDNService != nil && hs.pluginsCDNService.IsEnabled() {
|
||||
cdnBaseURL, err := hs.pluginsCDNService.BaseURL()
|
||||
if err != nil {
|
||||
|
||||
@@ -334,8 +334,9 @@ func (hs *HTTPServer) searchOrgUsersHelper(c *contextmodel.ReqContext, query *or
|
||||
for i := range filteredUsers {
|
||||
filteredUsers[i].AccessControl = accessControlMetadata[fmt.Sprint(filteredUsers[i].UserID)]
|
||||
if module, ok := modules[filteredUsers[i].UserID]; ok {
|
||||
oauthInfo := hs.SocialService.GetOAuthInfoProvider(module)
|
||||
filteredUsers[i].AuthLabels = []string{login.GetAuthProviderLabel(module)}
|
||||
filteredUsers[i].IsExternallySynced = login.IsExternallySynced(hs.Cfg, module)
|
||||
filteredUsers[i].IsExternallySynced = login.IsExternallySynced(hs.Cfg, module, oauthInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,8 +422,11 @@ func (hs *HTTPServer) updateOrgUserHelper(c *contextmodel.ReqContext, cmd org.Up
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get user auth info", nil)
|
||||
}
|
||||
}
|
||||
if authInfo != nil && authInfo.AuthModule != "" && login.IsExternallySynced(hs.Cfg, authInfo.AuthModule) {
|
||||
return response.Err(org.ErrCannotChangeRoleForExternallySyncedUser.Errorf("Cannot change role for externally synced user"))
|
||||
if authInfo != nil && authInfo.AuthModule != "" {
|
||||
oauthInfo := hs.SocialService.GetOAuthInfoProvider(authInfo.AuthModule)
|
||||
if login.IsExternallySynced(hs.Cfg, authInfo.AuthModule, oauthInfo) {
|
||||
return response.Err(org.ErrCannotChangeRoleForExternallySyncedUser.Errorf("Cannot change role for externally synced user"))
|
||||
}
|
||||
}
|
||||
|
||||
if err := hs.orgService.UpdateOrgUser(c.Req.Context(), &cmd); err != nil {
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/db/dbtest"
|
||||
"github.com/grafana/grafana/pkg/login/social"
|
||||
"github.com/grafana/grafana/pkg/login/social/socialtest"
|
||||
"github.com/grafana/grafana/pkg/models/roletype"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||
@@ -223,14 +225,7 @@ func TestOrgUsersAPIEndpoint_updateOrgRole(t *testing.T) {
|
||||
expectedCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "should not be able to change basicRole with a different provider",
|
||||
SkipOrgRoleSync: false,
|
||||
AuthEnabled: true,
|
||||
AuthModule: login.GenericOAuthModule,
|
||||
expectedCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "should not be able to change basicRole for a user synced through GCom",
|
||||
desc: "should not be able to change basicRole for a user synced through an OAuth provider",
|
||||
SkipOrgRoleSync: false,
|
||||
AuthEnabled: true,
|
||||
AuthModule: login.GrafanaComAuthModule,
|
||||
@@ -263,23 +258,17 @@ func TestOrgUsersAPIEndpoint_updateOrgRole(t *testing.T) {
|
||||
if tt.AuthModule == login.LDAPAuthModule {
|
||||
hs.Cfg.LDAPAuthEnabled = tt.AuthEnabled
|
||||
hs.Cfg.LDAPSkipOrgRoleSync = tt.SkipOrgRoleSync
|
||||
} else if tt.AuthModule == login.GenericOAuthModule {
|
||||
hs.Cfg.GenericOAuthAuthEnabled = tt.AuthEnabled
|
||||
hs.Cfg.GenericOAuthSkipOrgRoleSync = tt.SkipOrgRoleSync
|
||||
} else if tt.AuthModule == login.GrafanaComAuthModule {
|
||||
hs.Cfg.GrafanaNetAuthEnabled = tt.AuthEnabled
|
||||
hs.Cfg.GrafanaComSkipOrgRoleSync = tt.SkipOrgRoleSync
|
||||
} else if tt.AuthModule == "" {
|
||||
// authmodule empty means basic auth
|
||||
} else {
|
||||
t.Errorf("invalid auth module for test: %s", tt.AuthModule)
|
||||
}
|
||||
// AuthModule empty means basic auth
|
||||
|
||||
hs.authInfoService = &authinfotest.FakeService{
|
||||
ExpectedUserAuth: &login.UserAuth{AuthModule: tt.AuthModule},
|
||||
}
|
||||
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions}
|
||||
hs.orgService = &orgtest.FakeOrgService{}
|
||||
hs.SocialService = &socialtest.FakeSocialService{
|
||||
ExpectedAuthInfoProvider: &social.OAuthInfo{Enabled: tt.AuthEnabled, SkipOrgRoleSync: tt.SkipOrgRoleSync},
|
||||
}
|
||||
hs.accesscontrolService = &actest.FakeService{
|
||||
ExpectedPermissions: permissions,
|
||||
}
|
||||
|
||||
+4
-6
@@ -72,12 +72,10 @@ func (hs *HTTPServer) getUserUserProfile(c *contextmodel.ReqContext, userID int6
|
||||
authLabel := login.GetAuthProviderLabel(authInfo.AuthModule)
|
||||
userProfile.AuthLabels = append(userProfile.AuthLabels, authLabel)
|
||||
userProfile.IsExternal = true
|
||||
userProfile.IsExternallySynced = login.IsExternallySynced(hs.Cfg, authInfo.AuthModule)
|
||||
oAuthAndAllowAssignGrafanaAdmin := false
|
||||
if oauthInfo := hs.SocialService.GetOAuthInfoProvider(strings.TrimPrefix(authInfo.AuthModule, "oauth_")); oauthInfo != nil {
|
||||
oAuthAndAllowAssignGrafanaAdmin = oauthInfo.AllowAssignGrafanaAdmin
|
||||
}
|
||||
userProfile.IsGrafanaAdminExternallySynced = login.IsGrafanaAdminExternallySynced(hs.Cfg, authInfo.AuthModule, oAuthAndAllowAssignGrafanaAdmin)
|
||||
|
||||
oauthInfo := hs.SocialService.GetOAuthInfoProvider(authInfo.AuthModule)
|
||||
userProfile.IsExternallySynced = login.IsExternallySynced(hs.Cfg, authInfo.AuthModule, oauthInfo)
|
||||
userProfile.IsGrafanaAdminExternallySynced = login.IsGrafanaAdminExternallySynced(hs.Cfg, oauthInfo, authInfo.AuthModule)
|
||||
}
|
||||
|
||||
userProfile.AccessControl = hs.getAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "global.users:id:", strconv.FormatInt(userID, 10))
|
||||
|
||||
@@ -298,9 +298,7 @@ func Test_GetUserByID(t *testing.T) {
|
||||
|
||||
switch tc.authModule {
|
||||
case login.GenericOAuthModule:
|
||||
socialService.ExpectedAuthInfoProvider = &social.OAuthInfo{AllowAssignGrafanaAdmin: tc.allowAssignGrafanaAdmin, Enabled: tc.authEnabled}
|
||||
cfg.GenericOAuthAuthEnabled = tc.authEnabled
|
||||
cfg.GenericOAuthSkipOrgRoleSync = tc.skipOrgRoleSync
|
||||
socialService.ExpectedAuthInfoProvider = &social.OAuthInfo{AllowAssignGrafanaAdmin: tc.allowAssignGrafanaAdmin, Enabled: tc.authEnabled, SkipOrgRoleSync: tc.skipOrgRoleSync}
|
||||
case login.JWTModule:
|
||||
cfg.JWTAuthEnabled = tc.authEnabled
|
||||
cfg.JWTAuthSkipOrgRoleSync = tc.skipOrgRoleSync
|
||||
|
||||
Reference in New Issue
Block a user