github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/state/api/keymanager/client_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  	jujutesting "launchpad.net/juju-core/juju/testing"
    12  	"launchpad.net/juju-core/state"
    13  	"launchpad.net/juju-core/state/api/keymanager"
    14  	"launchpad.net/juju-core/state/api/params"
    15  	keymanagerserver "launchpad.net/juju-core/state/apiserver/keymanager"
    16  	keymanagertesting "launchpad.net/juju-core/state/apiserver/keymanager/testing"
    17  	"launchpad.net/juju-core/state/testing"
    18  	"launchpad.net/juju-core/utils/ssh"
    19  	sshtesting "launchpad.net/juju-core/utils/ssh/testing"
    20  )
    21  
    22  type keymanagerSuite struct {
    23  	jujutesting.JujuConnSuite
    24  
    25  	keymanager *keymanager.Client
    26  }
    27  
    28  var _ = gc.Suite(&keymanagerSuite{})
    29  
    30  func (s *keymanagerSuite) SetUpTest(c *gc.C) {
    31  	s.JujuConnSuite.SetUpTest(c)
    32  	s.keymanager = keymanager.NewClient(s.APIState)
    33  	c.Assert(s.keymanager, gc.NotNil)
    34  
    35  }
    36  
    37  func (s *keymanagerSuite) setAuthorisedKeys(c *gc.C, keys string) {
    38  	err := testing.UpdateConfig(s.BackingState, map[string]interface{}{"authorized-keys": keys})
    39  	c.Assert(err, gc.IsNil)
    40  }
    41  
    42  func (s *keymanagerSuite) TestListKeys(c *gc.C) {
    43  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
    44  	key2 := sshtesting.ValidKeyTwo.Key
    45  	s.setAuthorisedKeys(c, strings.Join([]string{key1, key2}, "\n"))
    46  
    47  	keyResults, err := s.keymanager.ListKeys(ssh.Fingerprints, "admin")
    48  	c.Assert(err, gc.IsNil)
    49  	c.Assert(len(keyResults), gc.Equals, 1)
    50  	result := keyResults[0]
    51  	c.Assert(result.Error, gc.IsNil)
    52  	c.Assert(result.Result, gc.DeepEquals,
    53  		[]string{sshtesting.ValidKeyOne.Fingerprint + " (user@host)", sshtesting.ValidKeyTwo.Fingerprint})
    54  }
    55  
    56  func (s *keymanagerSuite) TestListKeysErrors(c *gc.C) {
    57  	keyResults, err := s.keymanager.ListKeys(ssh.Fingerprints, "invalid")
    58  	c.Assert(err, gc.IsNil)
    59  	c.Assert(len(keyResults), gc.Equals, 1)
    60  	result := keyResults[0]
    61  	c.Assert(result.Error, gc.ErrorMatches, `permission denied`)
    62  }
    63  
    64  func clientError(message string) *params.Error {
    65  	return &params.Error{
    66  		Message: message,
    67  		Code:    "",
    68  	}
    69  }
    70  
    71  func (s *keymanagerSuite) assertEnvironKeys(c *gc.C, expected []string) {
    72  	envConfig, err := s.State.EnvironConfig()
    73  	c.Assert(err, gc.IsNil)
    74  	keys := envConfig.AuthorizedKeys()
    75  	c.Assert(keys, gc.Equals, strings.Join(expected, "\n"))
    76  }
    77  
    78  func (s *keymanagerSuite) TestAddKeys(c *gc.C) {
    79  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
    80  	s.setAuthorisedKeys(c, key1)
    81  
    82  	newKeys := []string{sshtesting.ValidKeyTwo.Key, sshtesting.ValidKeyThree.Key, "invalid"}
    83  	errResults, err := s.keymanager.AddKeys("admin", newKeys...)
    84  	c.Assert(err, gc.IsNil)
    85  	c.Assert(errResults, gc.DeepEquals, []params.ErrorResult{
    86  		{Error: nil},
    87  		{Error: nil},
    88  		{Error: clientError("invalid ssh key: invalid")},
    89  	})
    90  	s.assertEnvironKeys(c, append([]string{key1}, newKeys[:2]...))
    91  }
    92  
    93  func (s *keymanagerSuite) TestAddSystemKey(c *gc.C) {
    94  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
    95  	s.setAuthorisedKeys(c, key1)
    96  
    97  	apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageEnviron)
    98  	keyManager := keymanager.NewClient(apiState)
    99  	newKey := sshtesting.ValidKeyTwo.Key
   100  	errResults, err := keyManager.AddKeys("juju-system-key", newKey)
   101  	c.Assert(err, gc.IsNil)
   102  	c.Assert(errResults, gc.DeepEquals, []params.ErrorResult{
   103  		{Error: nil},
   104  	})
   105  	s.assertEnvironKeys(c, []string{key1, newKey})
   106  }
   107  
   108  func (s *keymanagerSuite) TestAddSystemKeyWrongUser(c *gc.C) {
   109  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   110  	s.setAuthorisedKeys(c, key1)
   111  
   112  	apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageEnviron)
   113  	keyManager := keymanager.NewClient(apiState)
   114  	newKey := sshtesting.ValidKeyTwo.Key
   115  	_, err := keyManager.AddKeys("some-user", newKey)
   116  	c.Assert(err, gc.ErrorMatches, "permission denied")
   117  	s.assertEnvironKeys(c, []string{key1})
   118  }
   119  
   120  func (s *keymanagerSuite) TestDeleteKeys(c *gc.C) {
   121  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   122  	key2 := sshtesting.ValidKeyTwo.Key
   123  	key3 := sshtesting.ValidKeyThree.Key
   124  	initialKeys := []string{key1, key2, key3, "invalid"}
   125  	s.setAuthorisedKeys(c, strings.Join(initialKeys, "\n"))
   126  
   127  	errResults, err := s.keymanager.DeleteKeys("admin", sshtesting.ValidKeyTwo.Fingerprint, "user@host", "missing")
   128  	c.Assert(err, gc.IsNil)
   129  	c.Assert(errResults, gc.DeepEquals, []params.ErrorResult{
   130  		{Error: nil},
   131  		{Error: nil},
   132  		{Error: clientError("invalid ssh key: missing")},
   133  	})
   134  	s.assertEnvironKeys(c, []string{"invalid", key3})
   135  }
   136  
   137  func (s *keymanagerSuite) TestImportKeys(c *gc.C) {
   138  	s.PatchValue(&keymanagerserver.RunSSHImportId, keymanagertesting.FakeImport)
   139  
   140  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   141  	s.setAuthorisedKeys(c, key1)
   142  
   143  	keyIds := []string{"lp:validuser", "invalid-key"}
   144  	errResults, err := s.keymanager.ImportKeys("admin", keyIds...)
   145  	c.Assert(err, gc.IsNil)
   146  	c.Assert(errResults, gc.DeepEquals, []params.ErrorResult{
   147  		{Error: nil},
   148  		{Error: clientError("invalid ssh key id: invalid-key")},
   149  	})
   150  	s.assertEnvironKeys(c, []string{key1, sshtesting.ValidKeyThree.Key})
   151  }
   152  
   153  func (s *keymanagerSuite) assertInvalidUserOperation(c *gc.C, test func(user string, keys []string) error) {
   154  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   155  	s.setAuthorisedKeys(c, key1)
   156  
   157  	// Run the required test code and check the error.
   158  	keys := []string{sshtesting.ValidKeyTwo.Key, sshtesting.ValidKeyThree.Key}
   159  	err := test("invalid", keys)
   160  	c.Assert(err, gc.ErrorMatches, `permission denied`)
   161  
   162  	// No environ changes.
   163  	s.assertEnvironKeys(c, []string{key1})
   164  }
   165  
   166  func (s *keymanagerSuite) TestAddKeysInvalidUser(c *gc.C) {
   167  	s.assertInvalidUserOperation(c, func(user string, keys []string) error {
   168  		_, err := s.keymanager.AddKeys(user, keys...)
   169  		return err
   170  	})
   171  }
   172  
   173  func (s *keymanagerSuite) TestDeleteKeysInvalidUser(c *gc.C) {
   174  	s.assertInvalidUserOperation(c, func(user string, keys []string) error {
   175  		_, err := s.keymanager.DeleteKeys(user, keys...)
   176  		return err
   177  	})
   178  }
   179  
   180  func (s *keymanagerSuite) TestImportKeysInvalidUser(c *gc.C) {
   181  	s.assertInvalidUserOperation(c, func(user string, keys []string) error {
   182  		_, err := s.keymanager.ImportKeys(user, keys...)
   183  		return err
   184  	})
   185  }