access_token_provider_test.go 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package pluginproxy
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/grafana/grafana/pkg/models"
  7. "github.com/grafana/grafana/pkg/plugins"
  8. . "github.com/smartystreets/goconvey/convey"
  9. "golang.org/x/oauth2"
  10. "golang.org/x/oauth2/jwt"
  11. )
  12. func TestAccessToken(t *testing.T) {
  13. Convey("Plugin with JWT token auth route", t, func() {
  14. pluginRoute := &plugins.AppPluginRoute{
  15. Path: "pathwithjwttoken1",
  16. Url: "https://api.jwt.io/some/path",
  17. Method: "GET",
  18. JwtTokenAuth: &plugins.JwtTokenAuth{
  19. Url: "https://login.server.com/{{.JsonData.tenantId}}/oauth2/token",
  20. Scopes: []string{
  21. "https://www.testapi.com/auth/monitoring.read",
  22. "https://www.testapi.com/auth/cloudplatformprojects.readonly",
  23. },
  24. Params: map[string]string{
  25. "token_uri": "{{.JsonData.tokenUri}}",
  26. "client_email": "{{.JsonData.clientEmail}}",
  27. "private_key": "{{.SecureJsonData.privateKey}}",
  28. },
  29. },
  30. }
  31. templateData := templateData{
  32. JsonData: map[string]interface{}{
  33. "clientEmail": "test@test.com",
  34. "tokenUri": "login.url.com/token",
  35. },
  36. SecureJsonData: map[string]string{
  37. "privateKey": "testkey",
  38. },
  39. }
  40. ds := &models.DataSource{Id: 1, Version: 2}
  41. Convey("should fetch token using jwt private key", func() {
  42. getTokenSource = func(conf *jwt.Config, ctx context.Context) (*oauth2.Token, error) {
  43. return &oauth2.Token{AccessToken: "abc"}, nil
  44. }
  45. provider := newAccessTokenProvider(ds, pluginRoute)
  46. token, err := provider.getJwtAccessToken(context.Background(), templateData)
  47. So(err, ShouldBeNil)
  48. So(token, ShouldEqual, "abc")
  49. })
  50. Convey("should set jwt config values", func() {
  51. getTokenSource = func(conf *jwt.Config, ctx context.Context) (*oauth2.Token, error) {
  52. So(conf.Email, ShouldEqual, "test@test.com")
  53. So(conf.PrivateKey, ShouldResemble, []byte("testkey"))
  54. So(len(conf.Scopes), ShouldEqual, 2)
  55. So(conf.Scopes[0], ShouldEqual, "https://www.testapi.com/auth/monitoring.read")
  56. So(conf.Scopes[1], ShouldEqual, "https://www.testapi.com/auth/cloudplatformprojects.readonly")
  57. So(conf.TokenURL, ShouldEqual, "login.url.com/token")
  58. return &oauth2.Token{AccessToken: "abc"}, nil
  59. }
  60. provider := newAccessTokenProvider(ds, pluginRoute)
  61. _, err := provider.getJwtAccessToken(context.Background(), templateData)
  62. So(err, ShouldBeNil)
  63. })
  64. Convey("should use cached token on second call", func() {
  65. getTokenSource = func(conf *jwt.Config, ctx context.Context) (*oauth2.Token, error) {
  66. return &oauth2.Token{
  67. AccessToken: "abc",
  68. Expiry: time.Now().Add(1 * time.Minute)}, nil
  69. }
  70. provider := newAccessTokenProvider(ds, pluginRoute)
  71. token1, err := provider.getJwtAccessToken(context.Background(), templateData)
  72. So(err, ShouldBeNil)
  73. So(token1, ShouldEqual, "abc")
  74. getTokenSource = func(conf *jwt.Config, ctx context.Context) (*oauth2.Token, error) {
  75. return &oauth2.Token{AccessToken: "error: cache not used"}, nil
  76. }
  77. token2, err := provider.getJwtAccessToken(context.Background(), templateData)
  78. So(err, ShouldBeNil)
  79. So(token2, ShouldEqual, "abc")
  80. })
  81. })
  82. }