21700: Install Bundler system-wide in Rails postinst
[arvados.git] / lib / controller / localdb / authorized_key_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package localdb
6
7 import (
8         _ "embed"
9         "errors"
10         "io/ioutil"
11         "net/http"
12         "os"
13         "strings"
14
15         "git.arvados.org/arvados.git/sdk/go/arvados"
16         "git.arvados.org/arvados.git/sdk/go/arvadostest"
17         "git.arvados.org/arvados.git/sdk/go/httpserver"
18         . "gopkg.in/check.v1"
19 )
20
21 var _ = Suite(&authorizedKeySuite{})
22
23 type authorizedKeySuite struct {
24         localdbSuite
25 }
26
27 //go:embed testdata/rsa.pub
28 var testPubKey string
29
30 func (s *authorizedKeySuite) TestAuthorizedKeyCreate(c *C) {
31         ak, err := s.localdb.AuthorizedKeyCreate(s.userctx, arvados.CreateOptions{
32                 Attrs: map[string]interface{}{
33                         "name":     "testkey",
34                         "key_type": "SSH",
35                 }})
36         c.Assert(err, IsNil)
37         c.Check(ak.KeyType, Equals, "SSH")
38         defer s.localdb.AuthorizedKeyDelete(s.userctx, arvados.DeleteOptions{UUID: ak.UUID})
39         updated, err := s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
40                 UUID:  ak.UUID,
41                 Attrs: map[string]interface{}{"name": "testkeyrenamed"}})
42         c.Check(err, IsNil)
43         c.Check(updated.UUID, Equals, ak.UUID)
44         c.Check(updated.Name, Equals, "testkeyrenamed")
45         c.Check(updated.ModifiedByUserUUID, Equals, arvadostest.ActiveUserUUID)
46
47         _, err = s.localdb.AuthorizedKeyCreate(s.userctx, arvados.CreateOptions{
48                 Attrs: map[string]interface{}{
49                         "name":       "testkey",
50                         "public_key": "ssh-dsa boguskey\n",
51                 }})
52         c.Check(err, ErrorMatches, `Public key does not appear to be valid: ssh: no key found`)
53         _, err = s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
54                 UUID: ak.UUID,
55                 Attrs: map[string]interface{}{
56                         "public_key": strings.Replace(testPubKey, "A", "#", 1),
57                 }})
58         c.Check(err, ErrorMatches, `Public key does not appear to be valid: ssh: no key found`)
59         _, err = s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
60                 UUID: ak.UUID,
61                 Attrs: map[string]interface{}{
62                         "public_key": testPubKey + testPubKey,
63                 }})
64         c.Check(err, ErrorMatches, `Public key does not appear to be valid: extra data after key`)
65         _, err = s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
66                 UUID: ak.UUID,
67                 Attrs: map[string]interface{}{
68                         "public_key": testPubKey + "# extra data\n",
69                 }})
70         c.Check(err, ErrorMatches, `Public key does not appear to be valid: extra data after key`)
71         _, err = s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
72                 UUID: ak.UUID,
73                 Attrs: map[string]interface{}{
74                         "public_key": strings.Replace(testPubKey, "ssh-rsa", "ssh-dsa", 1),
75                 }})
76         c.Check(err, ErrorMatches, `Public key does not appear to be valid: leading type field "ssh-dsa" does not match actual key type "ssh-rsa"`)
77         var se httpserver.HTTPStatusError
78         if c.Check(errors.As(err, &se), Equals, true) {
79                 c.Check(se.HTTPStatus(), Equals, http.StatusBadRequest)
80         }
81
82         dirents, err := os.ReadDir("./testdata")
83         c.Assert(err, IsNil)
84         c.Assert(dirents, Not(HasLen), 0)
85         for _, dirent := range dirents {
86                 if !strings.HasSuffix(dirent.Name(), ".pub") {
87                         continue
88                 }
89                 pubkeyfile := "./testdata/" + dirent.Name()
90                 c.Logf("checking public key from %s", pubkeyfile)
91                 pubkey, err := ioutil.ReadFile(pubkeyfile)
92                 if !c.Check(err, IsNil) {
93                         continue
94                 }
95                 updated, err := s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
96                         UUID: ak.UUID,
97                         Attrs: map[string]interface{}{
98                                 "public_key": string(pubkey),
99                         }})
100                 c.Check(err, IsNil)
101                 c.Check(updated.PublicKey, Equals, string(pubkey))
102
103                 _, err = s.localdb.AuthorizedKeyUpdate(s.userctx, arvados.UpdateOptions{
104                         UUID: ak.UUID,
105                         Attrs: map[string]interface{}{
106                                 "public_key": strings.Replace(string(pubkey), " ", "-bogus ", 1),
107                         }})
108                 c.Check(err, ErrorMatches, `.*type field ".*" does not match actual key type ".*"`)
109         }
110
111         deleted, err := s.localdb.AuthorizedKeyDelete(s.userctx, arvados.DeleteOptions{UUID: ak.UUID})
112         c.Check(err, IsNil)
113         c.Check(deleted.UUID, Equals, ak.UUID)
114 }