ds_proxy_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package pluginproxy
  2. import (
  3. "net/http"
  4. "net/url"
  5. "testing"
  6. macaron "gopkg.in/macaron.v1"
  7. "github.com/grafana/grafana/pkg/components/simplejson"
  8. "github.com/grafana/grafana/pkg/middleware"
  9. m "github.com/grafana/grafana/pkg/models"
  10. "github.com/grafana/grafana/pkg/plugins"
  11. "github.com/grafana/grafana/pkg/setting"
  12. "github.com/grafana/grafana/pkg/util"
  13. . "github.com/smartystreets/goconvey/convey"
  14. )
  15. func TestDSRouteRule(t *testing.T) {
  16. Convey("DataSourceProxy", t, func() {
  17. Convey("Plugin with routes", func() {
  18. plugin := &plugins.DataSourcePlugin{
  19. Routes: []*plugins.AppPluginRoute{
  20. {
  21. Path: "api/v4/",
  22. Url: "https://www.google.com",
  23. ReqRole: m.ROLE_EDITOR,
  24. Headers: []plugins.AppPluginRouteHeader{
  25. {Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"},
  26. },
  27. },
  28. {
  29. Path: "api/admin",
  30. Url: "https://www.google.com",
  31. ReqRole: m.ROLE_ADMIN,
  32. Headers: []plugins.AppPluginRouteHeader{
  33. {Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"},
  34. },
  35. },
  36. {
  37. Path: "api/anon",
  38. Url: "https://www.google.com",
  39. Headers: []plugins.AppPluginRouteHeader{
  40. {Name: "x-header", Content: "my secret {{.SecureJsonData.key}}"},
  41. },
  42. },
  43. },
  44. }
  45. setting.SecretKey = "password"
  46. key, _ := util.Encrypt([]byte("123"), "password")
  47. ds := &m.DataSource{
  48. JsonData: simplejson.NewFromAny(map[string]interface{}{
  49. "clientId": "asd",
  50. }),
  51. SecureJsonData: map[string][]byte{
  52. "key": key,
  53. },
  54. }
  55. req, _ := http.NewRequest("GET", "http://localhost/asd", nil)
  56. ctx := &middleware.Context{
  57. Context: &macaron.Context{
  58. Req: macaron.Request{Request: req},
  59. },
  60. SignedInUser: &m.SignedInUser{OrgRole: m.ROLE_EDITOR},
  61. }
  62. Convey("When matching route path", func() {
  63. proxy := NewDataSourceProxy(ds, plugin, ctx, "api/v4/some/method")
  64. proxy.route = plugin.Routes[0]
  65. proxy.applyRoute(req)
  66. Convey("should add headers and update url", func() {
  67. So(req.URL.String(), ShouldEqual, "https://www.google.com/some/method")
  68. So(req.Header.Get("x-header"), ShouldEqual, "my secret 123")
  69. })
  70. })
  71. Convey("Validating request", func() {
  72. Convey("plugin route with valid role", func() {
  73. proxy := NewDataSourceProxy(ds, plugin, ctx, "api/v4/some/method")
  74. err := proxy.validateRequest()
  75. So(err, ShouldBeNil)
  76. })
  77. Convey("plugin route with admin role and user is editor", func() {
  78. proxy := NewDataSourceProxy(ds, plugin, ctx, "api/admin")
  79. err := proxy.validateRequest()
  80. So(err, ShouldNotBeNil)
  81. })
  82. Convey("plugin route with admin role and user is admin", func() {
  83. ctx.SignedInUser.OrgRole = m.ROLE_ADMIN
  84. proxy := NewDataSourceProxy(ds, plugin, ctx, "api/admin")
  85. err := proxy.validateRequest()
  86. So(err, ShouldBeNil)
  87. })
  88. })
  89. })
  90. Convey("When proxying graphite", func() {
  91. plugin := &plugins.DataSourcePlugin{}
  92. ds := &m.DataSource{Url: "htttp://graphite:8080", Type: m.DS_GRAPHITE}
  93. ctx := &middleware.Context{}
  94. proxy := NewDataSourceProxy(ds, plugin, ctx, "/render")
  95. requestUrl, _ := url.Parse("http://grafana.com/sub")
  96. req := http.Request{URL: requestUrl}
  97. proxy.getDirector()(&req)
  98. Convey("Can translate request url and path", func() {
  99. So(req.URL.Host, ShouldEqual, "graphite:8080")
  100. So(req.URL.Path, ShouldEqual, "/render")
  101. })
  102. })
  103. Convey("When proxying InfluxDB", func() {
  104. plugin := &plugins.DataSourcePlugin{}
  105. ds := &m.DataSource{
  106. Type: m.DS_INFLUXDB_08,
  107. Url: "http://influxdb:8083",
  108. Database: "site",
  109. User: "user",
  110. Password: "password",
  111. }
  112. ctx := &middleware.Context{}
  113. proxy := NewDataSourceProxy(ds, plugin, ctx, "")
  114. requestUrl, _ := url.Parse("http://grafana.com/sub")
  115. req := http.Request{URL: requestUrl}
  116. proxy.getDirector()(&req)
  117. Convey("Should add db to url", func() {
  118. So(req.URL.Path, ShouldEqual, "/db/site/")
  119. })
  120. Convey("Should add username and password", func() {
  121. queryVals := req.URL.Query()
  122. So(queryVals["u"][0], ShouldEqual, "user")
  123. So(queryVals["p"][0], ShouldEqual, "password")
  124. })
  125. })
  126. Convey("When proxying a data source with no keepCookies specified", func() {
  127. plugin := &plugins.DataSourcePlugin{}
  128. json, _ := simplejson.NewJson([]byte(`{"keepCookies": []}`))
  129. ds := &m.DataSource{
  130. Type: m.DS_GRAPHITE,
  131. Url: "http://graphite:8086",
  132. JsonData: json,
  133. }
  134. ctx := &middleware.Context{}
  135. proxy := NewDataSourceProxy(ds, plugin, ctx, "")
  136. requestUrl, _ := url.Parse("http://grafana.com/sub")
  137. req := http.Request{URL: requestUrl, Header: make(http.Header)}
  138. cookies := "grafana_user=admin; grafana_remember=99; grafana_sess=11; JSESSION_ID=test"
  139. req.Header.Set("Cookie", cookies)
  140. proxy.getDirector()(&req)
  141. Convey("Should clear all cookies", func() {
  142. So(req.Header.Get("Cookie"), ShouldEqual, "")
  143. })
  144. })
  145. Convey("When proxying a data source with keep cookies specified", func() {
  146. plugin := &plugins.DataSourcePlugin{}
  147. json, _ := simplejson.NewJson([]byte(`{"keepCookies": ["JSESSION_ID"]}`))
  148. ds := &m.DataSource{
  149. Type: m.DS_GRAPHITE,
  150. Url: "http://graphite:8086",
  151. JsonData: json,
  152. }
  153. ctx := &middleware.Context{}
  154. proxy := NewDataSourceProxy(ds, plugin, ctx, "")
  155. requestUrl, _ := url.Parse("http://grafana.com/sub")
  156. req := http.Request{URL: requestUrl, Header: make(http.Header)}
  157. cookies := "grafana_user=admin; grafana_remember=99; grafana_sess=11; JSESSION_ID=test"
  158. req.Header.Set("Cookie", cookies)
  159. proxy.getDirector()(&req)
  160. Convey("Should keep named cookies", func() {
  161. So(req.Header.Get("Cookie"), ShouldEqual, "JSESSION_ID=test")
  162. })
  163. })
  164. Convey("When interpolating string", func() {
  165. data := templateData{
  166. SecureJsonData: map[string]string{
  167. "Test": "0asd+asd",
  168. },
  169. }
  170. interpolated, err := interpolateString("{{.SecureJsonData.Test}}", data)
  171. So(err, ShouldBeNil)
  172. So(interpolated, ShouldEqual, "0asd+asd")
  173. })
  174. })
  175. }