http.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // found in the LICENSE file.
  4. // +build ignore
  5. package main
  6. import (
  7. "bufio"
  8. "flag"
  9. "io/ioutil"
  10. "log"
  11. "net/http"
  12. "os"
  13. "regexp"
  14. "testing"
  15. )
  16. var (
  17. target string
  18. authUser string
  19. authPass string
  20. csrfToken string
  21. csrfFile string
  22. apiKey string
  23. )
  24. var jsonEndpoints = []string{
  25. "/rest/model?repo=default",
  26. "/rest/model/version?repo=default",
  27. "/rest/need",
  28. "/rest/connections",
  29. "/rest/config",
  30. "/rest/config/sync",
  31. "/rest/system",
  32. "/rest/errors",
  33. // "/rest/discovery",
  34. "/rest/report",
  35. }
  36. func main() {
  37. flag.StringVar(&target, "target", "localhost:8080", "Test target")
  38. flag.StringVar(&authUser, "user", "", "Username")
  39. flag.StringVar(&authPass, "pass", "", "Password")
  40. flag.StringVar(&csrfFile, "csrf", "", "CSRF token file")
  41. flag.StringVar(&apiKey, "api", "", "API key")
  42. flag.Parse()
  43. if len(csrfFile) > 0 {
  44. fd, err := os.Open(csrfFile)
  45. if err != nil {
  46. log.Fatal(err)
  47. }
  48. s := bufio.NewScanner(fd)
  49. for s.Scan() {
  50. csrfToken = s.Text()
  51. }
  52. fd.Close()
  53. }
  54. var tests []testing.InternalTest
  55. tests = append(tests, testing.InternalTest{"TestGetIndex", TestGetIndex})
  56. tests = append(tests, testing.InternalTest{"TestGetVersion", TestGetVersion})
  57. tests = append(tests, testing.InternalTest{"TestGetVersionNoCSRF", TestGetVersion})
  58. tests = append(tests, testing.InternalTest{"TestJSONEndpoints", TestJSONEndpoints})
  59. if len(authUser) > 0 || len(apiKey) > 0 {
  60. tests = append(tests, testing.InternalTest{"TestJSONEndpointsNoAuth", TestJSONEndpointsNoAuth})
  61. tests = append(tests, testing.InternalTest{"TestJSONEndpointsIncorrectAuth", TestJSONEndpointsIncorrectAuth})
  62. }
  63. if len(csrfToken) > 0 {
  64. tests = append(tests, testing.InternalTest{"TestJSONEndpointsNoCSRF", TestJSONEndpointsNoCSRF})
  65. }
  66. testing.Main(matcher, tests, nil, nil)
  67. }
  68. func matcher(s0, s1 string) (bool, error) {
  69. return true, nil
  70. }
  71. func TestGetIndex(t *testing.T) {
  72. res, err := get("/index.html")
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. if res.StatusCode != 200 {
  77. t.Errorf("Status %d != 200", res.StatusCode)
  78. }
  79. if res.ContentLength < 1024 {
  80. t.Errorf("Length %d < 1024", res.ContentLength)
  81. }
  82. res.Body.Close()
  83. res, err = get("/")
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. if res.StatusCode != 200 {
  88. t.Errorf("Status %d != 200", res.StatusCode)
  89. }
  90. if res.ContentLength < 1024 {
  91. t.Errorf("Length %d < 1024", res.ContentLength)
  92. }
  93. res.Body.Close()
  94. }
  95. func TestGetVersion(t *testing.T) {
  96. res, err := get("/rest/version")
  97. if err != nil {
  98. t.Fatal(err)
  99. }
  100. if res.StatusCode != 200 {
  101. t.Fatalf("Status %d != 200", res.StatusCode)
  102. }
  103. ver, err := ioutil.ReadAll(res.Body)
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. res.Body.Close()
  108. if !regexp.MustCompile(`v\d+\.\d+\.\d+`).Match(ver) {
  109. t.Errorf("Invalid version %q", ver)
  110. }
  111. }
  112. func TestGetVersionNoCSRF(t *testing.T) {
  113. r, err := http.NewRequest("GET", "http://"+target+"/rest/version", nil)
  114. if err != nil {
  115. t.Fatal(err)
  116. }
  117. if len(authUser) > 0 {
  118. r.SetBasicAuth(authUser, authPass)
  119. }
  120. res, err := http.DefaultClient.Do(r)
  121. if err != nil {
  122. t.Fatal(err)
  123. }
  124. if res.StatusCode != 403 {
  125. t.Fatalf("Status %d != 403", res.StatusCode)
  126. }
  127. }
  128. func TestJSONEndpoints(t *testing.T) {
  129. for _, p := range jsonEndpoints {
  130. res, err := get(p)
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. if res.StatusCode != 200 {
  135. t.Errorf("Status %d != 200 for %q", res.StatusCode, p)
  136. }
  137. if ct := res.Header.Get("Content-Type"); ct != "application/json; charset=utf-8" {
  138. t.Errorf("Content-Type %q != \"application/json\" for %q", ct, p)
  139. }
  140. }
  141. }
  142. func TestJSONEndpointsNoCSRF(t *testing.T) {
  143. for _, p := range jsonEndpoints {
  144. r, err := http.NewRequest("GET", "http://"+target+p, nil)
  145. if err != nil {
  146. t.Fatal(err)
  147. }
  148. if len(authUser) > 0 {
  149. r.SetBasicAuth(authUser, authPass)
  150. }
  151. res, err := http.DefaultClient.Do(r)
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. if res.StatusCode != 403 && res.StatusCode != 401 {
  156. t.Fatalf("Status %d != 403/401 for %q", res.StatusCode, p)
  157. }
  158. }
  159. }
  160. func TestJSONEndpointsNoAuth(t *testing.T) {
  161. for _, p := range jsonEndpoints {
  162. r, err := http.NewRequest("GET", "http://"+target+p, nil)
  163. if err != nil {
  164. t.Fatal(err)
  165. }
  166. if len(csrfToken) > 0 {
  167. r.Header.Set("X-CSRF-Token", csrfToken)
  168. }
  169. res, err := http.DefaultClient.Do(r)
  170. if err != nil {
  171. t.Fatal(err)
  172. }
  173. if res.StatusCode != 403 && res.StatusCode != 401 {
  174. t.Fatalf("Status %d != 403/401 for %q", res.StatusCode, p)
  175. }
  176. }
  177. }
  178. func TestJSONEndpointsIncorrectAuth(t *testing.T) {
  179. for _, p := range jsonEndpoints {
  180. r, err := http.NewRequest("GET", "http://"+target+p, nil)
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. if len(csrfToken) > 0 {
  185. r.Header.Set("X-CSRF-Token", csrfToken)
  186. }
  187. r.SetBasicAuth("wronguser", "wrongpass")
  188. res, err := http.DefaultClient.Do(r)
  189. if err != nil {
  190. t.Fatal(err)
  191. }
  192. if res.StatusCode != 403 && res.StatusCode != 401 {
  193. t.Fatalf("Status %d != 403/401 for %q", res.StatusCode, p)
  194. }
  195. }
  196. }
  197. func get(path string) (*http.Response, error) {
  198. r, err := http.NewRequest("GET", "http://"+target+path, nil)
  199. if err != nil {
  200. return nil, err
  201. }
  202. if len(authUser) > 0 {
  203. r.SetBasicAuth(authUser, authPass)
  204. }
  205. if len(csrfToken) > 0 {
  206. r.Header.Set("X-CSRF-Token", csrfToken)
  207. }
  208. if len(apiKey) > 0 {
  209. r.Header.Set("X-API-Key", apiKey)
  210. }
  211. return http.DefaultClient.Do(r)
  212. }