github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/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 "fmt" 8 "strings" 9 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/utils/ssh" 12 sshtesting "github.com/juju/utils/ssh/testing" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/names.v2" 15 16 "github.com/juju/juju/apiserver/common" 17 commontesting "github.com/juju/juju/apiserver/common/testing" 18 "github.com/juju/juju/apiserver/facades/client/keymanager" 19 keymanagertesting "github.com/juju/juju/apiserver/facades/client/keymanager/testing" 20 "github.com/juju/juju/apiserver/params" 21 apiservertesting "github.com/juju/juju/apiserver/testing" 22 jujutesting "github.com/juju/juju/juju/testing" 23 "github.com/juju/juju/state" 24 "github.com/juju/juju/testing/factory" 25 ) 26 27 type keyManagerSuite struct { 28 jujutesting.JujuConnSuite 29 30 keymanager *keymanager.KeyManagerAPI 31 resources *common.Resources 32 authoriser apiservertesting.FakeAuthorizer 33 34 commontesting.BlockHelper 35 } 36 37 var _ = gc.Suite(&keyManagerSuite{}) 38 39 func (s *keyManagerSuite) SetUpTest(c *gc.C) { 40 s.JujuConnSuite.SetUpTest(c) 41 s.resources = common.NewResources() 42 s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() }) 43 44 s.authoriser = apiservertesting.FakeAuthorizer{ 45 Tag: s.AdminUserTag(c), 46 } 47 var err error 48 s.keymanager, err = keymanager.NewKeyManagerAPI(s.State, s.resources, s.authoriser) 49 c.Assert(err, jc.ErrorIsNil) 50 51 s.BlockHelper = commontesting.NewBlockHelper(s.APIState) 52 s.AddCleanup(func(*gc.C) { s.BlockHelper.Close() }) 53 } 54 55 func (s *keyManagerSuite) TestNewKeyManagerAPIAcceptsClient(c *gc.C) { 56 endPoint, err := keymanager.NewKeyManagerAPI(s.State, s.resources, s.authoriser) 57 c.Assert(err, jc.ErrorIsNil) 58 c.Assert(endPoint, gc.NotNil) 59 } 60 61 func (s *keyManagerSuite) TestNewKeyManagerAPIRefusesController(c *gc.C) { 62 s.testNewKeyManagerAPIRefuses(c, names.NewMachineTag("0"), true) 63 } 64 65 func (s *keyManagerSuite) TestNewKeyManagerAPIRefusesUnit(c *gc.C) { 66 s.testNewKeyManagerAPIRefuses(c, names.NewUnitTag("mysql/0"), false) 67 } 68 69 func (s *keyManagerSuite) TestNewKeyManagerAPIRefusesMachine(c *gc.C) { 70 s.testNewKeyManagerAPIRefuses(c, names.NewMachineTag("99"), false) 71 } 72 73 func (s *keyManagerSuite) testNewKeyManagerAPIRefuses(c *gc.C, tag names.Tag, controller bool) { 74 auth := apiservertesting.FakeAuthorizer{ 75 Tag: tag, 76 Controller: controller, 77 } 78 endPoint, err := keymanager.NewKeyManagerAPI(s.State, s.resources, auth) 79 c.Assert(endPoint, gc.IsNil) 80 c.Assert(err, gc.ErrorMatches, "permission denied") 81 } 82 83 func (s *keyManagerSuite) setAuthorisedKeys(c *gc.C, keys string) { 84 s.setAuthorisedKeysForModel(c, s.State, keys) 85 } 86 87 func (s *keyManagerSuite) setAuthorisedKeysForModel(c *gc.C, st *state.State, keys string) { 88 m, err := st.Model() 89 c.Assert(err, jc.ErrorIsNil) 90 91 err = m.UpdateModelConfig(map[string]interface{}{"authorized-keys": keys}, nil) 92 c.Assert(err, jc.ErrorIsNil) 93 94 modelConfig, err := m.ModelConfig() 95 c.Assert(err, jc.ErrorIsNil) 96 c.Assert(modelConfig.AuthorizedKeys(), gc.Equals, keys) 97 } 98 99 func (s *keyManagerSuite) TestListKeys(c *gc.C) { 100 key1 := sshtesting.ValidKeyOne.Key + " user@host" 101 key2 := sshtesting.ValidKeyTwo.Key 102 s.setAuthorisedKeys(c, strings.Join([]string{key1, key2, "bad key"}, "\n")) 103 104 args := params.ListSSHKeys{ 105 Entities: params.Entities{[]params.Entity{ 106 {Tag: s.AdminUserTag(c).Name()}, 107 {Tag: "invalid"}, 108 }}, 109 Mode: ssh.FullKeys, 110 } 111 results, err := s.keymanager.ListKeys(args) 112 c.Assert(err, jc.ErrorIsNil) 113 c.Assert(results, gc.DeepEquals, params.StringsResults{ 114 Results: []params.StringsResult{ 115 {Result: []string{key1, key2, "Invalid key: bad key"}}, 116 {Result: []string{key1, key2, "Invalid key: bad key"}}, 117 }, 118 }) 119 } 120 121 func (s *keyManagerSuite) TestListKeysHidesJujuInternal(c *gc.C) { 122 key1 := sshtesting.ValidKeyOne.Key + " juju-client-key" 123 key2 := sshtesting.ValidKeyTwo.Key + " juju-system-key" 124 s.setAuthorisedKeys(c, strings.Join([]string{key1, key2}, "\n")) 125 126 args := params.ListSSHKeys{ 127 Entities: params.Entities{[]params.Entity{ 128 {Tag: s.AdminUserTag(c).Name()}, 129 }}, 130 Mode: ssh.FullKeys, 131 } 132 results, err := s.keymanager.ListKeys(args) 133 c.Assert(err, jc.ErrorIsNil) 134 c.Assert(results, gc.DeepEquals, params.StringsResults{ 135 Results: []params.StringsResult{ 136 {Result: nil}, 137 }, 138 }) 139 } 140 141 func (s *keyManagerSuite) TestListJujuSystemKey(c *gc.C) { 142 anAuthoriser := s.authoriser 143 anAuthoriser.Tag = names.NewUserTag("fred") 144 var err error 145 s.keymanager, err = keymanager.NewKeyManagerAPI(s.State, s.resources, anAuthoriser) 146 c.Assert(err, jc.ErrorIsNil) 147 key1 := sshtesting.ValidKeyOne.Key 148 s.setAuthorisedKeys(c, key1) 149 150 args := params.ListSSHKeys{ 151 Entities: params.Entities{[]params.Entity{ 152 {Tag: "juju-system-key"}, 153 }}, 154 Mode: ssh.FullKeys, 155 } 156 results, err := s.keymanager.ListKeys(args) 157 c.Assert(err, jc.ErrorIsNil) 158 c.Assert(results.Results, gc.HasLen, 1) 159 c.Assert(results.Results[0].Error, gc.ErrorMatches, "permission denied") 160 } 161 162 func (s *keyManagerSuite) assertModelKeys(c *gc.C, expected []string) { 163 s.assertKeysForModel(c, s.State, expected) 164 } 165 166 func (s *keyManagerSuite) assertKeysForModel(c *gc.C, st *state.State, expected []string) { 167 m, err := st.Model() 168 c.Assert(err, jc.ErrorIsNil) 169 170 modelConfig, err := m.ModelConfig() 171 c.Assert(err, jc.ErrorIsNil) 172 keys := modelConfig.AuthorizedKeys() 173 c.Assert(keys, gc.Equals, strings.Join(expected, "\n")) 174 } 175 176 func (s *keyManagerSuite) assertAddKeys(c *gc.C, st *state.State, apiUser names.UserTag, ok bool) { 177 key1 := sshtesting.ValidKeyOne.Key + " user@host" 178 key2 := sshtesting.ValidKeyTwo.Key 179 initialKeys := []string{key1, key2, "bad key"} 180 s.setAuthorisedKeysForModel(c, st, strings.Join(initialKeys, "\n")) 181 182 anAuthoriser := s.authoriser 183 anAuthoriser.Tag = apiUser 184 var err error 185 s.keymanager, err = keymanager.NewKeyManagerAPI(st, s.resources, anAuthoriser) 186 c.Assert(err, jc.ErrorIsNil) 187 188 newKey := sshtesting.ValidKeyThree.Key + " newuser@host" 189 args := params.ModifyUserSSHKeys{ 190 User: s.AdminUserTag(c).Name(), 191 Keys: []string{key2, newKey, "invalid-key"}, 192 } 193 results, err := s.keymanager.AddKeys(args) 194 if !ok { 195 c.Assert(err, gc.ErrorMatches, "permission denied") 196 c.Assert(params.ErrCode(err), gc.Equals, params.CodeUnauthorized) 197 return 198 } 199 c.Assert(err, jc.ErrorIsNil) 200 201 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 202 Results: []params.ErrorResult{ 203 {Error: apiservertesting.ServerError(fmt.Sprintf("duplicate ssh key: %s", key2))}, 204 {Error: nil}, 205 {Error: apiservertesting.ServerError("invalid ssh key: invalid-key")}, 206 }, 207 }) 208 s.assertKeysForModel(c, st, append(initialKeys, newKey)) 209 } 210 211 func (s *keyManagerSuite) TestAddKeys(c *gc.C) { 212 s.assertAddKeys(c, s.State, s.AdminUserTag(c), true) 213 } 214 215 func (s *keyManagerSuite) TestAddKeysSuperUser(c *gc.C) { 216 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "superuser-fred", NoModelUser: true}) 217 s.assertAddKeys(c, s.State, user.UserTag(), true) 218 } 219 220 func (s *keyManagerSuite) TestAddKeysModelAdmin(c *gc.C) { 221 otherState := s.Factory.MakeModel(c, nil) 222 defer otherState.Close() 223 224 otherModel, err := otherState.Model() 225 c.Assert(err, jc.ErrorIsNil) 226 227 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "admin" + otherModel.ModelTag().String()}) 228 s.assertAddKeys(c, otherState, user.UserTag(), true) 229 } 230 231 func (s *keyManagerSuite) TestAddKeysNonAuthorised(c *gc.C) { 232 user := s.Factory.MakeUser(c, nil) 233 s.assertAddKeys(c, s.State, user.UserTag(), false) 234 } 235 236 func (s *keyManagerSuite) TestBlockAddKeys(c *gc.C) { 237 key1 := sshtesting.ValidKeyOne.Key + " user@host" 238 key2 := sshtesting.ValidKeyTwo.Key 239 initialKeys := []string{key1, key2, "bad key"} 240 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 241 242 newKey := sshtesting.ValidKeyThree.Key + " newuser@host" 243 args := params.ModifyUserSSHKeys{ 244 User: s.AdminUserTag(c).Name(), 245 Keys: []string{key2, newKey, "invalid-key"}, 246 } 247 248 s.BlockAllChanges(c, "TestBlockAddKeys") 249 _, err := s.keymanager.AddKeys(args) 250 // Check that the call is blocked 251 s.AssertBlocked(c, err, "TestBlockAddKeys") 252 s.assertModelKeys(c, initialKeys) 253 } 254 255 func (s *keyManagerSuite) TestAddJujuSystemKey(c *gc.C) { 256 anAuthoriser := s.authoriser 257 anAuthoriser.Tag = names.NewUserTag("fred") 258 var err error 259 s.keymanager, err = keymanager.NewKeyManagerAPI(s.State, s.resources, anAuthoriser) 260 c.Assert(err, jc.ErrorIsNil) 261 key1 := sshtesting.ValidKeyOne.Key 262 s.setAuthorisedKeys(c, key1) 263 264 newKey := sshtesting.ValidKeyThree.Key + " juju-system-key" 265 args := params.ModifyUserSSHKeys{ 266 User: "juju-system-key", 267 Keys: []string{newKey}, 268 } 269 _, err = s.keymanager.AddKeys(args) 270 c.Assert(err, gc.ErrorMatches, "permission denied") 271 c.Assert(params.ErrCode(err), gc.Equals, params.CodeUnauthorized) 272 s.assertModelKeys(c, []string{key1}) 273 } 274 275 func (s *keyManagerSuite) assertDeleteKeys(c *gc.C, st *state.State, apiUser names.UserTag, ok bool) { 276 anAuthoriser := s.authoriser 277 anAuthoriser.Tag = apiUser 278 var err error 279 s.keymanager, err = keymanager.NewKeyManagerAPI(st, s.resources, anAuthoriser) 280 c.Assert(err, jc.ErrorIsNil) 281 282 key1 := sshtesting.ValidKeyOne.Key + " user@host" 283 key2 := sshtesting.ValidKeyTwo.Key 284 initialKeys := []string{key1, key2, "bad key"} 285 s.setAuthorisedKeysForModel(c, st, strings.Join(initialKeys, "\n")) 286 287 args := params.ModifyUserSSHKeys{ 288 User: s.AdminUserTag(c).Name(), 289 Keys: []string{sshtesting.ValidKeyTwo.Fingerprint, sshtesting.ValidKeyThree.Fingerprint, "invalid-key"}, 290 } 291 results, err := s.keymanager.DeleteKeys(args) 292 if !ok { 293 c.Assert(err, gc.ErrorMatches, "permission denied") 294 c.Assert(params.ErrCode(err), gc.Equals, params.CodeUnauthorized) 295 return 296 } 297 c.Assert(err, jc.ErrorIsNil) 298 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 299 Results: []params.ErrorResult{ 300 {Error: nil}, 301 {Error: apiservertesting.ServerError("invalid ssh key: " + sshtesting.ValidKeyThree.Fingerprint)}, 302 {Error: apiservertesting.ServerError("invalid ssh key: invalid-key")}, 303 }, 304 }) 305 s.assertKeysForModel(c, st, []string{key1, "bad key"}) 306 } 307 308 func (s *keyManagerSuite) TestDeleteKeys(c *gc.C) { 309 s.assertDeleteKeys(c, s.State, s.AdminUserTag(c), true) 310 } 311 312 func (s *keyManagerSuite) TestDeleteKeysSuperUser(c *gc.C) { 313 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "superuser-fred", NoModelUser: true}) 314 s.assertDeleteKeys(c, s.State, user.UserTag(), true) 315 } 316 317 func (s *keyManagerSuite) TestDeleteKeysModelAdmin(c *gc.C) { 318 otherState := s.Factory.MakeModel(c, nil) 319 defer otherState.Close() 320 321 otherModel, err := otherState.Model() 322 c.Assert(err, jc.ErrorIsNil) 323 324 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "admin" + otherModel.ModelTag().String()}) 325 s.assertDeleteKeys(c, otherState, user.UserTag(), true) 326 } 327 328 func (s *keyManagerSuite) TestDeleteKeysNonAuthorised(c *gc.C) { 329 user := s.Factory.MakeUser(c, nil) 330 s.assertDeleteKeys(c, s.State, user.UserTag(), false) 331 } 332 333 func (s *keyManagerSuite) TestDeleteKeysNotJujuInternal(c *gc.C) { 334 key1 := sshtesting.ValidKeyOne.Key + " juju-client-key" 335 key2 := sshtesting.ValidKeyTwo.Key + " juju-system-key" 336 key3 := sshtesting.ValidKeyThree.Key + " a user key" 337 initialKeys := []string{key1, key2, key3} 338 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 339 340 args := params.ModifyUserSSHKeys{ 341 User: s.AdminUserTag(c).Name(), 342 Keys: []string{"juju-client-key", "juju-system-key"}, 343 } 344 results, err := s.keymanager.DeleteKeys(args) 345 c.Check(results, gc.DeepEquals, params.ErrorResults{ 346 Results: []params.ErrorResult{ 347 {Error: apiservertesting.ServerError("may not delete internal key: juju-client-key")}, 348 {Error: apiservertesting.ServerError("may not delete internal key: juju-system-key")}, 349 }, 350 }) 351 c.Assert(err, jc.ErrorIsNil) 352 s.assertModelKeys(c, initialKeys) 353 } 354 355 func (s *keyManagerSuite) TestBlockDeleteKeys(c *gc.C) { 356 key1 := sshtesting.ValidKeyOne.Key + " user@host" 357 key2 := sshtesting.ValidKeyTwo.Key 358 initialKeys := []string{key1, key2, "bad key"} 359 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 360 361 args := params.ModifyUserSSHKeys{ 362 User: s.AdminUserTag(c).Name(), 363 Keys: []string{sshtesting.ValidKeyTwo.Fingerprint, sshtesting.ValidKeyThree.Fingerprint, "invalid-key"}, 364 } 365 366 s.BlockAllChanges(c, "TestBlockDeleteKeys") 367 _, err := s.keymanager.DeleteKeys(args) 368 // Check that the call is blocked 369 s.AssertBlocked(c, err, "TestBlockDeleteKeys") 370 s.assertModelKeys(c, initialKeys) 371 } 372 373 func (s *keyManagerSuite) TestCannotDeleteAllKeys(c *gc.C) { 374 key1 := sshtesting.ValidKeyOne.Key + " user@host" 375 key2 := sshtesting.ValidKeyTwo.Key 376 initialKeys := []string{key1, key2} 377 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 378 379 args := params.ModifyUserSSHKeys{ 380 User: s.AdminUserTag(c).Name(), 381 Keys: []string{sshtesting.ValidKeyTwo.Fingerprint, "user@host"}, 382 } 383 _, err := s.keymanager.DeleteKeys(args) 384 c.Assert(err, gc.ErrorMatches, "cannot delete all keys") 385 s.assertModelKeys(c, initialKeys) 386 } 387 388 func (s *keyManagerSuite) assertInvalidUserOperation(c *gc.C, runTestLogic func(args params.ModifyUserSSHKeys) error) { 389 initialKey := sshtesting.ValidKeyOne.Key + " user@host" 390 s.setAuthorisedKeys(c, initialKey) 391 392 // Set up the params. 393 newKey := sshtesting.ValidKeyThree.Key + " newuser@host" 394 args := params.ModifyUserSSHKeys{ 395 User: "invalid", 396 Keys: []string{newKey}, 397 } 398 // Run the required test code and check the error. 399 err := runTestLogic(args) 400 c.Assert(err, gc.DeepEquals, apiservertesting.ErrUnauthorized) 401 402 // No model changes. 403 s.assertModelKeys(c, []string{initialKey}) 404 } 405 406 func (s *keyManagerSuite) TestAddKeysInvalidUser(c *gc.C) { 407 c.Skip("no user validation done yet") 408 s.assertInvalidUserOperation(c, func(args params.ModifyUserSSHKeys) error { 409 _, err := s.keymanager.AddKeys(args) 410 return err 411 }) 412 } 413 414 func (s *keyManagerSuite) TestDeleteKeysInvalidUser(c *gc.C) { 415 c.Skip("no user validation done yet") 416 s.assertInvalidUserOperation(c, func(args params.ModifyUserSSHKeys) error { 417 _, err := s.keymanager.DeleteKeys(args) 418 return err 419 }) 420 } 421 422 func (s *keyManagerSuite) assertImportKeys(c *gc.C, st *state.State, apiUser names.UserTag, ok bool) { 423 s.PatchValue(&keymanager.RunSSHImportId, keymanagertesting.FakeImport) 424 425 key1 := sshtesting.ValidKeyOne.Key + " user@host" 426 key2 := sshtesting.ValidKeyTwo.Key 427 key3 := sshtesting.ValidKeyThree.Key 428 key4 := sshtesting.ValidKeyFour.Key 429 keymv := strings.Split(sshtesting.ValidKeyMulti, "\n") 430 keymp := strings.Split(sshtesting.PartValidKeyMulti, "\n") 431 keymi := strings.Split(sshtesting.MultiInvalid, "\n") 432 initialKeys := []string{key1, key2, "bad key"} 433 s.setAuthorisedKeysForModel(c, st, strings.Join(initialKeys, "\n")) 434 435 args := params.ModifyUserSSHKeys{ 436 User: s.AdminUserTag(c).Name(), 437 Keys: []string{ 438 "lp:existing", 439 "lp:validuser", 440 "invalid-key", 441 "lp:multi", 442 "lp:multiempty", 443 "lp:multipartial", 444 "lp:multiinvalid", 445 "lp:multionedup", 446 }, 447 } 448 449 anAuthoriser := s.authoriser 450 anAuthoriser.Tag = apiUser 451 var err error 452 s.keymanager, err = keymanager.NewKeyManagerAPI(st, s.resources, anAuthoriser) 453 c.Assert(err, jc.ErrorIsNil) 454 455 results, err := s.keymanager.ImportKeys(args) 456 if !ok { 457 c.Assert(err, gc.ErrorMatches, "permission denied") 458 c.Assert(params.ErrCode(err), gc.Equals, params.CodeUnauthorized) 459 return 460 } 461 c.Assert(err, jc.ErrorIsNil) 462 463 c.Assert(results.Results, gc.HasLen, 8) 464 c.Assert(results, gc.DeepEquals, params.ErrorResults{ 465 Results: []params.ErrorResult{ 466 {Error: apiservertesting.ServerError(fmt.Sprintf("duplicate ssh key: %s", key2))}, 467 {Error: nil}, 468 {Error: apiservertesting.ServerError("invalid ssh key id: invalid-key")}, 469 {Error: nil}, 470 {Error: apiservertesting.ServerError("invalid ssh key id: lp:multiempty")}, 471 {Error: apiservertesting.ServerError(fmt.Sprintf( 472 `invalid ssh key for lp:multipartial: `+ 473 `generating key fingerprint: `+ 474 `invalid authorized_key "%s"`, keymp[1]))}, 475 {Error: apiservertesting.ServerError(fmt.Sprintf( 476 `invalid ssh key for lp:multiinvalid: `+ 477 `generating key fingerprint: `+ 478 `invalid authorized_key "%s"`+"\n"+ 479 `invalid ssh key for lp:multiinvalid: `+ 480 `generating key fingerprint: `+ 481 `invalid authorized_key "%s"`, keymi[0], keymi[1]))}, 482 {Error: apiservertesting.ServerError(fmt.Sprintf("duplicate ssh key: %s", key2))}, 483 }, 484 }) 485 s.assertKeysForModel(c, st, append(initialKeys, key3, keymv[0], keymv[1], keymp[0], key4)) 486 } 487 488 func (s *keyManagerSuite) TestImportKeys(c *gc.C) { 489 s.assertImportKeys(c, s.State, s.AdminUserTag(c), true) 490 } 491 492 func (s *keyManagerSuite) TestImportKeysSuperUser(c *gc.C) { 493 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "superuser-fred", NoModelUser: true}) 494 s.assertImportKeys(c, s.State, user.UserTag(), true) 495 } 496 497 func (s *keyManagerSuite) TestImportKeysModelAdmin(c *gc.C) { 498 otherState := s.Factory.MakeModel(c, nil) 499 defer otherState.Close() 500 501 otherModel, err := otherState.Model() 502 c.Assert(err, jc.ErrorIsNil) 503 504 user := s.Factory.MakeUser(c, &factory.UserParams{Name: "admin" + otherModel.ModelTag().String()}) 505 s.assertImportKeys(c, otherState, user.UserTag(), true) 506 } 507 508 func (s *keyManagerSuite) TestImportKeysNonAuthorised(c *gc.C) { 509 user := s.Factory.MakeUser(c, nil) 510 s.assertImportKeys(c, s.State, user.UserTag(), false) 511 } 512 513 func (s *keyManagerSuite) TestBlockImportKeys(c *gc.C) { 514 s.PatchValue(&keymanager.RunSSHImportId, keymanagertesting.FakeImport) 515 516 key1 := sshtesting.ValidKeyOne.Key + " user@host" 517 key2 := sshtesting.ValidKeyTwo.Key 518 initialKeys := []string{key1, key2, "bad key"} 519 s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n")) 520 521 args := params.ModifyUserSSHKeys{ 522 User: s.AdminUserTag(c).Name(), 523 Keys: []string{"lp:existing", "lp:validuser", "invalid-key"}, 524 } 525 526 s.BlockAllChanges(c, "TestBlockImportKeys") 527 _, err := s.keymanager.ImportKeys(args) 528 // Check that the call is blocked 529 s.AssertBlocked(c, err, "TestBlockImportKeys") 530 s.assertModelKeys(c, initialKeys) 531 }