launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/apiserver/keymanager/keymanager_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package keymanager_test 5 6 import ( 7 "strings" 8 9 gc "launchpad.net/gocheck" 10 11 "fmt" 12 jujutesting "launchpad.net/juju-core/juju/testing" 13 "launchpad.net/juju-core/state/api/params" 14 "launchpad.net/juju-core/state/apiserver/common" 15 "launchpad.net/juju-core/state/apiserver/keymanager" 16 keymanagertesting "launchpad.net/juju-core/state/apiserver/keymanager/testing" 17 apiservertesting "launchpad.net/juju-core/state/apiserver/testing" 18 statetesting "launchpad.net/juju-core/state/testing" 19 "launchpad.net/juju-core/utils/ssh" 20 sshtesting "launchpad.net/juju-core/utils/ssh/testing" 21 ) 22 23 type keyManagerSuite struct { 24 jujutesting.JujuConnSuite 25 26 keymanager *keymanager.KeyManagerAPI 27 resources *common.Resources 28 authoriser apiservertesting.FakeAuthorizer 29 } 30 31 var _ = gc.Suite(&keyManagerSuite{}) 32 33 func (s *keyManagerSuite) SetUpTest(c *gc.C) { 34 s.JujuConnSuite.SetUpTest(c) 35 s.resources = common.NewResources() 36 s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() }) 37 38 s.authoriser = apiservertesting.FakeAuthorizer{ 39 Tag: "user-admin", 40 LoggedIn: true, 41 Client: true, 42 } 43 var err error 44 s.keymanager, err = keymanager.NewKeyManagerAPI(s.State, s.resources, s.authoriser) 45 c.Assert(err, gc.IsNil) 46 } 47 48 func (s *keyManagerSuite) TestNewKeyManagerAPIAcceptsClient(c *gc.C) { 49 endPoint, err := keymanager.NewKeyManagerAPI(s.State, s.resources, s.authoriser) 50 c.Assert(err, gc.IsNil) 51 c.Assert(endPoint, gc.NotNil) 52 } 53 54 func (s *keyManagerSuite) TestNewKeyManagerAPIRefusesNonClient(c *gc.C) { 55 anAuthoriser := s.authoriser 56 anAuthoriser.Client = false 57 endPoint, err := keymanager.NewKeyManagerAPI(s.State, s.resources, anAuthoriser) 58 c.Assert(endPoint, gc.IsNil) 59 c.Assert(err, gc.ErrorMatches, "permission denied") 60 } 61 62 func (s *keyManagerSuite) setAuthorisedKeys(c *gc.C, keys string) { 63 err := statetesting.UpdateConfig(s.State, map[string]interface{}{"authorized-keys": keys}) 64 c.Assert(err, gc.IsNil) 65 envConfig, err := s.State.EnvironConfig() 66 c.Assert(err, gc.IsNil) 67 c.Assert(envConfig.AuthorizedKeys(), gc.Equals, keys) 68 } 69 70 func (s *keyManagerSuite) TestListKeys(c *gc.C) { 71 key1 := sshtesting.ValidKeyOne.Key + " user@host" 72 key2 := sshtesting.ValidKeyTwo.Key 73 s.setAuthorisedKeys(c, strings.Join([]string{key1, key2, "bad key"}, "\n")) 74 75 args := params.ListSSHKeys{ 76 Entities: params.Entities{[]params.Entity{ 77 {Tag: "admin"}, 78 {Tag: "invalid"}, 79 }}, 80 Mode: ssh.FullKeys, 81 } 82 results, err := s.keymanager.ListKeys(args) 83 c.Assert(err, gc.IsNil) 84 c.Assert(results, gc.DeepEquals, params.StringsResults{ 85 Results: []params.StringsResult{ 86 {Result: []string{key1, key2, "Invalid key: bad key"}}, 87 {Error: apiservertesting.ErrUnauthorized}, 88 }, 89 }) 90 } 91 92 func (s *keyManagerSuite) assertEnvironKeys(c *gc.C, expected []string) { 93 envConfig, err := s.State.EnvironConfig() 94 c.Assert(err, gc.IsNil) 95 keys := envConfig.AuthorizedKeys() 96 c.Assert(keys, gc.Equals, strings.Join(expected, "\n")) 97 } 98 99 func (s *keyManagerSuite) TestAddKeys(c *gc.C) { 100 key1 := sshtesting.ValidKeyOne.Key + " user@host" 101 key2 := sshtesting.ValidKeyTwo.Key 102 initialKeys := []string{key1, key2, "bad key"} 103 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 104 105 newKey := sshtesting.ValidKeyThree.Key + " newuser@host" 106 args := params.ModifyUserSSHKeys{ 107 User: "admin", 108 Keys: []string{key2, newKey, "invalid-key"}, 109 } 110 results, err := s.keymanager.AddKeys(args) 111 c.Assert(err, gc.IsNil) 112 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 113 Results: []params.ErrorResult{ 114 {Error: apiservertesting.ServerError(fmt.Sprintf("duplicate ssh key: %s", key2))}, 115 {Error: nil}, 116 {Error: apiservertesting.ServerError("invalid ssh key: invalid-key")}, 117 }, 118 }) 119 s.assertEnvironKeys(c, append(initialKeys, newKey)) 120 } 121 122 func (s *keyManagerSuite) TestDeleteKeys(c *gc.C) { 123 key1 := sshtesting.ValidKeyOne.Key + " user@host" 124 key2 := sshtesting.ValidKeyTwo.Key 125 initialKeys := []string{key1, key2, "bad key"} 126 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 127 128 args := params.ModifyUserSSHKeys{ 129 User: "admin", 130 Keys: []string{sshtesting.ValidKeyTwo.Fingerprint, sshtesting.ValidKeyThree.Fingerprint, "invalid-key"}, 131 } 132 results, err := s.keymanager.DeleteKeys(args) 133 c.Assert(err, gc.IsNil) 134 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 135 Results: []params.ErrorResult{ 136 {Error: nil}, 137 {Error: apiservertesting.ServerError("invalid ssh key: " + sshtesting.ValidKeyThree.Fingerprint)}, 138 {Error: apiservertesting.ServerError("invalid ssh key: invalid-key")}, 139 }, 140 }) 141 s.assertEnvironKeys(c, []string{"bad key", key1}) 142 } 143 144 func (s *keyManagerSuite) TestCannotDeleteAllKeys(c *gc.C) { 145 key1 := sshtesting.ValidKeyOne.Key + " user@host" 146 key2 := sshtesting.ValidKeyTwo.Key 147 initialKeys := []string{key1, key2} 148 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 149 150 args := params.ModifyUserSSHKeys{ 151 User: "admin", 152 Keys: []string{sshtesting.ValidKeyTwo.Fingerprint, "user@host"}, 153 } 154 _, err := s.keymanager.DeleteKeys(args) 155 c.Assert(err, gc.ErrorMatches, "cannot delete all keys") 156 s.assertEnvironKeys(c, initialKeys) 157 } 158 159 func (s *keyManagerSuite) assertInvalidUserOperation(c *gc.C, runTestLogic func(args params.ModifyUserSSHKeys) error) { 160 initialKey := sshtesting.ValidKeyOne.Key + " user@host" 161 s.setAuthorisedKeys(c, initialKey) 162 163 // Set up the params. 164 newKey := sshtesting.ValidKeyThree.Key + " newuser@host" 165 args := params.ModifyUserSSHKeys{ 166 User: "invalid", 167 Keys: []string{newKey}, 168 } 169 // Run the required test code and check the error. 170 err := runTestLogic(args) 171 c.Assert(err, gc.DeepEquals, apiservertesting.ErrUnauthorized) 172 173 // No environ changes. 174 s.assertEnvironKeys(c, []string{initialKey}) 175 } 176 177 func (s *keyManagerSuite) TestAddKeysInvalidUser(c *gc.C) { 178 s.assertInvalidUserOperation(c, func(args params.ModifyUserSSHKeys) error { 179 _, err := s.keymanager.AddKeys(args) 180 return err 181 }) 182 } 183 184 func (s *keyManagerSuite) TestDeleteKeysInvalidUser(c *gc.C) { 185 s.assertInvalidUserOperation(c, func(args params.ModifyUserSSHKeys) error { 186 _, err := s.keymanager.DeleteKeys(args) 187 return err 188 }) 189 } 190 191 func (s *keyManagerSuite) TestImportKeys(c *gc.C) { 192 s.PatchValue(&keymanager.RunSSHImportId, keymanagertesting.FakeImport) 193 194 key1 := sshtesting.ValidKeyOne.Key + " user@host" 195 key2 := sshtesting.ValidKeyTwo.Key 196 key3 := sshtesting.ValidKeyThree.Key 197 initialKeys := []string{key1, key2, "bad key"} 198 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 199 200 args := params.ModifyUserSSHKeys{ 201 User: "admin", 202 Keys: []string{"lp:existing", "lp:validuser", "invalid-key"}, 203 } 204 results, err := s.keymanager.ImportKeys(args) 205 c.Assert(err, gc.IsNil) 206 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 207 Results: []params.ErrorResult{ 208 {Error: apiservertesting.ServerError(fmt.Sprintf("duplicate ssh key: %s", key2))}, 209 {Error: nil}, 210 {Error: apiservertesting.ServerError("invalid ssh key id: invalid-key")}, 211 }, 212 }) 213 s.assertEnvironKeys(c, append(initialKeys, key3)) 214 } 215 216 func (s *keyManagerSuite) TestCallSSHImportId(c *gc.C) { 217 c.Skip("the landing bot does not run ssh-import-id successfully") 218 output, err := keymanager.RunSSHImportId("lp:wallyworld") 219 c.Assert(err, gc.IsNil) 220 lines := strings.Split(output, "\n") 221 var key string 222 for _, line := range lines { 223 if !strings.HasPrefix(line, "ssh-") { 224 continue 225 } 226 _, _, err := ssh.KeyFingerprint(line) 227 if err == nil { 228 key = line 229 } 230 } 231 c.Assert(key, gc.Not(gc.Equals), "") 232 }