mirror of https://github.com/grafana/grafana
This reverts commit 88c11f1cc0
.
pull/37405/head
parent
9494c2cd4f
commit
55efeb0c02
@ -1,169 +0,0 @@ |
|||||||
package api |
|
||||||
|
|
||||||
import ( |
|
||||||
"net/http" |
|
||||||
"net/http/httptest" |
|
||||||
"testing" |
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol" |
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning" |
|
||||||
"github.com/grafana/grafana/pkg/setting" |
|
||||||
"github.com/stretchr/testify/assert" |
|
||||||
) |
|
||||||
|
|
||||||
type reloadProvisioningTestCase struct { |
|
||||||
desc string |
|
||||||
url string |
|
||||||
expectedCode int |
|
||||||
expectedBody string |
|
||||||
permissions []*accesscontrol.Permission |
|
||||||
exit bool |
|
||||||
checkCall func(mock provisioning.ProvisioningServiceMock) |
|
||||||
} |
|
||||||
|
|
||||||
func TestAPI_AdminProvisioningReload_AccessControl(t *testing.T) { |
|
||||||
tests := []reloadProvisioningTestCase{ |
|
||||||
{ |
|
||||||
desc: "should work for dashboards with specific scope", |
|
||||||
expectedCode: http.StatusOK, |
|
||||||
expectedBody: `{"message":"Dashboards config reloaded"}`, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersDashboards, |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/dashboards/reload", |
|
||||||
checkCall: func(mock provisioning.ProvisioningServiceMock) { |
|
||||||
assert.Len(t, mock.Calls.ProvisionDashboards, 1) |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should work for dashboards with broader scope", |
|
||||||
expectedCode: http.StatusOK, |
|
||||||
expectedBody: `{"message":"Dashboards config reloaded"}`, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersAll, |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/dashboards/reload", |
|
||||||
checkCall: func(mock provisioning.ProvisioningServiceMock) { |
|
||||||
assert.Len(t, mock.Calls.ProvisionDashboards, 1) |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should fail for dashboard with wrong scope", |
|
||||||
expectedCode: http.StatusForbidden, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: "services:noservice", |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/dashboards/reload", |
|
||||||
exit: true, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should fail for dashboard with no permission", |
|
||||||
expectedCode: http.StatusForbidden, |
|
||||||
url: "/api/admin/provisioning/dashboards/reload", |
|
||||||
exit: true, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should work for notifications with specific scope", |
|
||||||
expectedCode: http.StatusOK, |
|
||||||
expectedBody: `{"message":"Notifications config reloaded"}`, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersNotifications, |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/notifications/reload", |
|
||||||
checkCall: func(mock provisioning.ProvisioningServiceMock) { |
|
||||||
assert.Len(t, mock.Calls.ProvisionNotifications, 1) |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should fail for notifications with no permission", |
|
||||||
expectedCode: http.StatusForbidden, |
|
||||||
url: "/api/admin/provisioning/notifications/reload", |
|
||||||
exit: true, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should work for datasources with specific scope", |
|
||||||
expectedCode: http.StatusOK, |
|
||||||
expectedBody: `{"message":"Datasources config reloaded"}`, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersDatasources, |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/datasources/reload", |
|
||||||
checkCall: func(mock provisioning.ProvisioningServiceMock) { |
|
||||||
assert.Len(t, mock.Calls.ProvisionDatasources, 1) |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should fail for datasources with no permission", |
|
||||||
expectedCode: http.StatusForbidden, |
|
||||||
url: "/api/admin/provisioning/datasources/reload", |
|
||||||
exit: true, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should work for plugins with specific scope", |
|
||||||
expectedCode: http.StatusOK, |
|
||||||
expectedBody: `{"message":"Plugins config reloaded"}`, |
|
||||||
permissions: []*accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersPlugins, |
|
||||||
}, |
|
||||||
}, |
|
||||||
url: "/api/admin/provisioning/plugins/reload", |
|
||||||
checkCall: func(mock provisioning.ProvisioningServiceMock) { |
|
||||||
assert.Len(t, mock.Calls.ProvisionPlugins, 1) |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
desc: "should fail for plugins with no permission", |
|
||||||
expectedCode: http.StatusForbidden, |
|
||||||
url: "/api/admin/provisioning/plugins/reload", |
|
||||||
exit: true, |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
cfg := setting.NewCfg() |
|
||||||
|
|
||||||
for _, test := range tests { |
|
||||||
t.Run(test.desc, func(t *testing.T) { |
|
||||||
sc, hs := setupAccessControlScenarioContext(t, cfg, test.url, test.permissions) |
|
||||||
|
|
||||||
// Setup the mock
|
|
||||||
provisioningMock := provisioning.NewProvisioningServiceMock() |
|
||||||
hs.ProvisioningService = provisioningMock |
|
||||||
|
|
||||||
sc.resp = httptest.NewRecorder() |
|
||||||
var err error |
|
||||||
sc.req, err = http.NewRequest(http.MethodPost, test.url, nil) |
|
||||||
assert.NoError(t, err) |
|
||||||
|
|
||||||
sc.exec() |
|
||||||
|
|
||||||
// Check return code
|
|
||||||
assert.Equal(t, test.expectedCode, sc.resp.Code) |
|
||||||
if test.exit { |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
// Check body
|
|
||||||
assert.Equal(t, test.expectedBody, sc.resp.Body.String()) |
|
||||||
|
|
||||||
// Check we actually called the provisioning service
|
|
||||||
test.checkCall(*provisioningMock) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
package api |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol" |
|
||||||
) |
|
||||||
|
|
||||||
// API related actions
|
|
||||||
const ( |
|
||||||
ActionProvisioningReload = "provisioning:reload" |
|
||||||
) |
|
||||||
|
|
||||||
// API related scopes
|
|
||||||
const ( |
|
||||||
ScopeProvisionersAll = "provisioners:*" |
|
||||||
ScopeProvisionersDashboards = "provisioners:dashboards" |
|
||||||
ScopeProvisionersPlugins = "provisioners:plugins" |
|
||||||
ScopeProvisionersDatasources = "provisioners:datasources" |
|
||||||
ScopeProvisionersNotifications = "provisioners:notifications" |
|
||||||
) |
|
||||||
|
|
||||||
// declareFixedRoles declares to the AccessControl service fixed roles and their
|
|
||||||
// grants to organization roles ("Viewer", "Editor", "Admin") or "Grafana Admin"
|
|
||||||
// that HTTPServer needs
|
|
||||||
func (hs *HTTPServer) declareFixedRoles() error { |
|
||||||
registration := accesscontrol.RoleRegistration{ |
|
||||||
Role: accesscontrol.RoleDTO{ |
|
||||||
Version: 1, |
|
||||||
Name: "fixed:provisioning:admin", |
|
||||||
Description: "Reload provisioning configurations", |
|
||||||
Permissions: []accesscontrol.Permission{ |
|
||||||
{ |
|
||||||
Action: ActionProvisioningReload, |
|
||||||
Scope: ScopeProvisionersAll, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
Grants: []string{accesscontrol.RoleGrafanaAdmin}, |
|
||||||
} |
|
||||||
|
|
||||||
return hs.AccessControl.DeclareFixedRoles(registration) |
|
||||||
} |
|
@ -1,8 +0,0 @@ |
|||||||
package accesscontrol |
|
||||||
|
|
||||||
import "errors" |
|
||||||
|
|
||||||
var ( |
|
||||||
ErrFixedRolePrefixMissing = errors.New("fixed role should be prefixed with '" + FixedRolePrefix + "'") |
|
||||||
ErrInvalidBuiltinRole = errors.New("built-in role is not valid") |
|
||||||
) |
|
Loading…
Reference in new issue