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/arvadosclient"
19 "git.arvados.org/arvados.git/sdk/go/arvadostest"
20 "git.arvados.org/arvados.git/sdk/go/ctxlog"
21 check "gopkg.in/check.v1"
24 var _ = check.Suite(&AuthHandlerSuite{})
26 type AuthHandlerSuite struct {
27 cluster *arvados.Cluster
30 func (s *AuthHandlerSuite) SetUpTest(c *check.C) {
31 arvadostest.ResetEnv()
32 repoRoot, err := filepath.Abs("../api/tmp/git/test")
33 c.Assert(err, check.IsNil)
35 cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load()
36 c.Assert(err, check.Equals, nil)
37 s.cluster, err = cfg.GetCluster("")
38 c.Assert(err, check.Equals, nil)
40 s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{{Host: "localhost:0"}: {}}
41 s.cluster.TLS.Insecure = true
42 s.cluster.Git.GitCommand = "/usr/bin/git"
43 s.cluster.Git.Repositories = repoRoot
46 func (s *AuthHandlerSuite) TestPermission(c *check.C) {
47 client, err := arvados.NewClientFromConfig(s.cluster)
48 c.Assert(err, check.IsNil)
49 ac, err := arvadosclient.New(client)
50 c.Assert(err, check.IsNil)
53 clientPool: &arvadosclient.ClientPool{Prototype: ac},
54 handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
55 log.Printf("%v", r.URL)
56 io.WriteString(w, r.URL.Path)
59 baseURL, err := url.Parse("http://git.example/")
60 c.Assert(err, check.IsNil)
61 for _, trial := range []struct {
69 label: "read repo by name",
70 token: arvadostest.ActiveToken,
71 pathIn: arvadostest.Repository2Name + ".git/git-upload-pack",
72 pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack",
75 label: "read repo by uuid",
76 token: arvadostest.ActiveToken,
77 pathIn: arvadostest.Repository2UUID + ".git/git-upload-pack",
78 pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack",
81 label: "write repo by name",
82 token: arvadostest.ActiveToken,
83 pathIn: arvadostest.Repository2Name + ".git/git-receive-pack",
84 pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack",
87 label: "write repo by uuid",
88 token: arvadostest.ActiveToken,
89 pathIn: arvadostest.Repository2UUID + ".git/git-receive-pack",
90 pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack",
93 label: "uuid not found",
94 token: arvadostest.ActiveToken,
95 pathIn: strings.Replace(arvadostest.Repository2UUID, "6", "z", -1) + ".git/git-upload-pack",
96 status: http.StatusNotFound,
99 label: "name not found",
100 token: arvadostest.ActiveToken,
101 pathIn: "nonexistent-bogus.git/git-upload-pack",
102 status: http.StatusNotFound,
105 label: "read read-only repo",
106 token: arvadostest.SpectatorToken,
107 pathIn: arvadostest.FooRepoName + ".git/git-upload-pack",
108 pathOut: arvadostest.FooRepoUUID + "/.git/git-upload-pack",
111 label: "write read-only repo",
112 token: arvadostest.SpectatorToken,
113 pathIn: arvadostest.FooRepoName + ".git/git-receive-pack",
114 status: http.StatusForbidden,
117 c.Logf("trial label: %q", trial.label)
118 u, err := baseURL.Parse(trial.pathIn)
119 c.Assert(err, check.IsNil)
120 resp := httptest.NewRecorder()
121 req := &http.Request{
125 "Authorization": {"Bearer " + trial.token}}}
126 h.ServeHTTP(resp, req)
127 if trial.status == 0 {
128 trial.status = http.StatusOK
130 c.Check(resp.Code, check.Equals, trial.status)
131 if trial.status < 400 {
132 if trial.pathOut != "" && !strings.HasPrefix(trial.pathOut, "/") {
133 trial.pathOut = "/" + trial.pathOut
135 c.Check(resp.Body.String(), check.Equals, trial.pathOut)
140 func (s *AuthHandlerSuite) TestCORS(c *check.C) {
141 h := &authHandler{cluster: s.cluster}
144 resp := httptest.NewRecorder()
145 req := &http.Request{
149 "Access-Control-Request-Method": {"GET"},
152 h.ServeHTTP(resp, req)
153 c.Check(resp.Code, check.Equals, http.StatusOK)
154 c.Check(resp.Header().Get("Access-Control-Allow-Methods"), check.Equals, "GET, POST")
155 c.Check(resp.Header().Get("Access-Control-Allow-Headers"), check.Equals, "Authorization, Content-Type")
156 c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*")
157 c.Check(resp.Body.String(), check.Equals, "")
159 // CORS actual request. Bogus token and path ensure
160 // authHandler responds 4xx without calling our wrapped (nil)
162 u, err := url.Parse("git.zzzzz.arvadosapi.com/test")
163 c.Assert(err, check.Equals, nil)
164 resp = httptest.NewRecorder()
170 "Authorization": {"OAuth2 foobar"},
173 h.ServeHTTP(resp, req)
174 c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*")