Replace signed in user for identity.requester (#73750)
* Make identity.Requester available at Context * Clean pkg/services/guardian/guardian.go * Clean guardian provider and guardian AC * Clean pkg/api/team.go * Clean ctxhandler, datasources, plugin and live * Question: what to do with the UserDisplayDTO? * Clean dashboards and guardian * Remove identity.Requester from ReqContext * Implement NewUserDisplayDTOFromRequester * Fix tests * Change status code numbers for http constants * Upgrade signature of ngalert services * log parsing errors instead of throwing error * Fix tests and add logs * linting
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/kinds"
|
||||
"github.com/grafana/grafana/pkg/kinds/dashboard"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
@@ -337,7 +338,7 @@ type GetDashboardRefByIDQuery struct {
|
||||
type SaveDashboardDTO struct {
|
||||
OrgID int64
|
||||
UpdatedAt time.Time
|
||||
User *user.SignedInUser
|
||||
User identity.Requester
|
||||
Message string
|
||||
Overwrite bool
|
||||
Dashboard *Dashboard
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
@@ -181,12 +182,18 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
|
||||
}
|
||||
}
|
||||
|
||||
namespaceID, userIDstr := dto.User.GetNamespacedID()
|
||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
||||
if err != nil {
|
||||
dr.log.Warn("failed to parse user ID", "namespaceID", namespaceID, "userID", userIDstr, "error", err)
|
||||
}
|
||||
|
||||
cmd := &dashboards.SaveDashboardCommand{
|
||||
Dashboard: dash.Data,
|
||||
Message: dto.Message,
|
||||
OrgID: dto.OrgID,
|
||||
Overwrite: dto.Overwrite,
|
||||
UserID: dto.User.UserID,
|
||||
UserID: userID,
|
||||
FolderID: dash.FolderID,
|
||||
IsFolder: dash.IsFolder,
|
||||
PluginID: dash.PluginID,
|
||||
@@ -209,7 +216,7 @@ func (dr *DashboardServiceImpl) DeleteOrphanedProvisionedDashboards(ctx context.
|
||||
|
||||
// getGuardianForSavePermissionCheck returns the guardian to be used for checking permission of dashboard
|
||||
// It replaces deleted Dashboard.GetDashboardIdForSavePermissionCheck()
|
||||
func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user *user.SignedInUser) (guardian.DashboardGuardian, error) {
|
||||
func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user identity.Requester) (guardian.DashboardGuardian, error) {
|
||||
newDashboard := d.ID == 0
|
||||
|
||||
if newDashboard {
|
||||
@@ -297,7 +304,8 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
|
||||
|
||||
if dto.Dashboard.ID == 0 {
|
||||
if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err)
|
||||
namespaceID, userID := dto.User.GetNamespacedID()
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +345,8 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
|
||||
|
||||
if dto.Dashboard.ID == 0 {
|
||||
if err := dr.setDefaultPermissions(ctx, dto, dash, true); err != nil {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err)
|
||||
namespaceID, userID := dto.User.GetNamespacedID()
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +394,8 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboar
|
||||
// new dashboard created
|
||||
if dto.Dashboard.ID == 0 {
|
||||
if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err)
|
||||
namespaceID, userID := dto.User.GetNamespacedID()
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +452,8 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashbo
|
||||
}
|
||||
|
||||
if err := dr.setDefaultPermissions(ctx, dto, dash, false); err != nil {
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "user", dto.User.UserID, "error", err)
|
||||
namespaceID, userID := dto.User.GetNamespacedID()
|
||||
dr.log.Error("Could not make user admin", "dashboard", dash.Title, "namespaceID", namespaceID, "userID", userID, "error", err)
|
||||
}
|
||||
|
||||
return dash, nil
|
||||
@@ -462,9 +473,16 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
|
||||
inFolder := dash.FolderID > 0
|
||||
var permissions []accesscontrol.SetResourcePermissionCommand
|
||||
|
||||
if !provisioned && dto.User.IsRealUser() && !dto.User.IsAnonymous {
|
||||
namespaceID, userIDstr := dto.User.GetNamespacedID()
|
||||
userID, err := identity.IntIdentifier(namespaceID, userIDstr)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !provisioned && namespaceID == identity.NamespaceUser {
|
||||
permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{
|
||||
UserID: dto.User.UserID, Permission: dashboards.PERMISSION_ADMIN.String(),
|
||||
UserID: userID, Permission: dashboards.PERMISSION_ADMIN.String(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -480,7 +498,7 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
|
||||
svc = dr.folderPermissions
|
||||
}
|
||||
|
||||
_, err := svc.SetPermissions(ctx, dto.OrgID, dash.UID, permissions...)
|
||||
_, err = svc.SetPermissions(ctx, dto.OrgID, dash.UID, permissions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/alerting/models"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
@@ -112,9 +113,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sqlStore)
|
||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "", sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When creating a new dashboard in other folder, it should create dashboard guardian for other folder with correct arguments and rsult in access denied error",
|
||||
@@ -132,9 +136,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.otherSavedFolder.ID, sc.dashboardGuardianMock.DashID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When creating a new dashboard by existing title in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -152,9 +159,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When creating a new dashboard by existing UID in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -173,9 +183,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When updating a dashboard by existing id in the General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -194,9 +207,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When updating a dashboard by existing id in other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -215,9 +231,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When moving a dashboard by existing ID to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -236,9 +255,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When moving a dashboard by existing id to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -257,9 +279,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
assert.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When moving a dashboard by existing uid to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -278,9 +303,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInGeneralFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
|
||||
permissionScenario(t, "When moving a dashboard by existing UID to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error",
|
||||
@@ -299,9 +327,12 @@ func TestIntegrationIntegratedDashboardService(t *testing.T) {
|
||||
err := callSaveWithError(t, cmd, sc.sqlStore)
|
||||
require.Equal(t, dashboards.ErrDashboardUpdateAccessDenied, err)
|
||||
|
||||
userID, err := identity.IntIdentifier(sc.dashboardGuardianMock.User.GetNamespacedID())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, sc.savedDashInFolder.UID, sc.dashboardGuardianMock.DashUID)
|
||||
assert.Equal(t, cmd.OrgID, sc.dashboardGuardianMock.OrgID)
|
||||
assert.Equal(t, cmd.UserID, sc.dashboardGuardianMock.User.UserID)
|
||||
assert.Equal(t, cmd.UserID, userID)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user