github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/common/authkeys_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	jc "github.com/juju/testing/checkers"
    13  	"github.com/juju/utils"
    14  	"github.com/juju/utils/ssh"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/cmd/juju/common"
    18  	"github.com/juju/juju/testing"
    19  )
    20  
    21  type AuthKeysSuite struct {
    22  	testing.BaseSuite
    23  	dotssh string // ~/.ssh
    24  }
    25  
    26  var _ = gc.Suite(&AuthKeysSuite{})
    27  
    28  func (s *AuthKeysSuite) SetUpTest(c *gc.C) {
    29  	s.BaseSuite.SetUpTest(c)
    30  	old := utils.Home()
    31  	newhome := c.MkDir()
    32  	err := utils.SetHome(newhome)
    33  	c.Assert(err, jc.ErrorIsNil)
    34  	s.AddCleanup(func(*gc.C) {
    35  		ssh.ClearClientKeys()
    36  		err := utils.SetHome(old)
    37  		c.Assert(err, jc.ErrorIsNil)
    38  	})
    39  
    40  	s.dotssh = filepath.Join(newhome, ".ssh")
    41  	err = os.Mkdir(s.dotssh, 0755)
    42  	c.Assert(err, jc.ErrorIsNil)
    43  }
    44  
    45  func (s *AuthKeysSuite) TestReadAuthorizedKeysErrors(c *gc.C) {
    46  	ctx := testing.Context(c)
    47  	_, err := common.ReadAuthorizedKeys(ctx, "")
    48  	c.Assert(err, gc.ErrorMatches, "no public ssh keys found")
    49  	c.Assert(err, gc.Equals, common.ErrNoAuthorizedKeys)
    50  	_, err = common.ReadAuthorizedKeys(ctx, filepath.Join(s.dotssh, "notthere.pub"))
    51  	c.Assert(err, gc.ErrorMatches, "no public ssh keys found")
    52  	c.Assert(err, gc.Equals, common.ErrNoAuthorizedKeys)
    53  }
    54  
    55  func writeFile(c *gc.C, filename string, contents string) {
    56  	err := ioutil.WriteFile(filename, []byte(contents), 0644)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  }
    59  
    60  func (s *AuthKeysSuite) TestReadAuthorizedKeys(c *gc.C) {
    61  	ctx := testing.Context(c)
    62  	writeFile(c, filepath.Join(s.dotssh, "id_rsa.pub"), "id_rsa")
    63  	writeFile(c, filepath.Join(s.dotssh, "identity.pub"), "identity")
    64  	writeFile(c, filepath.Join(s.dotssh, "test.pub"), "test")
    65  	keys, err := common.ReadAuthorizedKeys(ctx, "")
    66  	c.Assert(err, jc.ErrorIsNil)
    67  	c.Assert(keys, gc.Equals, "id_rsa\nidentity\n")
    68  	keys, err = common.ReadAuthorizedKeys(ctx, "test.pub") // relative to ~/.ssh
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	c.Assert(keys, gc.Equals, "test\n")
    71  }
    72  
    73  func (s *AuthKeysSuite) TestReadAuthorizedKeysClientKeys(c *gc.C) {
    74  	ctx := testing.Context(c)
    75  	keydir := filepath.Join(s.dotssh, "juju")
    76  	err := ssh.LoadClientKeys(keydir) // auto-generates a key pair
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	pubkeyFiles := ssh.PublicKeyFiles()
    79  	c.Assert(pubkeyFiles, gc.HasLen, 1)
    80  	data, err := ioutil.ReadFile(pubkeyFiles[0])
    81  	c.Assert(err, jc.ErrorIsNil)
    82  	prefix := strings.Trim(string(data), "\n") + "\n"
    83  
    84  	writeFile(c, filepath.Join(s.dotssh, "id_rsa.pub"), "id_rsa")
    85  	writeFile(c, filepath.Join(s.dotssh, "test.pub"), "test")
    86  	keys, err := common.ReadAuthorizedKeys(ctx, "")
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	c.Assert(keys, gc.Equals, prefix+"id_rsa\n")
    89  	keys, err = common.ReadAuthorizedKeys(ctx, "test.pub")
    90  	c.Assert(err, jc.ErrorIsNil)
    91  	c.Assert(keys, gc.Equals, prefix+"test\n")
    92  	keys, err = common.ReadAuthorizedKeys(ctx, "notthere.pub")
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	c.Assert(keys, gc.Equals, prefix)
    95  }
    96  
    97  func (s *AuthKeysSuite) TestFinalizeAuthorizedKeysNoop(c *gc.C) {
    98  	attrs := map[string]interface{}{"authorized-keys": "meep"}
    99  	err := common.FinalizeAuthorizedKeys(testing.Context(c), attrs)
   100  	c.Assert(err, jc.ErrorIsNil)
   101  	c.Assert(attrs, jc.DeepEquals, map[string]interface{}{"authorized-keys": "meep"})
   102  }
   103  
   104  func (s *AuthKeysSuite) TestFinalizeAuthorizedKeysPath(c *gc.C) {
   105  	writeFile(c, filepath.Join(s.dotssh, "whatever"), "meep")
   106  	attrs := map[string]interface{}{"authorized-keys-path": "whatever"}
   107  	err := common.FinalizeAuthorizedKeys(testing.Context(c), attrs)
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(attrs, jc.DeepEquals, map[string]interface{}{"authorized-keys": "meep\n"})
   110  }
   111  
   112  func (s *AuthKeysSuite) TestFinalizeAuthorizedKeysDefault(c *gc.C) {
   113  	writeFile(c, filepath.Join(s.dotssh, "id_rsa.pub"), "meep")
   114  	attrs := map[string]interface{}{}
   115  	err := common.FinalizeAuthorizedKeys(testing.Context(c), attrs)
   116  	c.Assert(err, jc.ErrorIsNil)
   117  	c.Assert(attrs, jc.DeepEquals, map[string]interface{}{"authorized-keys": "meep\n"})
   118  }
   119  
   120  func (s *AuthKeysSuite) TestFinalizeAuthorizedKeysConflict(c *gc.C) {
   121  	attrs := map[string]interface{}{"authorized-keys": "foo", "authorized-keys-path": "bar"}
   122  	err := common.FinalizeAuthorizedKeys(testing.Context(c), attrs)
   123  	c.Assert(err, gc.ErrorMatches, `"authorized-keys" and "authorized-keys-path" may not both be specified`)
   124  }