mirror of
https://github.com/grafana/grafana.git
synced 2025-07-28 06:52:08 +08:00

* UserService: update callers to use the UserService instead of calling sqlstore directly There is one major change hiding in this PR. UserService.Delete originally called a number of services to delete user-related records. I moved everything except the actual call to the user table, and moved those into the API. This was done to avoid dependencies cycles; many of our services depend on the user service, so the user service itself should have as few dependencies as possible.
538 lines
23 KiB
Go
538 lines
23 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
var (
|
|
searchOrgsURL = "/api/orgs/"
|
|
getCurrentOrgURL = "/api/org/"
|
|
getOrgsURL = "/api/orgs/%v"
|
|
getOrgsByNameURL = "/api/orgs/name/%v"
|
|
putCurrentOrgURL = "/api/org/"
|
|
putOrgsURL = "/api/orgs/%v"
|
|
putCurrentOrgAddressURL = "/api/org/address"
|
|
putOrgsAddressURL = "/api/orgs/%v/address"
|
|
|
|
testUpdateOrgNameForm = `{ "name": "TestOrgChanged" }`
|
|
testUpdateOrgAddressForm = `{ "address1": "1 test road",
|
|
"address2": "2 test road",
|
|
"city": "TestCity",
|
|
"ZipCode": "TESTZIPCODE",
|
|
"State": "TestState",
|
|
"Country": "TestCountry" }`
|
|
|
|
deleteOrgsURL = "/api/orgs/%v"
|
|
|
|
createOrgsURL = "/api/orgs/"
|
|
testCreateOrgCmd = `{ "name": "TestOrg%v"}`
|
|
)
|
|
|
|
// `/api/org` endpoints test
|
|
|
|
func TestAPIEndpoint_GetCurrentOrg_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("Viewer can view CurrentOrg", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, getCurrentOrgURL, nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
sc.initCtx.IsSignedIn = false
|
|
t.Run("Unsigned user cannot view CurrentOrg", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, getCurrentOrgURL, nil, t)
|
|
assert.Equal(t, http.StatusUnauthorized, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_GetCurrentOrg_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("AccessControl allows viewing CurrentOrg with correct permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodGet, getCurrentOrgURL, nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents viewing CurrentOrg with correct permissions in another org", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, 2)
|
|
response := callAPI(sc.server, http.MethodGet, getCurrentOrgURL, nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents viewing CurrentOrg with incorrect permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodGet, getCurrentOrgURL, nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutCurrentOrg_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
|
|
require.NoError(t, err)
|
|
|
|
input := strings.NewReader(testUpdateOrgNameForm)
|
|
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
t.Run("Viewer cannot update current org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
setInitCtxSignedInOrgAdmin(sc.initCtx)
|
|
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
|
|
t.Run("Admin can update current org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutCurrentOrg_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", sc.initCtx.UserID)
|
|
require.NoError(t, err)
|
|
|
|
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
|
|
|
|
input := strings.NewReader(testUpdateOrgNameForm)
|
|
t.Run("AccessControl allows updating current org with correct permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating current org with correct permissions in another org", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating current org with incorrect permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutCurrentOrgAddress_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
|
|
require.NoError(t, err)
|
|
|
|
input := strings.NewReader(testUpdateOrgAddressForm)
|
|
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
t.Run("Viewer cannot update current org address", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgAddressURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
setInitCtxSignedInOrgAdmin(sc.initCtx)
|
|
t.Run("Admin can update current org address", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgAddressURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutCurrentOrgAddress_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
_, err := sc.db.CreateOrgWithMember("TestOrg", testUserID)
|
|
require.NoError(t, err)
|
|
|
|
input := strings.NewReader(testUpdateOrgAddressForm)
|
|
t.Run("AccessControl allows updating current org address with correct permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgAddressURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
input = strings.NewReader(testUpdateOrgAddressForm)
|
|
t.Run("AccessControl prevents updating current org address with correct permissions in another org", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgAddressURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating current org address with incorrect permissions", func(t *testing.T) {
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, sc.initCtx.OrgID)
|
|
response := callAPI(sc.server, http.MethodPut, putCurrentOrgAddressURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
// `/api/orgs/` endpoints test
|
|
|
|
// setupOrgsDBForAccessControlTests creates orgs up until orgID and fake user as member of org
|
|
func setupOrgsDBForAccessControlTests(t *testing.T, db sqlstore.Store, c accessControlScenarioContext, orgID int64) {
|
|
t.Helper()
|
|
setInitCtxSignedInViewer(c.initCtx)
|
|
u := *c.initCtx.SignedInUser
|
|
u.OrgID = orgID
|
|
c.userService.(*usertest.FakeUserService).ExpectedSignedInUser = &u
|
|
|
|
// Create `orgsCount` orgs
|
|
for i := 1; i <= int(orgID); i++ {
|
|
_, err := db.CreateOrgWithMember(fmt.Sprintf("TestOrg%v", i), 0)
|
|
require.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
func TestAPIEndpoint_CreateOrgs_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
setting.AllowUserOrgCreate = false
|
|
input := strings.NewReader(fmt.Sprintf(testCreateOrgCmd, 2))
|
|
t.Run("Viewer cannot create Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPost, createOrgsURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
input = strings.NewReader(fmt.Sprintf(testCreateOrgCmd, 3))
|
|
t.Run("Grafana Admin viewer can create Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPost, createOrgsURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = false
|
|
setting.AllowUserOrgCreate = true
|
|
input = strings.NewReader(fmt.Sprintf(testCreateOrgCmd, 4))
|
|
t.Run("User viewer can create Orgs when AllowUserOrgCreate setting is true", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPost, createOrgsURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_CreateOrgs_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 0)
|
|
|
|
input := strings.NewReader(fmt.Sprintf(testCreateOrgCmd, 2))
|
|
t.Run("AccessControl allows creating Orgs with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsCreate}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodPost, createOrgsURL, input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
input = strings.NewReader(fmt.Sprintf(testCreateOrgCmd, 3))
|
|
t.Run("AccessControl prevents creating Orgs with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodPost, createOrgsURL, input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_DeleteOrgs_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("Viewer cannot delete Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodDelete, fmt.Sprintf(deleteOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana Admin viewer can delete Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodDelete, fmt.Sprintf(deleteOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_DeleteOrgs_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("AccessControl prevents deleting Orgs with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
|
|
response := callAPI(sc.server, http.MethodDelete, fmt.Sprintf(deleteOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents deleting Orgs with correct permissions in another org", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsDelete}}, 1)
|
|
response := callAPI(sc.server, http.MethodDelete, fmt.Sprintf(deleteOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
t.Run("AccessControl allows deleting Orgs with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsDelete}}, 2)
|
|
response := callAPI(sc.server, http.MethodDelete, fmt.Sprintf(deleteOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_SearchOrgs_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
t.Run("Viewer cannot list Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, searchOrgsURL, nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana Admin viewer can list Orgs", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, searchOrgsURL, nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_SearchOrgs_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
|
|
t.Run("AccessControl allows listing Orgs with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodGet, searchOrgsURL, nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents listing Orgs with correct permissions not granted globally", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, 1)
|
|
response := callAPI(sc.server, http.MethodGet, searchOrgsURL, nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents listing Orgs with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodGet, searchOrgsURL, nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_GetOrg_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
// Create two orgs, to fetch another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("Viewer cannot view another Org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana admin viewer can view another Org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_GetOrg_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
|
|
// Create two orgs, to fetch another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("AccessControl allows viewing another org with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, 2)
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents viewing another org with correct permissions in another org", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, 1)
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents viewing another org with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsURL, 2), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_GetOrgByName_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
// Create two orgs, to fetch another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("Viewer cannot view another Org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsByNameURL, "TestOrg2"), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana admin viewer can view another Org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsByNameURL, "TestOrg2"), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_GetOrgByName_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
|
|
// Create two orgs, to fetch another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
t.Run("AccessControl allows viewing another org with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsRead}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsByNameURL, "TestOrg2"), nil, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
t.Run("AccessControl prevents viewing another org with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, accesscontrol.GlobalOrgID)
|
|
response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsByNameURL, "TestOrg2"), nil, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutOrg_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
|
|
// Create two orgs, to update another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
input := strings.NewReader(testUpdateOrgNameForm)
|
|
|
|
t.Run("Viewer cannot update another org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana Admin can update another org", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsURL, 2), input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutOrg_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
|
|
// Create two orgs, to update another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
input := strings.NewReader(testUpdateOrgNameForm)
|
|
t.Run("AccessControl allows updating another org with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsURL, 2), input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating another org with correct permissions in another org", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 1)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating another org with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutOrgAddress_LegacyAccessControl(t *testing.T) {
|
|
cfg := setting.NewCfg()
|
|
cfg.RBACEnabled = false
|
|
sc := setupHTTPServerWithCfg(t, true, cfg)
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
|
|
// Create two orgs, to update another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
input := strings.NewReader(testUpdateOrgAddressForm)
|
|
|
|
t.Run("Viewer cannot update another org address", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsAddressURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
sc.initCtx.SignedInUser.IsGrafanaAdmin = true
|
|
t.Run("Grafana Admin can update another org address", func(t *testing.T) {
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsAddressURL, 2), input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
}
|
|
|
|
func TestAPIEndpoint_PutOrgAddress_AccessControl(t *testing.T) {
|
|
sc := setupHTTPServer(t, true)
|
|
|
|
// Create two orgs, to update another one than the logged in one
|
|
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
|
|
|
|
input := strings.NewReader(testUpdateOrgAddressForm)
|
|
t.Run("AccessControl allows updating another org address with correct permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsAddressURL, 2), input, t)
|
|
assert.Equal(t, http.StatusOK, response.Code)
|
|
})
|
|
|
|
input = strings.NewReader(testUpdateOrgAddressForm)
|
|
t.Run("AccessControl prevents updating another org address with correct permissions in the current org", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: accesscontrol.ActionOrgsWrite}}, 1)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsAddressURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
|
|
t.Run("AccessControl prevents updating another org address with incorrect permissions", func(t *testing.T) {
|
|
setInitCtxSignedInViewer(sc.initCtx)
|
|
setAccessControlPermissions(sc.acmock, []accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
|
|
response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsAddressURL, 2), input, t)
|
|
assert.Equal(t, http.StatusForbidden, response.Code)
|
|
})
|
|
}
|