mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			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.SQLStore, 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)
 | |
| 	})
 | |
| }
 |