| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | package middleware | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2019-04-30 20:42:01 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2019-04-08 19:31:46 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-11-17 23:11:56 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2020-11-25 14:55:22 +08:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2021-07-22 21:49:58 +08:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2021-11-17 23:11:56 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2019-02-06 04:14:23 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 19:08:52 +08:00
										 |  |  | 	"github.com/grafana/grafana-plugin-sdk-go/backend/gtime" | 
					
						
							| 
									
										
										
										
											2019-05-06 15:22:59 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/fs" | 
					
						
							| 
									
										
										
										
											2021-01-12 14:42:32 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/log" | 
					
						
							| 
									
										
										
										
											2019-04-08 19:31:46 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/infra/remotecache" | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/login" | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2019-03-08 22:15:17 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/auth" | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/contexthandler" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/contexthandler/authproxy" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/rendering" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/services/sqlstore" | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2021-10-11 20:30:59 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | func fakeGetTime() func() time.Time { | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 	var timeSeed int64 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	return func() time.Time { | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 		fakeNow := time.Unix(timeSeed, 0) | 
					
						
							|  |  |  | 		timeSeed++ | 
					
						
							|  |  |  | 		return fakeNow | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-19 02:24:23 +08:00
										 |  |  | func TestMiddleWareSecurityHeaders(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should get correct x-xss-protection header", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, "1; mode=block", sc.resp.Header().Get("X-XSS-Protection")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 		cfg.XSSProtectionHeader = true | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-06-19 02:24:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should not get x-xss-protection when disabled", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/").exec() | 
					
						
							|  |  |  | 		assert.Empty(t, sc.resp.Header().Get("X-XSS-Protection")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 		cfg.XSSProtectionHeader = false | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-06-19 02:24:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should add correct Strict-Transport-Security header", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, "max-age=64000", sc.resp.Header().Get("Strict-Transport-Security")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.cfg.StrictTransportSecurityPreload = true | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, "max-age=64000; preload", sc.resp.Header().Get("Strict-Transport-Security")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.cfg.StrictTransportSecuritySubDomains = true | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, "max-age=64000; preload; includeSubDomains", sc.resp.Header().Get("Strict-Transport-Security")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 		cfg.Protocol = setting.HTTPSScheme | 
					
						
							|  |  |  | 		cfg.StrictTransportSecurity = true | 
					
						
							|  |  |  | 		cfg.StrictTransportSecurityMaxAge = 64000 | 
					
						
							| 
									
										
										
										
											2019-06-19 02:24:23 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-01 22:23:36 +08:00
										 |  |  | func TestMiddlewareContext(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	const noCache = "no-cache" | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should add context to injector", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							|  |  |  | 		assert.NotNil(t, sc.context) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "Default middleware should allow get request", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-01 22:23:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should add Cache-Control header for requests to API", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/search").exec() | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		assert.Equal(t, noCache, sc.resp.Header().Get("Cache-Control")) | 
					
						
							|  |  |  | 		assert.Equal(t, noCache, sc.resp.Header().Get("Pragma")) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Equal(t, "-1", sc.resp.Header().Get("Expires")) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2017-07-04 22:33:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should not add Cache-Control header for requests to datasource proxy API", func( | 
					
						
							|  |  |  | 		t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/datasources/proxy/1/test").exec() | 
					
						
							|  |  |  | 		assert.Empty(t, sc.resp.Header().Get("Cache-Control")) | 
					
						
							|  |  |  | 		assert.Empty(t, sc.resp.Header().Get("Pragma")) | 
					
						
							|  |  |  | 		assert.Empty(t, sc.resp.Header().Get("Expires")) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-05-06 15:22:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should add Cache-Control header for requests with HTML response", func( | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		sc.handlerFunc = func(c *models.ReqContext) { | 
					
						
							|  |  |  | 			t.Log("Handler called") | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			data := &dtos.IndexViewData{ | 
					
						
							|  |  |  | 				User:     &dtos.CurrentUser{}, | 
					
						
							|  |  |  | 				Settings: map[string]interface{}{}, | 
					
						
							|  |  |  | 				NavTree:  []*dtos.NavLink{}, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-10 19:29:46 +08:00
										 |  |  | 			t.Log("Calling HTML", "data", data) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			c.HTML(200, "index-template", data) | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 			t.Log("Returned HTML with code 200") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		require.Equal(t, 200, sc.resp.Code) | 
					
						
							|  |  |  | 		assert.Equal(t, noCache, sc.resp.Header().Get("Cache-Control")) | 
					
						
							|  |  |  | 		assert.Equal(t, noCache, sc.resp.Header().Get("Pragma")) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Equal(t, "-1", sc.resp.Header().Get("Expires")) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2017-07-04 22:33:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should add X-Frame-Options header with deny for request when not allowing embedding", func( | 
					
						
							|  |  |  | 		t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/search").exec() | 
					
						
							|  |  |  | 		assert.Equal(t, "deny", sc.resp.Header().Get("X-Frame-Options")) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-05-06 15:56:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "middleware should not add X-Frame-Options header for request when allowing embedding", func( | 
					
						
							|  |  |  | 		t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/api/search").exec() | 
					
						
							|  |  |  | 		assert.Empty(t, sc.resp.Header().Get("X-Frame-Options")) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 		cfg.AllowEmbedding = true | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-05-06 15:56:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "Invalid api key", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.apiKey = "invalid_key_test" | 
					
						
							|  |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Empty(t, sc.resp.Header().Get("Set-Cookie")) | 
					
						
							|  |  |  | 		assert.Equal(t, 401, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		assert.Equal(t, contexthandler.InvalidAPIKey, sc.respJson["message"]) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	middlewareScenario(t, "Valid API key", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		const orgID int64 = 12 | 
					
						
							|  |  |  | 		keyhash, err := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bus.AddHandler("test", func(query *models.GetApiKeyByNameQuery) error { | 
					
						
							|  |  |  | 			query.Result = &models.ApiKey{OrgId: orgID, Role: models.ROLE_EDITOR, Key: keyhash} | 
					
						
							|  |  |  | 			return nil | 
					
						
							| 
									
										
										
										
											2015-06-30 15:37:52 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").withValidApiKey().exec() | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		require.Equal(t, 200, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 		assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							|  |  |  | 		assert.Equal(t, models.ROLE_EDITOR, sc.context.OrgRole) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	middlewareScenario(t, "Valid API key, but does not match DB hash", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 		const keyhash = "Something_not_matching" | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		bus.AddHandler("test", func(query *models.GetApiKeyByNameQuery) error { | 
					
						
							|  |  |  | 			query.Result = &models.ApiKey{OrgId: 12, Role: models.ROLE_EDITOR, Key: keyhash} | 
					
						
							|  |  |  | 			return nil | 
					
						
							| 
									
										
										
										
											2015-05-02 04:26:16 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").withValidApiKey().exec() | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Equal(t, 401, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		assert.Equal(t, contexthandler.InvalidAPIKey, sc.respJson["message"]) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	middlewareScenario(t, "Valid API key, but expired", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 		sc.contextHandler.GetTime = fakeGetTime() | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		keyhash, err := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bus.AddHandler("test", func(query *models.GetApiKeyByNameQuery) error { | 
					
						
							|  |  |  | 			// api key expired one second before
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			expires := sc.contextHandler.GetTime().Add(-1 * time.Second).Unix() | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			query.Result = &models.ApiKey{OrgId: 12, Role: models.ROLE_EDITOR, Key: keyhash, | 
					
						
							|  |  |  | 				Expires: &expires} | 
					
						
							|  |  |  | 			return nil | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").withValidApiKey().exec() | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Equal(t, 401, sc.resp.Code) | 
					
						
							|  |  |  | 		assert.Equal(t, "Expired API key", sc.respJson["message"]) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	middlewareScenario(t, "Non-expired auth token in cookie which is not being rotated", func( | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		const userID int64 = 12 | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.withTokenSessionCookie("token") | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 		bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			query.Result = &models.SignedInUser{OrgId: 2, UserId: userID} | 
					
						
							|  |  |  | 			return nil | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) { | 
					
						
							|  |  |  | 			return &models.UserToken{ | 
					
						
							|  |  |  | 				UserId:        userID, | 
					
						
							|  |  |  | 				UnhashedToken: unhashedToken, | 
					
						
							|  |  |  | 			}, nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		require.NotNil(t, sc.context) | 
					
						
							|  |  |  | 		require.NotNil(t, sc.context.UserToken) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 		assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 		assert.Equal(t, userID, sc.context.UserToken.UserId) | 
					
						
							|  |  |  | 		assert.Equal(t, "token", sc.context.UserToken.UnhashedToken) | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		assert.Empty(t, sc.resp.Header().Get("Set-Cookie")) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 	middlewareScenario(t, "Non-expired auth token in cookie which is being rotated", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		const userID int64 = 12 | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.withTokenSessionCookie("token") | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 		bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			query.Result = &models.SignedInUser{OrgId: 2, UserId: userID} | 
					
						
							|  |  |  | 			return nil | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) { | 
					
						
							|  |  |  | 			return &models.UserToken{ | 
					
						
							|  |  |  | 				UserId:        userID, | 
					
						
							|  |  |  | 				UnhashedToken: "", | 
					
						
							|  |  |  | 			}, nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.userAuthTokenService.TryRotateTokenProvider = func(ctx context.Context, userToken *models.UserToken, | 
					
						
							|  |  |  | 			clientIP net.IP, userAgent string) (bool, error) { | 
					
						
							|  |  |  | 			userToken.UnhashedToken = "rotated" | 
					
						
							|  |  |  | 			return true, nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		maxAge := int(sc.cfg.LoginMaxLifetime.Seconds()) | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sameSiteModes := []http.SameSite{ | 
					
						
							|  |  |  | 			http.SameSiteNoneMode, | 
					
						
							|  |  |  | 			http.SameSiteLaxMode, | 
					
						
							|  |  |  | 			http.SameSiteStrictMode, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, sameSiteMode := range sameSiteModes { | 
					
						
							|  |  |  | 			t.Run(fmt.Sprintf("Same site mode %d", sameSiteMode), func(t *testing.T) { | 
					
						
							|  |  |  | 				origCookieSameSiteMode := setting.CookieSameSiteMode | 
					
						
							|  |  |  | 				t.Cleanup(func() { | 
					
						
							|  |  |  | 					setting.CookieSameSiteMode = origCookieSameSiteMode | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				setting.CookieSameSiteMode = sameSiteMode | 
					
						
							| 
									
										
										
										
											2019-02-06 04:14:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-06 22:56:19 +08:00
										 |  |  | 				expectedCookiePath := "/" | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 				if len(sc.cfg.AppSubURL) > 0 { | 
					
						
							|  |  |  | 					expectedCookiePath = sc.cfg.AppSubURL | 
					
						
							| 
									
										
										
										
											2020-04-06 22:56:19 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 				expectedCookie := &http.Cookie{ | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 					Name:     sc.cfg.LoginCookieName, | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 					Value:    "rotated", | 
					
						
							| 
									
										
										
										
											2020-04-06 22:56:19 +08:00
										 |  |  | 					Path:     expectedCookiePath, | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 					HttpOnly: true, | 
					
						
							| 
									
										
										
										
											2020-09-14 21:57:38 +08:00
										 |  |  | 					MaxAge:   maxAge, | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 					Secure:   setting.CookieSecure, | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 					SameSite: sameSiteMode, | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 14:10:08 +08:00
										 |  |  | 				sc.fakeReq("GET", "/").exec() | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 				assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 				assert.Equal(t, userID, sc.context.UserToken.UserId) | 
					
						
							|  |  |  | 				assert.Equal(t, "rotated", sc.context.UserToken.UnhashedToken) | 
					
						
							|  |  |  | 				assert.Equal(t, expectedCookie.String(), sc.resp.Header().Get("Set-Cookie")) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		t.Run("Should not set cookie with SameSite attribute when setting.CookieSameSiteDisabled is true", func(t *testing.T) { | 
					
						
							|  |  |  | 			origCookieSameSiteDisabled := setting.CookieSameSiteDisabled | 
					
						
							|  |  |  | 			origCookieSameSiteMode := setting.CookieSameSiteMode | 
					
						
							|  |  |  | 			t.Cleanup(func() { | 
					
						
							|  |  |  | 				setting.CookieSameSiteDisabled = origCookieSameSiteDisabled | 
					
						
							|  |  |  | 				setting.CookieSameSiteMode = origCookieSameSiteMode | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			setting.CookieSameSiteDisabled = true | 
					
						
							|  |  |  | 			setting.CookieSameSiteMode = http.SameSiteLaxMode | 
					
						
							| 
									
										
										
										
											2020-01-15 00:41:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			expectedCookiePath := "/" | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 			if len(sc.cfg.AppSubURL) > 0 { | 
					
						
							|  |  |  | 				expectedCookiePath = sc.cfg.AppSubURL | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			expectedCookie := &http.Cookie{ | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 				Name:     sc.cfg.LoginCookieName, | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				Value:    "rotated", | 
					
						
							|  |  |  | 				Path:     expectedCookiePath, | 
					
						
							|  |  |  | 				HttpOnly: true, | 
					
						
							|  |  |  | 				MaxAge:   maxAge, | 
					
						
							|  |  |  | 				Secure:   setting.CookieSecure, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-01-15 00:41:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/").exec() | 
					
						
							|  |  |  | 			assert.Equal(t, expectedCookie.String(), sc.resp.Header().Get("Set-Cookie")) | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "Invalid/expired auth token in cookie", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.withTokenSessionCookie("token") | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.userAuthTokenService.LookupTokenProvider = func(ctx context.Context, unhashedToken string) (*models.UserToken, error) { | 
					
						
							|  |  |  | 			return nil, models.ErrUserTokenNotFound | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							| 
									
										
										
										
											2019-02-05 06:44:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.False(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 		assert.Equal(t, int64(0), sc.context.UserId) | 
					
						
							|  |  |  | 		assert.Nil(t, sc.context.UserToken) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 	middlewareScenario(t, "When anonymous access is enabled", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-01-07 18:36:13 +08:00
										 |  |  | 		org, err := sc.sqlStore.CreateOrgWithMember(sc.cfg.AnonymousOrgName, 1) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		sc.fakeReq("GET", "/").exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert.Equal(t, int64(0), sc.context.UserId) | 
					
						
							| 
									
										
										
										
											2021-01-07 18:36:13 +08:00
										 |  |  | 		assert.Equal(t, org.Id, sc.context.OrgId) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		assert.Equal(t, models.ROLE_EDITOR, sc.context.OrgRole) | 
					
						
							|  |  |  | 		assert.False(t, sc.context.IsSignedIn) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 		cfg.AnonymousEnabled = true | 
					
						
							|  |  |  | 		cfg.AnonymousOrgName = "test" | 
					
						
							|  |  |  | 		cfg.AnonymousOrgRole = string(models.ROLE_EDITOR) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("auth_proxy", func(t *testing.T) { | 
					
						
							|  |  |  | 		const userID int64 = 33 | 
					
						
							|  |  |  | 		const orgID int64 = 4 | 
					
						
							| 
									
										
										
										
											2021-07-22 21:49:58 +08:00
										 |  |  | 		const defaultOrgId int64 = 1 | 
					
						
							|  |  |  | 		const orgRole = "Admin" | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		configure := func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			cfg.AuthProxyEnabled = true | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = true | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = true | 
					
						
							|  |  |  | 			cfg.AuthProxyHeaderName = "X-WEBAUTH-USER" | 
					
						
							|  |  |  | 			cfg.AuthProxyHeaderProperty = "username" | 
					
						
							| 
									
										
										
										
											2021-07-22 21:49:58 +08:00
										 |  |  | 			cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS", "Role": "X-WEBAUTH-ROLE"} | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		const hdrName = "markelog" | 
					
						
							|  |  |  | 		const group = "grafana-core-team" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should not sync the user if it's in the cache", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				query.Result = &models.SignedInUser{OrgId: orgID, UserId: query.UserId} | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 16:32:06 +08:00
										 |  |  | 			h, err := authproxy.HashCacheKey(hdrName + "-" + group) | 
					
						
							|  |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			key := fmt.Sprintf(authproxy.CachePrefix, h) | 
					
						
							|  |  |  | 			err = sc.remoteCacheService.Set(key, userID, 0) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.req.Header.Set("X-WEBAUTH-GROUPS", group) | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, configure) | 
					
						
							| 
									
										
										
										
											2015-05-02 18:06:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should respect auto signup option", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			var actualAuthProxyAutoSignUp *bool = nil | 
					
						
							| 
									
										
										
										
											2018-12-19 11:16:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				actualAuthProxyAutoSignUp = &cmd.SignupAllowed | 
					
						
							|  |  |  | 				return login.ErrInvalidCredentials | 
					
						
							| 
									
										
										
										
											2018-12-19 11:16:29 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2019-07-01 19:29:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.False(t, *actualAuthProxyAutoSignUp) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			assert.Equal(t, 407, sc.resp.Code) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.Nil(t, sc.context) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = false | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2019-07-01 19:29:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should create an user from a header", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				if query.UserId > 0 { | 
					
						
							|  |  |  | 					query.Result = &models.SignedInUser{OrgId: orgID, UserId: userID} | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return models.ErrUserNotFound | 
					
						
							| 
									
										
										
										
											2019-07-01 19:29:41 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2018-12-19 11:16:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2018-12-19 11:16:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = true | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-12-19 11:16:29 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-22 21:49:58 +08:00
										 |  |  | 		middlewareScenario(t, "Should assign role from header to default org", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 			var storedRoleInfo map[int64]models.RoleType = nil | 
					
						
							|  |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							|  |  |  | 				if query.UserId > 0 { | 
					
						
							|  |  |  | 					query.Result = &models.SignedInUser{OrgId: defaultOrgId, UserId: userID, OrgRole: storedRoleInfo[defaultOrgId]} | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return models.ErrUserNotFound | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				storedRoleInfo = cmd.ExternalUser.OrgRoles | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							|  |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							|  |  |  | 			sc.req.Header.Set("X-WEBAUTH-ROLE", orgRole) | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, defaultOrgId, sc.context.OrgId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgRole, string(sc.context.OrgRole)) | 
					
						
							|  |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = true | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		middlewareScenario(t, "Should NOT assign role from header to non-default org", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 			var storedRoleInfo map[int64]models.RoleType = nil | 
					
						
							|  |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							|  |  |  | 				if query.UserId > 0 { | 
					
						
							|  |  |  | 					query.Result = &models.SignedInUser{OrgId: orgID, UserId: userID, OrgRole: storedRoleInfo[orgID]} | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return models.ErrUserNotFound | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				storedRoleInfo = cmd.ExternalUser.OrgRoles | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							|  |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							|  |  |  | 			sc.req.Header.Set("X-WEBAUTH-ROLE", "Admin") | 
					
						
							|  |  |  | 			sc.req.Header.Set("X-Grafana-Org-Id", strconv.FormatInt(orgID, 10)) | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// For non-default org, the user role should be empty
 | 
					
						
							|  |  |  | 			assert.Equal(t, "", string(sc.context.OrgRole)) | 
					
						
							|  |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = true | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 23:11:56 +08:00
										 |  |  | 		middlewareScenario(t, "Should use organisation specified by targetOrgId parameter", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							|  |  |  | 				if query.UserId > 0 { | 
					
						
							|  |  |  | 					query.Result = &models.SignedInUser{OrgId: query.OrgId, UserId: userID} | 
					
						
							|  |  |  | 					return nil | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return models.ErrUserNotFound | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			targetOrgID := 123 | 
					
						
							|  |  |  | 			sc.fakeReq("GET", fmt.Sprintf("/?targetOrgId=%d", targetOrgID)) | 
					
						
							|  |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, int64(targetOrgID), sc.context.OrgId) | 
					
						
							|  |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							|  |  |  | 			cfg.AuthProxyAutoSignUp = true | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		middlewareScenario(t, "Request body should not be read in default context handler", func(t *testing.T, sc *scenarioContext) { | 
					
						
							|  |  |  | 			sc.fakeReq("POST", "/?targetOrgId=123") | 
					
						
							|  |  |  | 			body := "key=value" | 
					
						
							|  |  |  | 			sc.req.Body = io.NopCloser(strings.NewReader(body)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.handlerFunc = func(c *models.ReqContext) { | 
					
						
							|  |  |  | 				t.Log("Handler called") | 
					
						
							|  |  |  | 				defer func() { | 
					
						
							|  |  |  | 					err := c.Req.Body.Close() | 
					
						
							|  |  |  | 					require.NoError(t, err) | 
					
						
							|  |  |  | 				}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				bodyAfterHandler, e := io.ReadAll(c.Req.Body) | 
					
						
							|  |  |  | 				require.NoError(t, e) | 
					
						
							|  |  |  | 				require.Equal(t, body, string(bodyAfterHandler)) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							|  |  |  | 			sc.req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | 
					
						
							|  |  |  | 			sc.req.Header.Set("Content-Length", strconv.Itoa(len(body))) | 
					
						
							|  |  |  | 			sc.m.Post("/", sc.defaultHandler) | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should get an existing user from header", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			const userID int64 = 12 | 
					
						
							|  |  |  | 			const orgID int64 = 2 | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				query.Result = &models.SignedInUser{OrgId: orgID, UserId: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-03-24 03:50:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should allow the request from whitelist IP", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				query.Result = &models.SignedInUser{OrgId: orgID, UserId: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.req.RemoteAddr = "[2001::23]:12345" | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.True(t, sc.context.IsSignedIn) | 
					
						
							|  |  |  | 			assert.Equal(t, userID, sc.context.UserId) | 
					
						
							|  |  |  | 			assert.Equal(t, orgID, sc.context.OrgId) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.AuthProxyWhitelist = "192.168.1.0/24, 2001::0/120" | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		middlewareScenario(t, "Should not allow the request from whitelisted IP", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("test", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				query.Result = &models.SignedInUser{OrgId: orgID, UserId: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				cmd.Result = &models.User{Id: userID} | 
					
						
							|  |  |  | 				return nil | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2018-03-24 03:50:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.req.RemoteAddr = "[2001::23]:12345" | 
					
						
							|  |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.Equal(t, 407, sc.resp.Code) | 
					
						
							|  |  |  | 			assert.Nil(t, sc.context) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, func(cfg *setting.Cfg) { | 
					
						
							|  |  |  | 			configure(cfg) | 
					
						
							|  |  |  | 			cfg.AuthProxyWhitelist = "8.8.8.8" | 
					
						
							|  |  |  | 			cfg.LDAPEnabled = false | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2016-02-23 21:22:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should return 407 status code if LDAP says no", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			bus.AddHandler("LDAP", func(cmd *models.UpsertUserCommand) error { | 
					
						
							|  |  |  | 				return errors.New("Do not add user") | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.Equal(t, 407, sc.resp.Code) | 
					
						
							|  |  |  | 			assert.Nil(t, sc.context) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, configure) | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		middlewareScenario(t, "Should return 407 status code if there is cache mishap", func(t *testing.T, sc *scenarioContext) { | 
					
						
							| 
									
										
										
										
											2021-05-19 00:24:42 +08:00
										 |  |  | 			bus.AddHandlerCtx("Do not have the user", func(ctx context.Context, query *models.GetSignedInUserQuery) error { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 				return errors.New("Do not add user") | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.fakeReq("GET", "/") | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName) | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			sc.exec() | 
					
						
							| 
									
										
										
										
											2019-08-21 01:13:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 			assert.Equal(t, 407, sc.resp.Code) | 
					
						
							|  |  |  | 			assert.Nil(t, sc.context) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		}, configure) | 
					
						
							| 
									
										
										
										
											2015-05-01 17:55:59 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | func middlewareScenario(t *testing.T, desc string, fn scenarioFunc, cbs ...func(*setting.Cfg)) { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	t.Helper() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run(desc, func(t *testing.T) { | 
					
						
							|  |  |  | 		t.Cleanup(bus.ClearBusHandlers) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 14:42:32 +08:00
										 |  |  | 		logger := log.New("test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		loginMaxLifetime, err := gtime.ParseDuration("30d") | 
					
						
							| 
									
										
										
										
											2020-11-03 02:26:19 +08:00
										 |  |  | 		require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		cfg := setting.NewCfg() | 
					
						
							|  |  |  | 		cfg.LoginCookieName = "grafana_session" | 
					
						
							|  |  |  | 		cfg.LoginMaxLifetime = loginMaxLifetime | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		// Required when rendering errors
 | 
					
						
							|  |  |  | 		cfg.ErrTemplateName = "error-template" | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		for _, cb := range cbs { | 
					
						
							|  |  |  | 			cb(cfg) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-06 04:14:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc := &scenarioContext{t: t, cfg: cfg} | 
					
						
							| 
									
										
										
										
											2019-01-23 19:41:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-18 00:31:44 +08:00
										 |  |  | 		viewsPath, err := filepath.Abs("../../public/views") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		exists, err := fs.Exists(viewsPath) | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 		require.Truef(t, exists, "Views directory should exist at %q", viewsPath) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 20:30:59 +08:00
										 |  |  | 		sc.m = web.New() | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.m.Use(AddDefaultResponseHeaders(cfg)) | 
					
						
							| 
									
										
										
										
											2021-08-10 15:03:22 +08:00
										 |  |  | 		sc.m.UseMiddleware(AddCSPHeader(cfg, logger)) | 
					
						
							| 
									
										
										
										
											2021-10-11 20:30:59 +08:00
										 |  |  | 		sc.m.UseMiddleware(web.Renderer(viewsPath, "[[", "]]")) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		ctxHdlr := getContextHandler(t, cfg) | 
					
						
							| 
									
										
										
										
											2021-01-07 18:36:13 +08:00
										 |  |  | 		sc.sqlStore = ctxHdlr.SQLStore | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.contextHandler = ctxHdlr | 
					
						
							|  |  |  | 		sc.m.Use(ctxHdlr.Middleware) | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		sc.m.Use(OrgRedirect(sc.cfg)) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.userAuthTokenService = ctxHdlr.AuthTokenService.(*auth.FakeUserAuthTokenService) | 
					
						
							| 
									
										
										
										
											2021-03-31 23:40:44 +08:00
										 |  |  | 		sc.jwtAuthService = ctxHdlr.JWTAuthService.(*models.FakeJWTService) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 		sc.remoteCacheService = ctxHdlr.RemoteCache | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 14:47:03 +08:00
										 |  |  | 		sc.defaultHandler = func(c *models.ReqContext) { | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 			require.NotNil(t, c) | 
					
						
							|  |  |  | 			t.Log("Default HTTP handler called") | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 			sc.context = c | 
					
						
							|  |  |  | 			if sc.handlerFunc != nil { | 
					
						
							|  |  |  | 				sc.handlerFunc(sc.context) | 
					
						
							| 
									
										
										
										
											2020-01-15 20:03:12 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 				t.Log("Returning JSON OK") | 
					
						
							| 
									
										
										
										
											2020-11-17 18:51:31 +08:00
										 |  |  | 				resp := make(map[string]interface{}) | 
					
						
							|  |  |  | 				resp["message"] = "OK" | 
					
						
							|  |  |  | 				c.JSON(200, resp) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-05-02 18:06:58 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sc.m.Get("/", sc.defaultHandler) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 18:09:32 +08:00
										 |  |  | 		fn(t, sc) | 
					
						
							| 
									
										
										
										
											2015-05-02 15:24:56 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-18 00:31:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHandler { | 
					
						
							| 
									
										
										
										
											2020-12-03 15:28:54 +08:00
										 |  |  | 	t.Helper() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	sqlStore := sqlstore.InitTestDB(t) | 
					
						
							|  |  |  | 	if cfg == nil { | 
					
						
							|  |  |  | 		cfg = setting.NewCfg() | 
					
						
							| 
									
										
										
										
											2020-11-03 02:26:19 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	cfg.RemoteCacheOptions = &setting.RemoteCacheOptions{ | 
					
						
							|  |  |  | 		Name: "database", | 
					
						
							| 
									
										
										
										
											2020-02-18 00:31:44 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 21:11:22 +08:00
										 |  |  | 	remoteCacheSvc, err := remotecache.ProvideService(cfg, sqlStore) | 
					
						
							|  |  |  | 	require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | 	userAuthTokenSvc := auth.NewFakeUserAuthTokenService() | 
					
						
							|  |  |  | 	renderSvc := &fakeRenderService{} | 
					
						
							| 
									
										
										
										
											2021-03-31 23:40:44 +08:00
										 |  |  | 	authJWTSvc := models.NewFakeJWTService() | 
					
						
							| 
									
										
										
										
											2021-08-25 21:11:22 +08:00
										 |  |  | 	return contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, sqlStore) | 
					
						
							| 
									
										
										
										
											2020-02-18 00:31:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | type fakeRenderService struct { | 
					
						
							|  |  |  | 	rendering.Service | 
					
						
							| 
									
										
										
										
											2020-02-18 00:31:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 18:44:44 +08:00
										 |  |  | func (s *fakeRenderService) Init() error { | 
					
						
							| 
									
										
										
										
											2020-06-30 01:15:11 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } |