| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2017-02-08 05:15:52 +08:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/components/simplejson" | 
					
						
							| 
									
										
										
										
											2023-01-18 23:01:25 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/db/dbtest" | 
					
						
							| 
									
										
										
										
											2022-03-10 00:57:50 +08:00
										 |  |  | 	ac "github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2022-11-24 22:38:55 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol/actest" | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources" | 
					
						
							| 
									
										
										
										
											2023-08-21 21:26:49 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources/guardian" | 
					
						
							| 
									
										
										
										
											2023-10-18 23:09:22 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2023-09-11 19:59:24 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" | 
					
						
							| 
									
										
										
										
											2020-12-28 19:24:42 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2023-07-17 22:27:19 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web" | 
					
						
							| 
									
										
										
										
											2023-01-30 16:18:26 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web/webtest" | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2023-01-18 23:01:25 +08:00
										 |  |  | 	mockSQLStore := dbtest.NewFakeDB() | 
					
						
							| 
									
										
										
										
											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"}, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											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(), | 
					
						
							| 
									
										
										
										
											2023-09-11 19:59:24 +08:00
										 |  |  | 			pluginStore: &pluginstore.FakePluginStore{}, | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 			DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							|  |  |  | 				expectedDatasources: ds, | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2023-08-21 21:26:49 +08:00
										 |  |  | 			dsGuardian: guardian.ProvideGuardian(), | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 		respJSON := []map[string]any{} | 
					
						
							| 
									
										
										
										
											2020-11-13 16:52:38 +08:00
										 |  |  | 		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(), | 
					
						
							| 
									
										
										
										
											2023-09-11 19:59:24 +08:00
										 |  |  | 				pluginStore: &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-09-21 01:31:08 +08:00
										 |  |  | 		Cfg:                setting.NewCfg(), | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Post(sc.url, routing.Wrap(func(c *contextmodel.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", | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:    "invalid:url", | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							| 
									
										
										
										
											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-11-24 22:38:55 +08:00
										 |  |  | 		Cfg:                  setting.NewCfg(), | 
					
						
							|  |  |  | 		AccessControl:        acimpl.ProvideAccessControl(setting.NewCfg()), | 
					
						
							|  |  |  | 		accesscontrolService: actest.FakeService{}, | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Post(sc.url, routing.Wrap(func(c *contextmodel.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, | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:    url, | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | // Using a custom header whose name matches the name specified for auth proxy header should fail
 | 
					
						
							|  |  |  | func TestAddDataSource_InvalidJSONData(t *testing.T) { | 
					
						
							|  |  |  | 	hs := &HTTPServer{ | 
					
						
							|  |  |  | 		DataSourcesService: &dataSourcesServiceMock{}, | 
					
						
							|  |  |  | 		Cfg:                setting.NewCfg(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc := setupScenarioContext(t, "/api/datasources") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hs.Cfg = setting.NewCfg() | 
					
						
							|  |  |  | 	hs.Cfg.AuthProxyEnabled = true | 
					
						
							|  |  |  | 	hs.Cfg.AuthProxyHeaderName = "X-AUTH-PROXY-HEADER" | 
					
						
							|  |  |  | 	jsonData := simplejson.New() | 
					
						
							|  |  |  | 	jsonData.Set("httpHeaderName1", hs.Cfg.AuthProxyHeaderName) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Post(sc.url, routing.Wrap(func(c *contextmodel.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							|  |  |  | 			Name:     "Test", | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:      "localhost:5432", | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 			Access:   "direct", | 
					
						
							|  |  |  | 			Type:     "test", | 
					
						
							|  |  |  | 			JsonData: jsonData, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							|  |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 400, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | // 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-09-21 01:31:08 +08:00
										 |  |  | 		Cfg:                setting.NewCfg(), | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *contextmodel.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", | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:    "invalid:url", | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | // Using a custom header whose name matches the name specified for auth proxy header should fail
 | 
					
						
							|  |  |  | func TestUpdateDataSource_InvalidJSONData(t *testing.T) { | 
					
						
							|  |  |  | 	hs := &HTTPServer{ | 
					
						
							|  |  |  | 		DataSourcesService: &dataSourcesServiceMock{}, | 
					
						
							|  |  |  | 		Cfg:                setting.NewCfg(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sc := setupScenarioContext(t, "/api/datasources/1234") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hs.Cfg.AuthProxyEnabled = true | 
					
						
							|  |  |  | 	hs.Cfg.AuthProxyHeaderName = "X-AUTH-PROXY-HEADER" | 
					
						
							|  |  |  | 	jsonData := simplejson.New() | 
					
						
							|  |  |  | 	jsonData.Set("httpHeaderName1", hs.Cfg.AuthProxyHeaderName) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *contextmodel.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 		c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							|  |  |  | 			Name:     "Test", | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:      "localhost:5432", | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 			Access:   "direct", | 
					
						
							|  |  |  | 			Type:     "test", | 
					
						
							|  |  |  | 			JsonData: jsonData, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | 		return hs.AddDataSource(c) | 
					
						
							|  |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	assert.Equal(t, 400, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Using a team HTTP header whose name matches the name specified for auth proxy header should fail
 | 
					
						
							|  |  |  | func TestUpdateDataSourceTeamHTTPHeaders_InvalidJSONData(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 	tenantID := "1234" | 
					
						
							|  |  |  | 	testcases := []struct { | 
					
						
							|  |  |  | 		desc string | 
					
						
							|  |  |  | 		data datasources.TeamHTTPHeaders | 
					
						
							|  |  |  | 		want int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc: "We should only allow for headers being X-Prom-Label-Policy", | 
					
						
							|  |  |  | 			data: datasources.TeamHTTPHeaders{tenantID: []datasources.TeamHTTPHeader{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Header: "Authorization", | 
					
						
							|  |  |  | 					Value:  "foo!=bar", | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:54 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			want: 400, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc: "Allowed header but no team id", | 
					
						
							|  |  |  | 			data: datasources.TeamHTTPHeaders{"": []datasources.TeamHTTPHeader{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Header: "X-Prom-Label-Policy", | 
					
						
							|  |  |  | 					Value:  "foo=bar", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: 400, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc: "Allowed team id and header name with invalid header values ", | 
					
						
							|  |  |  | 			data: datasources.TeamHTTPHeaders{tenantID: []datasources.TeamHTTPHeader{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Header: "X-Prom-Label-Policy", | 
					
						
							|  |  |  | 					Value:  "Bad value", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: 400, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Complete valid case, with team id, header name and header value
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			desc: "Allowed header and header values ", | 
					
						
							|  |  |  | 			data: datasources.TeamHTTPHeaders{tenantID: []datasources.TeamHTTPHeader{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Header: "X-Prom-Label-Policy", | 
					
						
							|  |  |  | 					Value:  `1234:{ name!="value",foo!~"bar" }`, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			want: 200, | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:54 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 	for _, tc := range testcases { | 
					
						
							|  |  |  | 		t.Run(tc.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			hs := &HTTPServer{ | 
					
						
							|  |  |  | 				DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							|  |  |  | 					expectedDatasource: &datasources.DataSource{}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				Cfg:                  setting.NewCfg(), | 
					
						
							|  |  |  | 				Features:             featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders), | 
					
						
							|  |  |  | 				accesscontrolService: actest.FakeService{}, | 
					
						
							| 
									
										
										
										
											2023-11-08 22:37:32 +08:00
										 |  |  | 				AccessControl: actest.FakeAccessControl{ | 
					
						
							|  |  |  | 					ExpectedEvaluate: true, | 
					
						
							|  |  |  | 					ExpectedErr:      nil, | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			sc := setupScenarioContext(t, fmt.Sprintf("/api/datasources/%s", tenantID)) | 
					
						
							|  |  |  | 			hs.Cfg.AuthProxyEnabled = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			jsonData := simplejson.New() | 
					
						
							|  |  |  | 			jsonData.Set("teamHttpHeaders", tc.data) | 
					
						
							|  |  |  | 			sc.m.Put(sc.url, routing.Wrap(func(c *contextmodel.ReqContext) response.Response { | 
					
						
							|  |  |  | 				c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{ | 
					
						
							|  |  |  | 					Name:     "Test", | 
					
						
							|  |  |  | 					URL:      "localhost:5432", | 
					
						
							|  |  |  | 					Access:   "direct", | 
					
						
							|  |  |  | 					Type:     "test", | 
					
						
							|  |  |  | 					JsonData: jsonData, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2023-11-08 22:37:32 +08:00
										 |  |  | 				c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{ | 
					
						
							|  |  |  | 					{Action: datasources.ActionPermissionsWrite, Scope: datasources.ScopeAll}, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 				return hs.AddDataSource(c) | 
					
						
							|  |  |  | 			})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.Equal(t, tc.want, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2023-10-17 18:23:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-09-21 01:31:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | // 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-11-24 22:38:55 +08:00
										 |  |  | 		Cfg:                  setting.NewCfg(), | 
					
						
							|  |  |  | 		AccessControl:        acimpl.ProvideAccessControl(setting.NewCfg()), | 
					
						
							|  |  |  | 		accesscontrolService: actest.FakeService{}, | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *contextmodel.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, | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			URL:    url, | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							| 
									
										
										
										
											2020-05-12 19:04:18 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 		c.SignedInUser = authedUserWithPermissions(1, 1, []ac.Permission{}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 22:27:19 +08:00
										 |  |  | // Updating data source name where data source with same name exists.
 | 
					
						
							|  |  |  | func TestUpdateDataSourceByID_DataSourceNameExists(t *testing.T) { | 
					
						
							|  |  |  | 	hs := &HTTPServer{ | 
					
						
							|  |  |  | 		DataSourcesService: &dataSourcesServiceMock{ | 
					
						
							|  |  |  | 			expectedDatasource: &datasources.DataSource{}, | 
					
						
							|  |  |  | 			mockUpdateDataSource: func(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) (*datasources.DataSource, error) { | 
					
						
							|  |  |  | 				return nil, datasources.ErrDataSourceNameExists | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Cfg:                  setting.NewCfg(), | 
					
						
							|  |  |  | 		AccessControl:        acimpl.ProvideAccessControl(setting.NewCfg()), | 
					
						
							|  |  |  | 		accesscontrolService: actest.FakeService{}, | 
					
						
							|  |  |  | 		Live:                 newTestLive(t, nil), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc := setupScenarioContext(t, "/api/datasources/1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.m.Put(sc.url, routing.Wrap(func(c *contextmodel.ReqContext) response.Response { | 
					
						
							|  |  |  | 		c.Req = web.SetURLParams(c.Req, map[string]string{":id": "1"}) | 
					
						
							|  |  |  | 		c.Req.Body = mockRequestBody(datasources.UpdateDataSourceCommand{ | 
					
						
							|  |  |  | 			Access: "direct", | 
					
						
							|  |  |  | 			Type:   "test", | 
					
						
							|  |  |  | 			Name:   "test", | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return hs.UpdateDataSourceByID(c) | 
					
						
							|  |  |  | 	})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	require.Equal(t, http.StatusConflict, sc.resp.Code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | func TestAPI_datasources_AccessControl(t *testing.T) { | 
					
						
							|  |  |  | 	type testCase struct { | 
					
						
							|  |  |  | 		desc         string | 
					
						
							|  |  |  | 		urls         []string | 
					
						
							|  |  |  | 		method       string | 
					
						
							|  |  |  | 		body         string | 
					
						
							|  |  |  | 		permission   []ac.Permission | 
					
						
							|  |  |  | 		expectedCode int | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-09 21:01:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 	tests := []testCase{ | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:   "should be able to update datasource with correct permission", | 
					
						
							|  |  |  | 			urls:   []string{"api/datasources/1", "/api/datasources/uid/1"}, | 
					
						
							|  |  |  | 			method: http.MethodPut, | 
					
						
							|  |  |  | 			body:   `{"name": "test", "url": "http://localhost:5432", "type": "postgresql", "access": "Proxy"}`, | 
					
						
							|  |  |  | 			permission: []ac.Permission{ | 
					
						
							|  |  |  | 				{Action: datasources.ActionWrite, Scope: datasources.ScopeProvider.GetResourceScope("1")}, | 
					
						
							|  |  |  | 				{Action: datasources.ActionWrite, Scope: datasources.ScopeProvider.GetResourceScopeUID("1")}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:         "should not be able to update datasource without correct permission", | 
					
						
							|  |  |  | 			urls:         []string{"api/datasources/1", "/api/datasources/uid/1"}, | 
					
						
							|  |  |  | 			method:       http.MethodPut, | 
					
						
							|  |  |  | 			permission:   []ac.Permission{}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:   "should be able to fetch datasource with correct permission", | 
					
						
							|  |  |  | 			urls:   []string{"api/datasources/1", "/api/datasources/uid/1", "/api/datasources/name/test"}, | 
					
						
							|  |  |  | 			method: http.MethodGet, | 
					
						
							|  |  |  | 			permission: []ac.Permission{ | 
					
						
							|  |  |  | 				{Action: datasources.ActionRead, Scope: datasources.ScopeProvider.GetResourceScope("1")}, | 
					
						
							|  |  |  | 				{Action: datasources.ActionRead, Scope: datasources.ScopeProvider.GetResourceScopeUID("1")}, | 
					
						
							|  |  |  | 				{Action: datasources.ActionRead, Scope: datasources.ScopeProvider.GetResourceScopeName("test")}, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2022-01-22 07:22:43 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:         "should not be able to fetch datasource without correct permission", | 
					
						
							|  |  |  | 			urls:         []string{"api/datasources/1", "/api/datasources/uid/1"}, | 
					
						
							|  |  |  | 			method:       http.MethodGet, | 
					
						
							|  |  |  | 			permission:   []ac.Permission{}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:         "should be able to create datasource with correct permission", | 
					
						
							|  |  |  | 			urls:         []string{"/api/datasources"}, | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			body:         `{"name": "test", "url": "http://localhost:5432", "type": "postgresql", "access": "Proxy"}`, | 
					
						
							|  |  |  | 			permission:   []ac.Permission{{Action: datasources.ActionCreate}}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:         "should not be able to create datasource without correct permission", | 
					
						
							|  |  |  | 			urls:         []string{"/api/datasources"}, | 
					
						
							|  |  |  | 			method:       http.MethodPost, | 
					
						
							|  |  |  | 			permission:   []ac.Permission{}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:   "should be able to delete datasource with correct permission", | 
					
						
							|  |  |  | 			urls:   []string{"/api/datasources/1", "/api/datasources/uid/1"}, | 
					
						
							|  |  |  | 			method: http.MethodDelete, | 
					
						
							|  |  |  | 			permission: []ac.Permission{ | 
					
						
							|  |  |  | 				{Action: datasources.ActionDelete, Scope: datasources.ScopeProvider.GetResourceScope("1")}, | 
					
						
							|  |  |  | 				{Action: datasources.ActionDelete, Scope: datasources.ScopeProvider.GetResourceScopeUID("1")}, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			expectedCode: http.StatusOK, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 			desc:         "should not be able to delete datasource without correct permission", | 
					
						
							|  |  |  | 			urls:         []string{"/api/datasources/1", "/api/datasources/uid/1"}, | 
					
						
							|  |  |  | 			method:       http.MethodDelete, | 
					
						
							|  |  |  | 			permission:   []ac.Permission{}, | 
					
						
							|  |  |  | 			expectedCode: http.StatusForbidden, | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.desc, func(t *testing.T) { | 
					
						
							|  |  |  | 			server := SetupAPITestServer(t, func(hs *HTTPServer) { | 
					
						
							|  |  |  | 				hs.Cfg = setting.NewCfg() | 
					
						
							|  |  |  | 				hs.DataSourcesService = &dataSourcesServiceMock{expectedDatasource: &datasources.DataSource{}} | 
					
						
							|  |  |  | 				hs.accesscontrolService = actest.FakeService{} | 
					
						
							|  |  |  | 				hs.Live = newTestLive(t, hs.SQLStore) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for _, url := range tt.urls { | 
					
						
							|  |  |  | 				var body io.Reader | 
					
						
							|  |  |  | 				if tt.body != "" { | 
					
						
							|  |  |  | 					body = strings.NewReader(tt.body) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 				res, err := server.SendJSON(webtest.RequestWithSignedInUser(server.NewRequest(tt.method, url, body), authedUserWithPermissions(1, 1, tt.permission))) | 
					
						
							| 
									
										
										
										
											2023-01-23 17:54:29 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							|  |  |  | 				assert.Equal(t, tt.expectedCode, res.StatusCode) | 
					
						
							|  |  |  | 				require.NoError(t, res.Body.Close()) | 
					
						
							| 
									
										
										
										
											2021-09-01 21:18:17 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-03 22:02:57 +08:00
										 |  |  | func TestValidateLBACHeader(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 	testcases := []struct { | 
					
						
							|  |  |  | 		desc            string | 
					
						
							|  |  |  | 		teamHeaderValue string | 
					
						
							|  |  |  | 		want            bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-11-03 22:02:57 +08:00
										 |  |  | 			desc:            "Should allow valid header", | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 			teamHeaderValue: `1234:{ name!="value",foo!~"bar" }`, | 
					
						
							|  |  |  | 			want:            true, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-03 22:02:57 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:            "Should allow valid selector", | 
					
						
							|  |  |  | 			teamHeaderValue: `1234:{ name!="value",foo!~"bar/baz.foo" }`, | 
					
						
							|  |  |  | 			want:            true, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			desc:            "Should return false for incorrect header value", | 
					
						
							|  |  |  | 			teamHeaderValue: `1234:!="value",foo!~"bar" }`, | 
					
						
							|  |  |  | 			want:            false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, tc := range testcases { | 
					
						
							|  |  |  | 		t.Run(tc.desc, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-11-03 22:02:57 +08:00
										 |  |  | 			assert.Equal(t, tc.want, validateLBACHeader(tc.teamHeaderValue)) | 
					
						
							| 
									
										
										
										
											2023-10-27 19:37:37 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2023-07-17 22:27:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mockUpdateDataSource func(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) (*datasources.DataSource, error) | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) (*datasources.DataSource, error) { | 
					
						
							|  |  |  | 	return m.expectedDatasource, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error) { | 
					
						
							|  |  |  | 	return m.expectedDatasources, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) ([]*datasources.DataSource, error) { | 
					
						
							|  |  |  | 	return m.expectedDatasources, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) (*datasources.DataSource, error) { | 
					
						
							|  |  |  | 	return nil, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) (*datasources.DataSource, error) { | 
					
						
							|  |  |  | 	return m.expectedDatasource, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | func (m *dataSourcesServiceMock) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) (*datasources.DataSource, error) { | 
					
						
							| 
									
										
										
										
											2023-07-17 22:27:19 +08:00
										 |  |  | 	if m.mockUpdateDataSource != nil { | 
					
						
							|  |  |  | 		return m.mockUpdateDataSource(ctx, cmd) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | 	return m.expectedDatasource, m.expectedError | 
					
						
							| 
									
										
										
										
											2022-02-11 22:52:14 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | } |