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

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package user_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/cmd"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  	"gopkg.in/juju/names.v2"
    13  
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/cmd/juju/user"
    16  	"github.com/juju/juju/juju"
    17  	"github.com/juju/juju/jujuclient"
    18  	coretesting "github.com/juju/juju/testing"
    19  )
    20  
    21  type LoginCommandSuite struct {
    22  	BaseSuite
    23  	mockAPI  *mockLoginAPI
    24  	loginErr error
    25  }
    26  
    27  var _ = gc.Suite(&LoginCommandSuite{})
    28  
    29  func (s *LoginCommandSuite) SetUpTest(c *gc.C) {
    30  	s.BaseSuite.SetUpTest(c)
    31  	s.mockAPI = &mockLoginAPI{}
    32  	s.loginErr = nil
    33  }
    34  
    35  func (s *LoginCommandSuite) run(c *gc.C, stdin string, args ...string) (*cmd.Context, juju.NewAPIConnectionParams, error) {
    36  	var argsOut juju.NewAPIConnectionParams
    37  	cmd, _ := user.NewLoginCommandForTest(func(args juju.NewAPIConnectionParams) (user.LoginAPI, user.ConnectionAPI, error) {
    38  		argsOut = args
    39  		// The account details are modified in place, so take a copy.
    40  		accountDetails := *argsOut.AccountDetails
    41  		argsOut.AccountDetails = &accountDetails
    42  		if s.loginErr != nil {
    43  			err := s.loginErr
    44  			s.loginErr = nil
    45  			return nil, nil, err
    46  		}
    47  		return s.mockAPI, s.mockAPI, nil
    48  	}, s.store)
    49  	ctx := coretesting.Context(c)
    50  	if stdin == "" {
    51  		stdin = "sekrit\n"
    52  	}
    53  	ctx.Stdin = strings.NewReader(stdin)
    54  	err := coretesting.InitCommand(cmd, args)
    55  	if err != nil {
    56  		return nil, argsOut, err
    57  	}
    58  	err = cmd.Run(ctx)
    59  	return ctx, argsOut, err
    60  }
    61  
    62  func (s *LoginCommandSuite) TestInit(c *gc.C) {
    63  	for i, test := range []struct {
    64  		args        []string
    65  		user        string
    66  		errorString string
    67  	}{
    68  		{
    69  		// no args is fine
    70  		}, {
    71  			args: []string{"foobar"},
    72  			user: "foobar",
    73  		}, {
    74  			args:        []string{"--foobar"},
    75  			errorString: "flag provided but not defined: --foobar",
    76  		}, {
    77  			args:        []string{"foobar", "extra"},
    78  			errorString: `unrecognized args: \["extra"\]`,
    79  		},
    80  	} {
    81  		c.Logf("test %d", i)
    82  		wrappedCommand, command := user.NewLoginCommandForTest(nil, s.store)
    83  		err := coretesting.InitCommand(wrappedCommand, test.args)
    84  		if test.errorString == "" {
    85  			c.Check(command.User, gc.Equals, test.user)
    86  		} else {
    87  			c.Check(err, gc.ErrorMatches, test.errorString)
    88  		}
    89  	}
    90  }
    91  
    92  func (s *LoginCommandSuite) TestLogin(c *gc.C) {
    93  	context, args, err := s.run(c, "current-user\nsekrit\n")
    94  	c.Assert(err, jc.ErrorIsNil)
    95  	c.Assert(coretesting.Stdout(context), gc.Equals, "")
    96  	c.Assert(coretesting.Stderr(context), gc.Equals, `
    97  username: You are now logged in to "testing" as "current-user@local".
    98  `[1:],
    99  	)
   100  	s.assertStorePassword(c, "current-user@local", "", "superuser")
   101  	c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{
   102  		User: "current-user@local",
   103  	})
   104  }
   105  
   106  func (s *LoginCommandSuite) TestLoginNewUser(c *gc.C) {
   107  	err := s.store.RemoveAccount("testing")
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	context, args, err := s.run(c, "", "new-user")
   110  	c.Assert(err, jc.ErrorIsNil)
   111  	c.Assert(coretesting.Stdout(context), gc.Equals, "")
   112  	c.Assert(coretesting.Stderr(context), gc.Equals, `
   113  You are now logged in to "testing" as "new-user@local".
   114  `[1:],
   115  	)
   116  	s.assertStorePassword(c, "new-user@local", "", "superuser")
   117  	c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{
   118  		User: "new-user@local",
   119  	})
   120  }
   121  
   122  func (s *LoginCommandSuite) TestLoginAlreadyLoggedInSameUser(c *gc.C) {
   123  	_, _, err := s.run(c, "", "current-user")
   124  	c.Assert(err, jc.ErrorIsNil)
   125  }
   126  
   127  func (s *LoginCommandSuite) TestLoginAlreadyLoggedInDifferentUser(c *gc.C) {
   128  	_, _, err := s.run(c, "", "other-user")
   129  	c.Assert(err, gc.ErrorMatches, `already logged in
   130  
   131  Run "juju logout" first before attempting to log in as a different user.
   132  `)
   133  }
   134  
   135  func (s *LoginCommandSuite) TestLoginWithMacaroons(c *gc.C) {
   136  	err := s.store.RemoveAccount("testing")
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	context, args, err := s.run(c, "")
   139  	c.Assert(err, jc.ErrorIsNil)
   140  	c.Assert(coretesting.Stdout(context), gc.Equals, "")
   141  	c.Assert(coretesting.Stderr(context), gc.Equals, `
   142  You are now logged in to "testing" as "user@external".
   143  `[1:],
   144  	)
   145  	c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{})
   146  }
   147  
   148  func (s *LoginCommandSuite) TestLoginWithMacaroonsNotSupported(c *gc.C) {
   149  	err := s.store.RemoveAccount("testing")
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	s.loginErr = &params.Error{Code: params.CodeNoCreds, Message: "barf"}
   152  	context, _, err := s.run(c, "new-user\nsekrit\n")
   153  	c.Assert(err, jc.ErrorIsNil)
   154  	c.Assert(coretesting.Stdout(context), gc.Equals, "")
   155  	c.Assert(coretesting.Stderr(context), gc.Equals, `
   156  username: You are now logged in to "testing" as "new-user@local".
   157  `[1:],
   158  	)
   159  }
   160  
   161  type mockLoginAPI struct{}
   162  
   163  func (*mockLoginAPI) Close() error {
   164  	return nil
   165  }
   166  
   167  func (*mockLoginAPI) AuthTag() names.Tag {
   168  	return names.NewUserTag("user@external")
   169  }
   170  
   171  func (*mockLoginAPI) ControllerAccess() string {
   172  	return "superuser"
   173  }