auth_proxy_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package authproxy
  2. import (
  3. "encoding/base32"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "testing"
  8. "github.com/grafana/grafana/pkg/bus"
  9. "github.com/grafana/grafana/pkg/infra/remotecache"
  10. "github.com/grafana/grafana/pkg/models"
  11. "github.com/grafana/grafana/pkg/services/ldap"
  12. "github.com/grafana/grafana/pkg/services/multildap"
  13. "github.com/grafana/grafana/pkg/setting"
  14. . "github.com/smartystreets/goconvey/convey"
  15. "gopkg.in/macaron.v1"
  16. )
  17. type TestMultiLDAP struct {
  18. multildap.MultiLDAP
  19. ID int64
  20. userCalled bool
  21. loginCalled bool
  22. }
  23. func (stub *TestMultiLDAP) Login(query *models.LoginUserQuery) (
  24. *models.ExternalUserInfo, error,
  25. ) {
  26. stub.loginCalled = true
  27. result := &models.ExternalUserInfo{
  28. UserId: stub.ID,
  29. }
  30. return result, nil
  31. }
  32. func (stub *TestMultiLDAP) User(login string) (
  33. *models.ExternalUserInfo,
  34. ldap.ServerConfig,
  35. error,
  36. ) {
  37. stub.userCalled = true
  38. result := &models.ExternalUserInfo{
  39. UserId: stub.ID,
  40. }
  41. return result, ldap.ServerConfig{}, nil
  42. }
  43. func prepareMiddleware(t *testing.T, req *http.Request, store *remotecache.RemoteCache) *AuthProxy {
  44. t.Helper()
  45. ctx := &models.ReqContext{
  46. Context: &macaron.Context{
  47. Req: macaron.Request{
  48. Request: req,
  49. },
  50. },
  51. }
  52. auth := New(&Options{
  53. Store: store,
  54. Ctx: ctx,
  55. OrgID: 4,
  56. })
  57. return auth
  58. }
  59. func TestMiddlewareContext(t *testing.T) {
  60. Convey("auth_proxy helper", t, func() {
  61. req, _ := http.NewRequest("POST", "http://example.com", nil)
  62. setting.AuthProxyHeaderName = "X-Killa"
  63. store := remotecache.NewFakeStore(t)
  64. name := "markelog"
  65. req.Header.Add(setting.AuthProxyHeaderName, name)
  66. Convey("when the cache only contains the main header", func() {
  67. Convey("with a simple cache key", func() {
  68. // Set cache key
  69. key := fmt.Sprintf(CachePrefix, base32.StdEncoding.EncodeToString([]byte(name)))
  70. store.Set(key, int64(33), 0)
  71. // Set up the middleware
  72. auth := prepareMiddleware(t, req, store)
  73. id, err := auth.Login()
  74. So(auth.getKey(), ShouldEqual, "auth-proxy-sync-ttl:NVQXE23FNRXWO===")
  75. So(err, ShouldBeNil)
  76. So(id, ShouldEqual, 33)
  77. })
  78. Convey("when the cache key contains additional headers", func() {
  79. setting.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS"}
  80. group := "grafana-core-team"
  81. req.Header.Add("X-WEBAUTH-GROUPS", group)
  82. key := fmt.Sprintf(CachePrefix, base32.StdEncoding.EncodeToString([]byte(name+"-"+group)))
  83. store.Set(key, int64(33), 0)
  84. auth := prepareMiddleware(t, req, store)
  85. id, err := auth.Login()
  86. So(auth.getKey(), ShouldEqual, "auth-proxy-sync-ttl:NVQXE23FNRXWOLLHOJQWMYLOMEWWG33SMUWXIZLBNU======")
  87. So(err, ShouldBeNil)
  88. So(id, ShouldEqual, 33)
  89. })
  90. Convey("when the does not exist", func() {
  91. })
  92. })
  93. Convey("LDAP", func() {
  94. Convey("logs in via LDAP", func() {
  95. bus.AddHandler("test", func(cmd *models.UpsertUserCommand) error {
  96. cmd.Result = &models.User{
  97. Id: 42,
  98. }
  99. return nil
  100. })
  101. isLDAPEnabled = func() bool {
  102. return true
  103. }
  104. stub := &TestMultiLDAP{
  105. ID: 42,
  106. }
  107. getLDAPConfig = func() (*ldap.Config, error) {
  108. config := &ldap.Config{
  109. Servers: []*ldap.ServerConfig{
  110. {
  111. SearchBaseDNs: []string{"BaseDNHere"},
  112. },
  113. },
  114. }
  115. return config, nil
  116. }
  117. newLDAP = func(servers []*ldap.ServerConfig) multildap.IMultiLDAP {
  118. return stub
  119. }
  120. defer func() {
  121. newLDAP = multildap.New
  122. isLDAPEnabled = ldap.IsEnabled
  123. getLDAPConfig = ldap.GetConfig
  124. }()
  125. store := remotecache.NewFakeStore(t)
  126. auth := prepareMiddleware(t, req, store)
  127. id, err := auth.Login()
  128. So(err, ShouldBeNil)
  129. So(id, ShouldEqual, 42)
  130. So(stub.userCalled, ShouldEqual, true)
  131. })
  132. Convey("gets nice error if ldap is enabled but not configured", func() {
  133. isLDAPEnabled = func() bool {
  134. return true
  135. }
  136. getLDAPConfig = func() (*ldap.Config, error) {
  137. return nil, errors.New("Something went wrong")
  138. }
  139. defer func() {
  140. newLDAP = multildap.New
  141. isLDAPEnabled = ldap.IsEnabled
  142. getLDAPConfig = ldap.GetConfig
  143. }()
  144. store := remotecache.NewFakeStore(t)
  145. auth := prepareMiddleware(t, req, store)
  146. stub := &TestMultiLDAP{
  147. ID: 42,
  148. }
  149. newLDAP = func(servers []*ldap.ServerConfig) multildap.IMultiLDAP {
  150. return stub
  151. }
  152. id, err := auth.Login()
  153. So(err, ShouldNotBeNil)
  154. So(err.Error(), ShouldContainSubstring, "Failed to get the user")
  155. So(id, ShouldNotEqual, 42)
  156. So(stub.loginCalled, ShouldEqual, false)
  157. })
  158. })
  159. })
  160. }