1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
16 "git.arvados.org/arvados.git/lib/config"
17 "git.arvados.org/arvados.git/sdk/go/arvados"
18 "git.arvados.org/arvados.git/sdk/go/arvadostest"
19 "git.arvados.org/arvados.git/sdk/go/ctxlog"
20 check "gopkg.in/check.v1"
23 var _ = check.Suite(&AuthHandlerSuite{})
25 type AuthHandlerSuite struct {
26 cluster *arvados.Cluster
29 func (s *AuthHandlerSuite) SetUpSuite(c *check.C) {
30 arvadostest.StartAPI()
33 func (s *AuthHandlerSuite) TearDownSuite(c *check.C) {
37 func (s *AuthHandlerSuite) SetUpTest(c *check.C) {
38 arvadostest.ResetEnv()
39 repoRoot, err := filepath.Abs("../api/tmp/git/test")
40 c.Assert(err, check.IsNil)
42 cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load()
43 c.Assert(err, check.Equals, nil)
44 s.cluster, err = cfg.GetCluster("")
45 c.Assert(err, check.Equals, nil)
47 s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{arvados.URL{Host: "localhost:0"}: arvados.ServiceInstance{}}
48 s.cluster.TLS.Insecure = true
49 s.cluster.Git.GitCommand = "/usr/bin/git"
50 s.cluster.Git.Repositories = repoRoot
53 func (s *AuthHandlerSuite) TestPermission(c *check.C) {
54 h := &authHandler{handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
55 log.Printf("%v", r.URL)
56 io.WriteString(w, r.URL.Path)
57 }), cluster: s.cluster}
58 baseURL, err := url.Parse("http://git.example/")
59 c.Assert(err, check.IsNil)
60 for _, trial := range []struct {
68 label: "read repo by name",
69 token: arvadostest.ActiveToken,
70 pathIn: arvadostest.Repository2Name + ".git/git-upload-pack",
71 pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack",
74 label: "read repo by uuid",
75 token: arvadostest.ActiveToken,
76 pathIn: arvadostest.Repository2UUID + ".git/git-upload-pack",
77 pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack",
80 label: "write repo by name",
81 token: arvadostest.ActiveToken,
82 pathIn: arvadostest.Repository2Name + ".git/git-receive-pack",
83 pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack",
86 label: "write repo by uuid",
87 token: arvadostest.ActiveToken,
88 pathIn: arvadostest.Repository2UUID + ".git/git-receive-pack",
89 pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack",
92 label: "uuid not found",
93 token: arvadostest.ActiveToken,
94 pathIn: strings.Replace(arvadostest.Repository2UUID, "6", "z", -1) + ".git/git-upload-pack",
95 status: http.StatusNotFound,
98 label: "name not found",
99 token: arvadostest.ActiveToken,
100 pathIn: "nonexistent-bogus.git/git-upload-pack",
101 status: http.StatusNotFound,
104 label: "read read-only repo",
105 token: arvadostest.SpectatorToken,
106 pathIn: arvadostest.FooRepoName + ".git/git-upload-pack",
107 pathOut: arvadostest.FooRepoUUID + "/.git/git-upload-pack",
110 label: "write read-only repo",
111 token: arvadostest.SpectatorToken,
112 pathIn: arvadostest.FooRepoName + ".git/git-receive-pack",
113 status: http.StatusForbidden,
116 c.Logf("trial label: %q", trial.label)
117 u, err := baseURL.Parse(trial.pathIn)
118 c.Assert(err, check.IsNil)
119 resp := httptest.NewRecorder()
120 req := &http.Request{
124 "Authorization": {"Bearer " + trial.token}}}
125 h.ServeHTTP(resp, req)
126 if trial.status == 0 {
127 trial.status = http.StatusOK
129 c.Check(resp.Code, check.Equals, trial.status)
130 if trial.status < 400 {
131 if trial.pathOut != "" && !strings.HasPrefix(trial.pathOut, "/") {
132 trial.pathOut = "/" + trial.pathOut
134 c.Check(resp.Body.String(), check.Equals, trial.pathOut)
139 func (s *AuthHandlerSuite) TestCORS(c *check.C) {
140 h := &authHandler{cluster: s.cluster}
143 resp := httptest.NewRecorder()
144 req := &http.Request{
148 "Access-Control-Request-Method": {"GET"},
151 h.ServeHTTP(resp, req)
152 c.Check(resp.Code, check.Equals, http.StatusOK)
153 c.Check(resp.Header().Get("Access-Control-Allow-Methods"), check.Equals, "GET, POST")
154 c.Check(resp.Header().Get("Access-Control-Allow-Headers"), check.Equals, "Authorization, Content-Type")
155 c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*")
156 c.Check(resp.Body.String(), check.Equals, "")
158 // CORS actual request. Bogus token and path ensure
159 // authHandler responds 4xx without calling our wrapped (nil)
161 u, err := url.Parse("git.zzzzz.arvadosapi.com/test")
162 c.Assert(err, check.Equals, nil)
163 resp = httptest.NewRecorder()
169 "Authorization": {"OAuth2 foobar"},
172 h.ServeHTTP(resp, req)
173 c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*")