| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/http/httptest" | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 00:57:50 +08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/response" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/api/routing" | 
					
						
							| 
									
										
										
										
											2017-02-08 18:57:05 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2022-03-10 00:57:50 +08:00
										 |  |  | 	ac "github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources" | 
					
						
							| 
									
										
										
										
											2022-02-28 16:54:56 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources/permissions" | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/org" | 
					
						
							| 
									
										
										
										
											2022-02-03 16:20:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore/mockstore" | 
					
						
							| 
									
										
										
										
											2020-12-28 19:24:42 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2020-11-24 19:10:32 +08:00
										 |  |  | 	testOrgID     int64  = 1 | 
					
						
							|  |  |  | 	testUserID    int64  = 1 | 
					
						
							|  |  |  | 	testUserLogin string = "testUser" | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | func TestDataSourcesProxy_userLoggedIn(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	mockSQLStore := mockstore.NewSQLStoreMock() | 
					
						
							| 
									
										
										
										
											2022-02-28 16:54:56 +08:00
										 |  |  | 	mockDatasourcePermissionService := permissions.NewMockDatasourcePermissionService() | 
					
						
							| 
									
										
										
										
											2022-01-15 00:55:57 +08:00
										 |  |  | 	loggedInUserScenario(t, "When calling GET on", "/api/datasources/", "/api/datasources/", func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		// Stubs the database query
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		ds := []*datasources.DataSource{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			{Name: "mmm"}, | 
					
						
							|  |  |  | 			{Name: "ZZZ"}, | 
					
						
							|  |  |  | 			{Name: "BBB"}, | 
					
						
							|  |  |  | 			{Name: "aaa"}, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-02-28 16:54:56 +08:00
										 |  |  | 		mockDatasourcePermissionService.DsResult = ds | 
					
						
							| 
									
										
										
										
											2018-06-23 10:15:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		// handler func being tested
 | 
					
						
							| 
									
										
										
										
											2021-03-17 23:06:10 +08:00
										 |  |  | 		hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 			Cfg:         setting.NewCfg(), | 
					
						
							|  |  |  | 			pluginStore: &fakePluginStore{}, | 
					
						
							|  |  |  | 			DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							|  |  |  | 				expectedDatasources: ds, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			DatasourcePermissionsService: mockDatasourcePermissionService, | 
					
						
							| 
									
										
										
										
											2021-03-17 23:06:10 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-12-28 19:24:42 +08:00
										 |  |  | 		sc.handlerFunc = hs.GetDataSources | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/datasources").exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		respJSON := []map[string]interface{}{} | 
					
						
							|  |  |  | 		err := json.NewDecoder(sc.resp.Body).Decode(&respJSON) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.Equal(t, "aaa", respJSON[0]["name"]) | 
					
						
							|  |  |  | 		assert.Equal(t, "BBB", respJSON[1]["name"]) | 
					
						
							|  |  |  | 		assert.Equal(t, "mmm", respJSON[2]["name"]) | 
					
						
							|  |  |  | 		assert.Equal(t, "ZZZ", respJSON[3]["name"]) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	}, mockSQLStore) | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	loggedInUserScenario(t, "Should be able to save a data source when calling DELETE on non-existing", | 
					
						
							| 
									
										
										
										
											2022-01-15 00:55:57 +08:00
										 |  |  | 		"/api/datasources/name/12345", "/api/datasources/name/:name", func(sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 02:39:56 +08:00
										 |  |  | 			// handler func being tested
 | 
					
						
							|  |  |  | 			hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 				Cfg:         setting.NewCfg(), | 
					
						
							|  |  |  | 				pluginStore: &fakePluginStore{}, | 
					
						
							| 
									
										
										
										
											2021-05-19 02:39:56 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			sc.handlerFunc = hs.DeleteDataSourceByName | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 			sc.fakeReqWithParams("DELETE", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 			assert.Equal(t, 404, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		}, mockSQLStore) | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Adding data sources with invalid URLs should lead to an error.
 | 
					
						
							|  |  |  | func TestAddDataSource_InvalidURL(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	sc := setupScenarioContext(t, "/api/datasources") | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		DataSourcesService: &dataSourcesServiceMock{}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	sc.m.Post(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Name:   "Test", | 
					
						
							|  |  |  | 			Url:    "invalid:url", | 
					
						
							|  |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 400, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Adding data sources with URLs not specifying protocol should work.
 | 
					
						
							|  |  |  | func TestAddDataSource_URLWithoutProtocol(t *testing.T) { | 
					
						
							|  |  |  | 	const name = "Test" | 
					
						
							|  |  |  | 	const url = "localhost:5432" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			expectedDatasource: &datasources.DataSource{}, | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	sc := setupScenarioContext(t, "/api/datasources") | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	sc.m.Post(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Name:   name, | 
					
						
							|  |  |  | 			Url:    url, | 
					
						
							|  |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Updating data sources with invalid URLs should lead to an error.
 | 
					
						
							|  |  |  | func TestUpdateDataSource_InvalidURL(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		DataSourcesService: &dataSourcesServiceMock{}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	sc := setupScenarioContext(t, "/api/datasources/1234") | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Name:   "Test", | 
					
						
							|  |  |  | 			Url:    "invalid:url", | 
					
						
							|  |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 400, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Updating data sources with URLs not specifying protocol should work.
 | 
					
						
							|  |  |  | func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) { | 
					
						
							|  |  |  | 	const name = "Test" | 
					
						
							|  |  |  | 	const url = "localhost:5432" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	hs := &HTTPServer{ | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			expectedDatasource: &datasources.DataSource{}, | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 	sc := setupScenarioContext(t, "/api/datasources/1234") | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Name:   name, | 
					
						
							|  |  |  | 			Url:    url, | 
					
						
							|  |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestAPI_Datasources_AccessControl(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	testDatasource := datasources.DataSource{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		Id:     3, | 
					
						
							|  |  |  | 		Uid:    "testUID", | 
					
						
							|  |  |  | 		OrgId:  testOrgID, | 
					
						
							|  |  |  | 		Name:   "test", | 
					
						
							|  |  |  | 		Url:    "http://localhost:5432", | 
					
						
							|  |  |  | 		Type:   "postgresql", | 
					
						
							|  |  |  | 		Access: "Proxy", | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	testDatasourceReadOnly := datasources.DataSource{ | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		Id:       4, | 
					
						
							|  |  |  | 		Uid:      "testUID", | 
					
						
							|  |  |  | 		OrgId:    testOrgID, | 
					
						
							|  |  |  | 		Name:     "test", | 
					
						
							|  |  |  | 		Url:      "http://localhost:5432", | 
					
						
							|  |  |  | 		Type:     "postgresql", | 
					
						
							|  |  |  | 		Access:   "Proxy", | 
					
						
							|  |  |  | 		ReadOnly: true, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	addDatasourceBody := func() io.Reader { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		s, _ := json.Marshal(datasources.AddDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			Name:   "test", | 
					
						
							|  |  |  | 			Url:    "http://localhost:5432", | 
					
						
							|  |  |  | 			Type:   "postgresql", | 
					
						
							|  |  |  | 			Access: "Proxy", | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return bytes.NewReader(s) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	dsServiceMock := &dataSourcesServiceMock{ | 
					
						
							|  |  |  | 		expectedDatasource: &testDatasource, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-28 16:54:56 +08:00
										 |  |  | 	dsPermissionService := permissions.NewMockDatasourcePermissionService() | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	dsPermissionService.DsResult = []*datasources.DataSource{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		&testDatasource, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	updateDatasourceBody := func() io.Reader { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		s, _ := json.Marshal(datasources.UpdateDataSourceCommand{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			Name:   "test", | 
					
						
							|  |  |  | 			Url:    "http://localhost:5432", | 
					
						
							|  |  |  | 			Type:   "postgresql", | 
					
						
							|  |  |  | 			Access: "Proxy", | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return bytes.NewReader(s) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	type acTestCaseWithHandler struct { | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		body func() io.Reader | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		accessControlTestCase | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		expectedDS       *datasources.DataSource | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 		expectedSQLError error | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	tests := []acTestCaseWithHandler{ | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			body: updateDatasourceBody, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusNotFound, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPut should return 404 if datasource not found", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", "12345678"), | 
					
						
							|  |  |  | 				method:       http.MethodPut, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionWrite, | 
					
						
							|  |  |  | 						Scope:  datasources.ScopeAll, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			expectedSQLError: datasources.ErrDataSourceNotFound, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGet should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          "/api/datasources/", | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: datasources.ActionRead, Scope: datasources.ScopeAll}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGet should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          "/api/datasources/", | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			body: addDatasourceBody, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPost should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          "/api/datasources/", | 
					
						
							|  |  |  | 				method:       http.MethodPost, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: datasources.ActionCreate}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPost should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          "/api/datasources/", | 
					
						
							|  |  |  | 				method:       http.MethodPost, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			body: updateDatasourceBody, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPut should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodPut, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionWrite, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:id:%v", testDatasource.Id), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPut should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodPut, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			body: updateDatasourceBody, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesPut should return 403 for read only datasource", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasourceReadOnly.Id), | 
					
						
							|  |  |  | 				method:       http.MethodPut, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionWrite, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:id:%v", testDatasourceReadOnly.Id), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasourceReadOnly, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByID should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionDelete, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:id:%v", testDatasource.Id), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByID should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByUID should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/uid/%v", testDatasource.Uid), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionDelete, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:uid:%v", testDatasource.Uid), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByUID should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/uid/%v", testDatasource.Uid), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByName should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/name/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionDelete, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:name:%v", testDatasource.Name), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesDeleteByName should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/name/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodDelete, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByID should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionRead, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:id:%v", testDatasource.Id), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByID should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/%v", testDatasource.Id), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByUID should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/uid/%v", testDatasource.Uid), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionRead, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:uid:%v", testDatasource.Uid), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByUID should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/uid/%v", testDatasource.Uid), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByName should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/name/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionRead, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:name:%v", testDatasource.Name), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetByName should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/name/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusOK, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetIdByName should return 200 for user with correct permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/id/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions: []ac.Permission{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-03-16 22:11:03 +08:00
										 |  |  | 						Action: datasources.ActionIDRead, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 						Scope:  fmt.Sprintf("datasources:name:%v", testDatasource.Name), | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			accessControlTestCase: accessControlTestCase{ | 
					
						
							|  |  |  | 				expectedCode: http.StatusForbidden, | 
					
						
							|  |  |  | 				desc:         "DatasourcesGetIdByName should return 403 for user without required permissions", | 
					
						
							|  |  |  | 				url:          fmt.Sprintf("/api/datasources/id/%v", testDatasource.Name), | 
					
						
							|  |  |  | 				method:       http.MethodGet, | 
					
						
							| 
									
										
										
										
											2022-06-14 16:17:48 +08:00
										 |  |  | 				permissions:  []ac.Permission{{Action: "wrong"}}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			expectedDS: &testDatasource, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, test := range tests { | 
					
						
							|  |  |  | 		t.Run(test.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			cfg := setting.NewCfg() | 
					
						
							|  |  |  | 			sc, hs := setupAccessControlScenarioContext(t, cfg, test.url, test.permissions) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			// mock sqlStore and datasource permission service
 | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 			dsServiceMock.expectedError = test.expectedSQLError | 
					
						
							|  |  |  | 			dsServiceMock.expectedDatasource = test.expectedDS | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			dsPermissionService.DsResult = []*datasources.DataSource{test.expectedDS} | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			if test.expectedDS == nil { | 
					
						
							| 
									
										
										
										
											2022-02-28 16:54:56 +08:00
										 |  |  | 				dsPermissionService.DsResult = nil | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 			hs.DataSourcesService = dsServiceMock | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 			hs.DatasourcePermissionsService = dsPermissionService | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			// Create a middleware to pretend user is logged in
 | 
					
						
							|  |  |  | 			pretendSignInMiddleware := func(c *models.ReqContext) { | 
					
						
							|  |  |  | 				sc.context = c | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 				sc.context.UserID = testUserID | 
					
						
							|  |  |  | 				sc.context.OrgID = testOrgID | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 				sc.context.Login = testUserLogin | 
					
						
							| 
									
										
										
										
											2022-08-10 17:56:48 +08:00
										 |  |  | 				sc.context.OrgRole = org.RoleViewer | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 				sc.context.IsSignedIn = true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			sc.m.Use(pretendSignInMiddleware) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.resp = httptest.NewRecorder() | 
					
						
							|  |  |  | 			hs.SettingsProvider = &setting.OSSImpl{Cfg: cfg} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var err error | 
					
						
							|  |  |  | 			if test.body != nil { | 
					
						
							|  |  |  | 				sc.req, err = http.NewRequest(test.method, test.url, test.body()) | 
					
						
							|  |  |  | 				sc.req.Header.Add("Content-Type", "application/json") | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				sc.req, err = http.NewRequest(test.method, test.url, nil) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			assert.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							|  |  |  | 			assert.Equal(t, test.expectedCode, sc.resp.Code) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type dataSourcesServiceMock struct { | 
					
						
							|  |  |  | 	datasources.DataSourceService | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	expectedDatasources []*datasources.DataSource | 
					
						
							|  |  |  | 	expectedDatasource  *datasources.DataSource | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	expectedError       error | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	query.Result = m.expectedDatasource | 
					
						
							|  |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	query.Result = m.expectedDatasources | 
					
						
							|  |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	cmd.Result = m.expectedDatasource | 
					
						
							|  |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error { | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	cmd.Result = m.expectedDatasource | 
					
						
							|  |  |  | 	return m.expectedError | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | func (m *dataSourcesServiceMock) DecryptedValues(ctx context.Context, ds *datasources.DataSource) (map[string]string, error) { | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 	decryptedValues := make(map[string]string) | 
					
						
							|  |  |  | 	return decryptedValues, m.expectedError | 
					
						
							|  |  |  | } |