cors_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
  2. // See LICENSE.txt for license information.
  3. package api4
  4. import (
  5. "fmt"
  6. "net/http"
  7. "testing"
  8. "github.com/mattermost/mattermost-server/v5/model"
  9. "github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. )
  13. const (
  14. acAllowOrigin = "Access-Control-Allow-Origin"
  15. acExposeHeaders = "Access-Control-Expose-Headers"
  16. acMaxAge = "Access-Control-Max-Age"
  17. acAllowCredentials = "Access-Control-Allow-Credentials"
  18. acAllowMethods = "Access-Control-Allow-Methods"
  19. acAllowHeaders = "Access-Control-Allow-Headers"
  20. )
  21. func TestCORSRequestHandling(t *testing.T) {
  22. for name, testcase := range map[string]struct {
  23. AllowCorsFrom string
  24. CorsExposedHeaders string
  25. CorsAllowCredentials bool
  26. ModifyRequest func(req *http.Request)
  27. ExpectedAllowOrigin string
  28. ExpectedExposeHeaders string
  29. ExpectedAllowCredentials string
  30. }{
  31. "NoCORS": {
  32. "",
  33. "",
  34. false,
  35. func(req *http.Request) {
  36. },
  37. "",
  38. "",
  39. "",
  40. },
  41. "CORSEnabled": {
  42. "http://somewhere.com",
  43. "",
  44. false,
  45. func(req *http.Request) {
  46. },
  47. "",
  48. "",
  49. "",
  50. },
  51. "CORSEnabledStarOrigin": {
  52. "*",
  53. "",
  54. false,
  55. func(req *http.Request) {
  56. req.Header.Set("Origin", "http://pre-release.mattermost.com")
  57. },
  58. "*",
  59. "",
  60. "",
  61. },
  62. "CORSEnabledStarNoOrigin": { // CORS spec requires this, not a bug.
  63. "*",
  64. "",
  65. false,
  66. func(req *http.Request) {
  67. },
  68. "",
  69. "",
  70. "",
  71. },
  72. "CORSEnabledMatching": {
  73. "http://mattermost.com",
  74. "",
  75. false,
  76. func(req *http.Request) {
  77. req.Header.Set("Origin", "http://mattermost.com")
  78. },
  79. "http://mattermost.com",
  80. "",
  81. "",
  82. },
  83. "CORSEnabledMultiple": {
  84. "http://spinmint.com http://mattermost.com",
  85. "",
  86. false,
  87. func(req *http.Request) {
  88. req.Header.Set("Origin", "http://mattermost.com")
  89. },
  90. "http://mattermost.com",
  91. "",
  92. "",
  93. },
  94. "CORSEnabledWithCredentials": {
  95. "http://mattermost.com",
  96. "",
  97. true,
  98. func(req *http.Request) {
  99. req.Header.Set("Origin", "http://mattermost.com")
  100. },
  101. "http://mattermost.com",
  102. "",
  103. "true",
  104. },
  105. "CORSEnabledWithHeaders": {
  106. "http://mattermost.com",
  107. "x-my-special-header x-blueberry",
  108. true,
  109. func(req *http.Request) {
  110. req.Header.Set("Origin", "http://mattermost.com")
  111. },
  112. "http://mattermost.com",
  113. "X-My-Special-Header, X-Blueberry",
  114. "true",
  115. },
  116. } {
  117. t.Run(name, func(t *testing.T) {
  118. th := SetupConfigWithStoreMock(t, func(cfg *model.Config) {
  119. *cfg.ServiceSettings.AllowCorsFrom = testcase.AllowCorsFrom
  120. *cfg.ServiceSettings.CorsExposedHeaders = testcase.CorsExposedHeaders
  121. *cfg.ServiceSettings.CorsAllowCredentials = testcase.CorsAllowCredentials
  122. })
  123. defer th.TearDown()
  124. systemStore := mocks.SystemStore{}
  125. systemStore.On("Get").Return(make(model.StringMap), nil)
  126. licenseStore := mocks.LicenseStore{}
  127. licenseStore.On("Get", "").Return(&model.LicenseRecord{}, nil)
  128. th.App.Srv().Store.(*mocks.Store).On("System").Return(&systemStore)
  129. th.App.Srv().Store.(*mocks.Store).On("License").Return(&licenseStore)
  130. port := th.App.Srv().ListenAddr.Port
  131. host := fmt.Sprintf("http://localhost:%v", port)
  132. url := fmt.Sprintf("%v/api/v4/system/ping", host)
  133. req, err := http.NewRequest("GET", url, nil)
  134. require.NoError(t, err)
  135. testcase.ModifyRequest(req)
  136. client := &http.Client{}
  137. resp, err := client.Do(req)
  138. require.NoError(t, err)
  139. assert.Equal(t, http.StatusOK, resp.StatusCode)
  140. assert.Equal(t, testcase.ExpectedAllowOrigin, resp.Header.Get(acAllowOrigin))
  141. assert.Equal(t, testcase.ExpectedExposeHeaders, resp.Header.Get(acExposeHeaders))
  142. assert.Equal(t, "", resp.Header.Get(acMaxAge))
  143. assert.Equal(t, testcase.ExpectedAllowCredentials, resp.Header.Get(acAllowCredentials))
  144. assert.Equal(t, "", resp.Header.Get(acAllowMethods))
  145. assert.Equal(t, "", resp.Header.Get(acAllowHeaders))
  146. })
  147. }
  148. }