github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/cmd/juju/authorizedkeys_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	gc "launchpad.net/gocheck"
    11  
    12  	"github.com/juju/juju/cmd/envcmd"
    13  	"github.com/juju/juju/juju/osenv"
    14  	jujutesting "github.com/juju/juju/juju/testing"
    15  	keymanagerserver "github.com/juju/juju/state/apiserver/keymanager"
    16  	keymanagertesting "github.com/juju/juju/state/apiserver/keymanager/testing"
    17  	coretesting "github.com/juju/juju/testing"
    18  	"github.com/juju/juju/testing/factory"
    19  	sshtesting "github.com/juju/juju/utils/ssh/testing"
    20  )
    21  
    22  type AuthorizedKeysSuite struct {
    23  	coretesting.FakeJujuHomeSuite
    24  }
    25  
    26  var _ = gc.Suite(&AuthorizedKeysSuite{})
    27  
    28  var authKeysCommandNames = []string{
    29  	"add",
    30  	"delete",
    31  	"help",
    32  	"import",
    33  	"list",
    34  }
    35  
    36  func (s *AuthorizedKeysSuite) TestHelpCommands(c *gc.C) {
    37  	// Check that we have correctly registered all the sub commands
    38  	// by checking the help output.
    39  	out := badrun(c, 0, "authorized-keys", "--help")
    40  	lines := strings.Split(out, "\n")
    41  	var names []string
    42  	subcommandsFound := false
    43  	for _, line := range lines {
    44  		f := strings.Fields(line)
    45  		if len(f) == 1 && f[0] == "commands:" {
    46  			subcommandsFound = true
    47  			continue
    48  		}
    49  		if !subcommandsFound || len(f) == 0 || !strings.HasPrefix(line, "    ") {
    50  			continue
    51  		}
    52  		names = append(names, f[0])
    53  	}
    54  	// The names should be output in alphabetical order, so don't sort.
    55  	c.Assert(names, gc.DeepEquals, authKeysCommandNames)
    56  }
    57  
    58  func (s *AuthorizedKeysSuite) assertHelpOutput(c *gc.C, cmd, args string) {
    59  	if args != "" {
    60  		args = " " + args
    61  	}
    62  	expected := fmt.Sprintf("usage: juju authorized-keys %s [options]%s", cmd, args)
    63  	out := badrun(c, 0, "authorized-keys", cmd, "--help")
    64  	lines := strings.Split(out, "\n")
    65  	c.Assert(lines[0], gc.Equals, expected)
    66  }
    67  
    68  func (s *AuthorizedKeysSuite) TestHelpList(c *gc.C) {
    69  	s.assertHelpOutput(c, "list", "")
    70  }
    71  
    72  func (s *AuthorizedKeysSuite) TestHelpAdd(c *gc.C) {
    73  	s.assertHelpOutput(c, "add", "<ssh key> [...]")
    74  }
    75  
    76  func (s *AuthorizedKeysSuite) TestHelpDelete(c *gc.C) {
    77  	s.assertHelpOutput(c, "delete", "<ssh key id> [...]")
    78  }
    79  
    80  func (s *AuthorizedKeysSuite) TestHelpImport(c *gc.C) {
    81  	s.assertHelpOutput(c, "import", "<ssh key id> [...]")
    82  }
    83  
    84  type keySuiteBase struct {
    85  	jujutesting.JujuConnSuite
    86  }
    87  
    88  func (s *keySuiteBase) SetUpSuite(c *gc.C) {
    89  	s.JujuConnSuite.SetUpSuite(c)
    90  	s.PatchEnvironment(osenv.JujuEnvEnvKey, "dummyenv")
    91  }
    92  
    93  func (s *keySuiteBase) setAuthorizedKeys(c *gc.C, keys ...string) {
    94  	keyString := strings.Join(keys, "\n")
    95  	err := s.State.UpdateEnvironConfig(map[string]interface{}{"authorized-keys": keyString}, nil, nil)
    96  	c.Assert(err, gc.IsNil)
    97  	envConfig, err := s.State.EnvironConfig()
    98  	c.Assert(err, gc.IsNil)
    99  	c.Assert(envConfig.AuthorizedKeys(), gc.Equals, keyString)
   100  }
   101  
   102  func (s *keySuiteBase) assertEnvironKeys(c *gc.C, expected ...string) {
   103  	envConfig, err := s.State.EnvironConfig()
   104  	c.Assert(err, gc.IsNil)
   105  	keys := envConfig.AuthorizedKeys()
   106  	c.Assert(keys, gc.Equals, strings.Join(expected, "\n"))
   107  }
   108  
   109  type ListKeysSuite struct {
   110  	keySuiteBase
   111  }
   112  
   113  var _ = gc.Suite(&ListKeysSuite{})
   114  
   115  func (s *ListKeysSuite) TestListKeys(c *gc.C) {
   116  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   117  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   118  	s.setAuthorizedKeys(c, key1, key2)
   119  
   120  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}))
   121  	c.Assert(err, gc.IsNil)
   122  	output := strings.TrimSpace(coretesting.Stdout(context))
   123  	c.Assert(err, gc.IsNil)
   124  	c.Assert(output, gc.Matches, "Keys for user admin:\n.*\\(user@host\\)\n.*\\(another@host\\)")
   125  }
   126  
   127  func (s *ListKeysSuite) TestListFullKeys(c *gc.C) {
   128  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   129  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   130  	s.setAuthorizedKeys(c, key1, key2)
   131  
   132  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), "--full")
   133  	c.Assert(err, gc.IsNil)
   134  	output := strings.TrimSpace(coretesting.Stdout(context))
   135  	c.Assert(err, gc.IsNil)
   136  	c.Assert(output, gc.Matches, "Keys for user admin:\n.*user@host\n.*another@host")
   137  }
   138  
   139  func (s *ListKeysSuite) TestListKeysNonDefaultUser(c *gc.C) {
   140  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   141  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   142  	s.setAuthorizedKeys(c, key1, key2)
   143  	s.Factory.MakeUser(factory.UserParams{Username: "fred"})
   144  
   145  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), "--user", "fred")
   146  	c.Assert(err, gc.IsNil)
   147  	output := strings.TrimSpace(coretesting.Stdout(context))
   148  	c.Assert(err, gc.IsNil)
   149  	c.Assert(output, gc.Matches, "Keys for user fred:\n.*\\(user@host\\)\n.*\\(another@host\\)")
   150  }
   151  
   152  func (s *ListKeysSuite) TestTooManyArgs(c *gc.C) {
   153  	_, err := coretesting.RunCommand(c, envcmd.Wrap(&ListKeysCommand{}), "foo")
   154  	c.Assert(err, gc.ErrorMatches, `unrecognized args: \["foo"\]`)
   155  }
   156  
   157  type AddKeySuite struct {
   158  	keySuiteBase
   159  }
   160  
   161  var _ = gc.Suite(&AddKeySuite{})
   162  
   163  func (s *AddKeySuite) TestAddKey(c *gc.C) {
   164  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   165  	s.setAuthorizedKeys(c, key1)
   166  
   167  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   168  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&AddKeysCommand{}), key2, "invalid-key")
   169  	c.Assert(err, gc.IsNil)
   170  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot add key "invalid-key".*\n`)
   171  	s.assertEnvironKeys(c, key1, key2)
   172  }
   173  
   174  func (s *AddKeySuite) TestAddKeyNonDefaultUser(c *gc.C) {
   175  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   176  	s.setAuthorizedKeys(c, key1)
   177  	s.Factory.MakeUser(factory.UserParams{Username: "fred"})
   178  
   179  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   180  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&AddKeysCommand{}), "--user", "fred", key2)
   181  	c.Assert(err, gc.IsNil)
   182  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   183  	s.assertEnvironKeys(c, key1, key2)
   184  }
   185  
   186  type DeleteKeySuite struct {
   187  	keySuiteBase
   188  }
   189  
   190  var _ = gc.Suite(&DeleteKeySuite{})
   191  
   192  func (s *DeleteKeySuite) TestDeleteKeys(c *gc.C) {
   193  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   194  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   195  	s.setAuthorizedKeys(c, key1, key2)
   196  
   197  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&DeleteKeysCommand{}),
   198  		sshtesting.ValidKeyTwo.Fingerprint, "invalid-key")
   199  	c.Assert(err, gc.IsNil)
   200  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot delete key id "invalid-key".*\n`)
   201  	s.assertEnvironKeys(c, key1)
   202  }
   203  
   204  func (s *DeleteKeySuite) TestDeleteKeyNonDefaultUser(c *gc.C) {
   205  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   206  	key2 := sshtesting.ValidKeyTwo.Key + " another@host"
   207  	s.setAuthorizedKeys(c, key1, key2)
   208  	s.Factory.MakeUser(factory.UserParams{Username: "fred"})
   209  
   210  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&DeleteKeysCommand{}),
   211  		"--user", "fred", sshtesting.ValidKeyTwo.Fingerprint)
   212  	c.Assert(err, gc.IsNil)
   213  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   214  	s.assertEnvironKeys(c, key1)
   215  }
   216  
   217  type ImportKeySuite struct {
   218  	keySuiteBase
   219  }
   220  
   221  var _ = gc.Suite(&ImportKeySuite{})
   222  
   223  func (s *ImportKeySuite) SetUpTest(c *gc.C) {
   224  	s.keySuiteBase.SetUpTest(c)
   225  	s.PatchValue(&keymanagerserver.RunSSHImportId, keymanagertesting.FakeImport)
   226  }
   227  
   228  func (s *ImportKeySuite) TestImportKeys(c *gc.C) {
   229  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   230  	s.setAuthorizedKeys(c, key1)
   231  
   232  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&ImportKeysCommand{}), "lp:validuser", "invalid-key")
   233  	c.Assert(err, gc.IsNil)
   234  	c.Assert(coretesting.Stderr(context), gc.Matches, `cannot import key id "invalid-key".*\n`)
   235  	s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
   236  }
   237  
   238  func (s *ImportKeySuite) TestImportKeyNonDefaultUser(c *gc.C) {
   239  	key1 := sshtesting.ValidKeyOne.Key + " user@host"
   240  	s.setAuthorizedKeys(c, key1)
   241  	s.Factory.MakeUser(factory.UserParams{Username: "fred"})
   242  
   243  	context, err := coretesting.RunCommand(c, envcmd.Wrap(&ImportKeysCommand{}), "--user", "fred", "lp:validuser")
   244  	c.Assert(err, gc.IsNil)
   245  	c.Assert(coretesting.Stderr(context), gc.Equals, "")
   246  	s.assertEnvironKeys(c, key1, sshtesting.ValidKeyThree.Key)
   247  }