diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 0805a54bed1..ce97d109cb3 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -94,7 +94,6 @@ Experimental features might be changed or removed without prior notice. | `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files | | `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries | | `individualCookiePreferences` | Support overriding cookie preferences per user | -| `onlyExternalOrgRoleSync` | Prohibits a user from changing organization roles synced with external auth providers | | `timeSeriesTable` | Enable time series table transformer & sparkline cell type | | `prometheusResourceBrowserCache` | Displays browser caching options in Prometheus data source configuration | | `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index ab72bff0693..fa6c5881053 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -64,7 +64,6 @@ export interface FeatureToggles { lokiQuerySplitting?: boolean; lokiQuerySplittingConfig?: boolean; individualCookiePreferences?: boolean; - onlyExternalOrgRoleSync?: boolean; prometheusMetricEncyclopedia?: boolean; timeSeriesTable?: boolean; prometheusResourceBrowserCache?: boolean; diff --git a/pkg/api/org_users.go b/pkg/api/org_users.go index a91bb866749..8baa033225f 100644 --- a/pkg/api/org_users.go +++ b/pkg/api/org_users.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/services/accesscontrol" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" - "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/login" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" @@ -389,22 +388,22 @@ func (hs *HTTPServer) updateOrgUserHelper(c *contextmodel.ReqContext, cmd org.Up if !c.OrgRole.Includes(cmd.Role) && !c.IsGrafanaAdmin { return response.Error(http.StatusForbidden, "Cannot assign a role higher than user's role", nil) } - if hs.Features.IsEnabled(featuremgmt.FlagOnlyExternalOrgRoleSync) { - // we do not allow to change role for external synced users - qAuth := login.GetAuthInfoQuery{UserId: cmd.UserID} - authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &qAuth) - if err != nil { - if errors.Is(err, user.ErrUserNotFound) { - hs.log.Debug("Failed to get user auth info for basic auth user", cmd.UserID, nil) - } else { - hs.log.Error("Failed to get user auth info for external sync check", cmd.UserID, err) - 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")) + + // we do not allow to change role for external synced users + qAuth := login.GetAuthInfoQuery{UserId: cmd.UserID} + authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &qAuth) + if err != nil { + if errors.Is(err, user.ErrUserNotFound) { + hs.log.Debug("Failed to get user auth info for basic auth user", cmd.UserID, nil) + } else { + hs.log.Error("Failed to get user auth info for external sync check", cmd.UserID, err) + 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 err := hs.orgService.UpdateOrgUser(c.Req.Context(), &cmd); err != nil { if errors.Is(err, org.ErrLastOrgAdmin) { return response.Error(http.StatusBadRequest, "Cannot change role so that there is no organization admin left", nil) diff --git a/pkg/api/org_users_test.go b/pkg/api/org_users_test.go index 26f44466428..2d368ecc72b 100644 --- a/pkg/api/org_users_test.go +++ b/pkg/api/org_users_test.go @@ -275,7 +275,6 @@ func TestOrgUsersAPIEndpoint_updateOrgRole(t *testing.T) { hs.authInfoService = &logintest.AuthInfoServiceFake{ ExpectedUserAuth: &login.UserAuth{AuthModule: tt.AuthModule}, } - hs.Features = featuremgmt.WithFeatures(featuremgmt.FlagOnlyExternalOrgRoleSync, true) hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions} hs.orgService = &orgtest.FakeOrgService{} hs.accesscontrolService = &actest.FakeService{ diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index e526cb1cef7..ae783286245 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -316,12 +316,6 @@ var ( Stage: FeatureStageExperimental, Owner: grafanaBackendPlatformSquad, }, - { - Name: "onlyExternalOrgRoleSync", - Description: "Prohibits a user from changing organization roles synced with external auth providers", - Stage: FeatureStageExperimental, - Owner: grafanaAuthnzSquad, - }, { Name: "prometheusMetricEncyclopedia", Description: "Adds the metrics explorer component to the Prometheus query builder as an option in metric select", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index cd2b2c2dd0a..115ae2fa0db 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -45,7 +45,6 @@ logsContextDatasourceUi,GA,@grafana/observability-logs,false,false,false,true lokiQuerySplitting,GA,@grafana/observability-logs,false,false,false,true lokiQuerySplittingConfig,experimental,@grafana/observability-logs,false,false,false,true individualCookiePreferences,experimental,@grafana/backend-platform,false,false,false,false -onlyExternalOrgRoleSync,experimental,@grafana/grafana-authnz-team,false,false,false,false prometheusMetricEncyclopedia,GA,@grafana/observability-metrics,false,false,false,true timeSeriesTable,experimental,@grafana/app-o11y,false,false,false,true prometheusResourceBrowserCache,experimental,@grafana/observability-metrics,false,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 0182d314060..9a4d4f556e2 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -191,10 +191,6 @@ const ( // Support overriding cookie preferences per user FlagIndividualCookiePreferences = "individualCookiePreferences" - // FlagOnlyExternalOrgRoleSync - // Prohibits a user from changing organization roles synced with external auth providers - FlagOnlyExternalOrgRoleSync = "onlyExternalOrgRoleSync" - // FlagPrometheusMetricEncyclopedia // Adds the metrics explorer component to the Prometheus query builder as an option in metric select FlagPrometheusMetricEncyclopedia = "prometheusMetricEncyclopedia" diff --git a/public/app/features/users/UsersTable.tsx b/public/app/features/users/UsersTable.tsx index de46b1989b3..7c37a653da0 100644 --- a/public/app/features/users/UsersTable.tsx +++ b/public/app/features/users/UsersTable.tsx @@ -5,7 +5,6 @@ import { Button, ConfirmModal } from '@grafana/ui'; import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker'; import { fetchRoleOptions } from 'app/core/components/RolePicker/api'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; -import config from 'app/core/config'; import { contextSrv } from 'app/core/core'; import { AccessControlAction, OrgUser, Role } from 'app/types'; @@ -57,10 +56,8 @@ export const UsersTable = ({ users, orgId, onRoleChange, onRemoveUser }: Props)
{users.map((user, index) => { let basicRoleDisabled = !contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersWrite, user); - if (config.featureToggles.onlyExternalOrgRoleSync) { - const isUserSynced = user?.isExternallySynced; - basicRoleDisabled = isUserSynced || basicRoleDisabled; - } + const isUserSynced = user?.isExternallySynced; + basicRoleDisabled = isUserSynced || basicRoleDisabled; return (