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