1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
11
"github.com/juju/names"
12
jc "github.com/juju/testing/checkers"
13
gc "gopkg.in/check.v1"
14
"gopkg.in/macaroon.v1"
16
"github.com/juju/juju/cmd/juju/user"
17
"github.com/juju/juju/juju"
18
"github.com/juju/juju/jujuclient"
19
coretesting "github.com/juju/juju/testing"
22
type LoginCommandSuite struct {
27
var _ = gc.Suite(&LoginCommandSuite{})
29
func (s *LoginCommandSuite) SetUpTest(c *gc.C) {
30
s.BaseSuite.SetUpTest(c)
31
s.mockAPI = &mockLoginAPI{}
34
func (s *LoginCommandSuite) run(c *gc.C, args ...string) (*cmd.Context, juju.NewAPIConnectionParams, error) {
35
var argsOut juju.NewAPIConnectionParams
36
cmd, _ := user.NewLoginCommandForTest(func(args juju.NewAPIConnectionParams) (user.LoginAPI, error) {
38
// The account details are modified in place, so take a copy.
39
accountDetails := *argsOut.AccountDetails
40
argsOut.AccountDetails = &accountDetails
43
ctx := coretesting.Context(c)
44
ctx.Stdin = strings.NewReader("sekrit\nsekrit\n")
45
err := coretesting.InitCommand(cmd, args)
47
return nil, argsOut, err
50
return ctx, argsOut, err
53
func (s *LoginCommandSuite) TestInit(c *gc.C) {
54
for i, test := range []struct {
63
args: []string{"foobar"},
67
args: []string{"--foobar"},
68
errorString: "flag provided but not defined: --foobar",
70
args: []string{"foobar", "extra"},
71
errorString: `unrecognized args: \["extra"\]`,
75
wrappedCommand, command := user.NewLoginCommandForTest(nil, s.store)
76
err := coretesting.InitCommand(wrappedCommand, test.args)
77
if test.errorString == "" {
78
c.Check(command.User, gc.Equals, test.user)
80
c.Check(err, gc.ErrorMatches, test.errorString)
85
func (s *LoginCommandSuite) assertStorePassword(c *gc.C, user, pass string) {
86
details, err := s.store.AccountByName("testing", user)
87
c.Assert(err, jc.ErrorIsNil)
88
c.Assert(details.Password, gc.Equals, pass)
91
func (s *LoginCommandSuite) assertStoreMacaroon(c *gc.C, user string, mac *macaroon.Macaroon) {
92
details, err := s.store.AccountByName("testing", user)
93
c.Assert(err, jc.ErrorIsNil)
95
c.Assert(details.Macaroon, gc.Equals, "")
98
macaroonJSON, err := mac.MarshalJSON()
99
c.Assert(err, jc.ErrorIsNil)
100
c.Assert(details.Macaroon, gc.Equals, string(macaroonJSON))
103
func (s *LoginCommandSuite) TestLogin(c *gc.C) {
104
context, args, err := s.run(c)
105
c.Assert(err, jc.ErrorIsNil)
106
c.Assert(coretesting.Stdout(context), gc.Equals, "")
107
c.Assert(coretesting.Stderr(context), gc.Equals, `
110
You are now logged in to "testing" as "current-user@local".
113
s.assertStorePassword(c, "current-user@local", "")
114
s.assertStoreMacaroon(c, "current-user@local", fakeLocalLoginMacaroon(names.NewUserTag("current-user@local")))
115
c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{
116
User: "current-user@local",
121
func (s *LoginCommandSuite) TestLoginNewUser(c *gc.C) {
122
context, args, err := s.run(c, "new-user")
123
c.Assert(err, jc.ErrorIsNil)
124
c.Assert(coretesting.Stdout(context), gc.Equals, "")
125
c.Assert(coretesting.Stderr(context), gc.Equals, `
128
You are now logged in to "testing" as "new-user@local".
131
s.assertStorePassword(c, "new-user@local", "")
132
s.assertStoreMacaroon(c, "new-user@local", fakeLocalLoginMacaroon(names.NewUserTag("new-user@local")))
133
c.Assert(args.AccountDetails, jc.DeepEquals, &jujuclient.AccountDetails{
134
User: "new-user@local",
139
func (s *LoginCommandSuite) TestLoginFail(c *gc.C) {
140
s.mockAPI.SetErrors(errors.New("failed to do something"))
141
_, _, err := s.run(c)
142
c.Assert(err, gc.ErrorMatches, "failed to create a temporary credential: failed to do something")
143
s.assertStorePassword(c, "current-user@local", "old-password")
144
s.assertStoreMacaroon(c, "current-user@local", nil)
147
type mockLoginAPI struct {
148
mockChangePasswordAPI