mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			173 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
| package api
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 
 | |
| 	"github.com/grafana/grafana/pkg/services/accesscontrol"
 | |
| 	"github.com/grafana/grafana/pkg/setting"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	getCurrentOrgQuotasURL = "/api/org/quotas"
 | |
| 	getOrgsQuotasURL       = "/api/orgs/%v/quotas"
 | |
| 	putOrgsQuotasURL       = "/api/orgs/%v/quotas/%v"
 | |
| 
 | |
| 	testUpdateOrgQuotaCmd = `{ "limit": 20 }`
 | |
| )
 | |
| 
 | |
| var testOrgQuota = setting.OrgQuota{
 | |
| 	User:       10,
 | |
| 	DataSource: 10,
 | |
| 	Dashboard:  10,
 | |
| 	ApiKey:     10,
 | |
| 	AlertRule:  10,
 | |
| }
 | |
| 
 | |
| // setupDBAndSettingsForAccessControlQuotaTests stores users and create two orgs
 | |
| func setupDBAndSettingsForAccessControlQuotaTests(t *testing.T, sc accessControlScenarioContext) {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	sc.hs.Cfg.Quota.Enabled = true
 | |
| 	sc.hs.Cfg.Quota.Org = &testOrgQuota
 | |
| 	// Required while sqlstore quota.go relies on setting global variables
 | |
| 	setting.Quota = sc.hs.Cfg.Quota
 | |
| 
 | |
| 	// Create two orgs with the context user
 | |
| 	setupOrgsDBForAccessControlTests(t, sc.db, *sc.initCtx.SignedInUser, 2)
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_GetCurrentOrgQuotas_LegacyAccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, false)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	t.Run("Viewer can view CurrentOrgQuotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodGet, getCurrentOrgQuotasURL, nil, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| 
 | |
| 	sc.initCtx.IsSignedIn = false
 | |
| 	t.Run("Unsigned user cannot view CurrentOrgQuotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodGet, getCurrentOrgQuotasURL, nil, t)
 | |
| 		assert.Equal(t, http.StatusUnauthorized, response.Code)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_GetCurrentOrgQuotas_AccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, true)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	t.Run("AccessControl allows viewing CurrentOrgQuotas with correct permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasRead}}, sc.initCtx.OrgId)
 | |
| 		response := callAPI(sc.server, http.MethodGet, getCurrentOrgQuotasURL, nil, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| 	t.Run("AccessControl prevents viewing CurrentOrgQuotas with correct permissions in another org", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasRead}}, 2)
 | |
| 		response := callAPI(sc.server, http.MethodGet, getCurrentOrgQuotasURL, nil, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| 	t.Run("AccessControl prevents viewing CurrentOrgQuotas with incorrect permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: "orgs:invalid"}}, sc.initCtx.OrgId)
 | |
| 		response := callAPI(sc.server, http.MethodGet, getCurrentOrgQuotasURL, nil, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_GetOrgQuotas_LegacyAccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, false)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	t.Run("Viewer cannot view another org quotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsQuotasURL, 2), nil, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| 
 | |
| 	sc.initCtx.SignedInUser.IsGrafanaAdmin = true
 | |
| 	t.Run("Grafana admin viewer can view another org quotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsQuotasURL, 2), nil, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_GetOrgQuotas_AccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, true)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	t.Run("AccessControl allows viewing another org quotas with correct permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasRead}}, 2)
 | |
| 		response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsQuotasURL, 2), nil, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| 	t.Run("AccessControl prevents viewing another org quotas with correct permissions in another org", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasRead}}, 1)
 | |
| 		response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsQuotasURL, 2), nil, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| 	t.Run("AccessControl prevents viewing another org quotas with incorrect permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
 | |
| 		response := callAPI(sc.server, http.MethodGet, fmt.Sprintf(getOrgsQuotasURL, 2), nil, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_PutOrgQuotas_LegacyAccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, false)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	input := strings.NewReader(testUpdateOrgQuotaCmd)
 | |
| 	t.Run("Viewer cannot update another org quotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsQuotasURL, 2, "org_user"), input, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| 
 | |
| 	sc.initCtx.SignedInUser.IsGrafanaAdmin = true
 | |
| 	input = strings.NewReader(testUpdateOrgQuotaCmd)
 | |
| 	t.Run("Grafana admin viewer can update another org quotas", func(t *testing.T) {
 | |
| 		response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsQuotasURL, 2, "org_user"), input, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAPIEndpoint_PutOrgQuotas_AccessControl(t *testing.T) {
 | |
| 	sc := setupHTTPServer(t, true, true)
 | |
| 	setInitCtxSignedInViewer(sc.initCtx)
 | |
| 
 | |
| 	setupDBAndSettingsForAccessControlQuotaTests(t, sc)
 | |
| 
 | |
| 	input := strings.NewReader(testUpdateOrgQuotaCmd)
 | |
| 	t.Run("AccessControl allows updating another org quotas with correct permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasWrite}}, 2)
 | |
| 		response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsQuotasURL, 2, "org_user"), input, t)
 | |
| 		assert.Equal(t, http.StatusOK, response.Code)
 | |
| 	})
 | |
| 
 | |
| 	input = strings.NewReader(testUpdateOrgQuotaCmd)
 | |
| 	t.Run("AccessControl prevents updating another org quotas with correct permissions in another org", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: ActionOrgsQuotasWrite}}, 1)
 | |
| 		response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsQuotasURL, 2, "org_user"), input, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| 
 | |
| 	input = strings.NewReader(testUpdateOrgQuotaCmd)
 | |
| 	t.Run("AccessControl prevents updating another org quotas with incorrect permissions", func(t *testing.T) {
 | |
| 		setAccessControlPermissions(sc.acmock, []*accesscontrol.Permission{{Action: "orgs:invalid"}}, 2)
 | |
| 		response := callAPI(sc.server, http.MethodPut, fmt.Sprintf(putOrgsQuotasURL, 2, "org_user"), input, t)
 | |
| 		assert.Equal(t, http.StatusForbidden, response.Code)
 | |
| 	})
 | |
| }
 |