1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"github.com/juju/errors"
10
jc "github.com/juju/testing/checkers"
11
gc "gopkg.in/check.v1"
12
"gopkg.in/juju/names.v2"
14
"github.com/juju/juju/apiserver/common"
15
"github.com/juju/juju/apiserver/params"
16
apiservertesting "github.com/juju/juju/apiserver/testing"
17
"github.com/juju/juju/state"
20
type passwordSuite struct{}
22
var _ = gc.Suite(&passwordSuite{})
24
type entityWithError interface {
29
type fakeState struct {
30
entities map[names.Tag]entityWithError
33
func (st *fakeState) FindEntity(tag names.Tag) (state.Entity, error) {
34
entity, ok := st.entities[tag]
36
return nil, errors.NotFoundf("entity %q", tag)
38
if err := entity.error(); err != nil {
44
type fetchError string
46
func (f fetchError) error() error {
50
return fmt.Errorf("%s", string(f))
53
type fakeAuthenticator struct {
54
// Any Authenticator methods we don't implement on fakeAuthenticator
55
// will fall back to this and panic because it's always nil.
63
func (a *fakeAuthenticator) SetPassword(pass string) error {
71
// fakeUnitAuthenticator simulates a unit entity.
72
type fakeUnitAuthenticator struct {
77
func (a *fakeUnitAuthenticator) Tag() names.Tag {
78
return names.NewUnitTag("fake/0")
81
func (a *fakeUnitAuthenticator) SetMongoPassword(pass string) error {
89
// fakeMachineAuthenticator simulates a machine entity.
90
type fakeMachineAuthenticator struct {
92
jobs []state.MachineJob
95
func (a *fakeMachineAuthenticator) Jobs() []state.MachineJob {
99
func (a *fakeMachineAuthenticator) Tag() names.Tag {
100
return names.NewMachineTag("0")
103
func (*passwordSuite) TestSetPasswords(c *gc.C) {
105
entities: map[names.Tag]entityWithError{
106
u("x/0"): &fakeAuthenticator{},
107
u("x/1"): &fakeAuthenticator{},
108
u("x/2"): &fakeAuthenticator{
109
err: fmt.Errorf("x2 error"),
111
u("x/3"): &fakeAuthenticator{
112
fetchError: "x3 error",
114
u("x/4"): &fakeUnitAuthenticator{},
115
u("x/5"): &fakeMachineAuthenticator{jobs: []state.MachineJob{state.JobHostUnits}},
116
u("x/6"): &fakeMachineAuthenticator{jobs: []state.MachineJob{state.JobManageModel}},
119
getCanChange := func() (common.AuthFunc, error) {
120
return func(tag names.Tag) bool {
121
return tag != names.NewUnitTag("x/0")
124
pc := common.NewPasswordChanger(st, getCanChange)
125
var changes []params.EntityPassword
126
for i := 0; i < len(st.entities); i++ {
127
tag := fmt.Sprintf("unit-x-%d", i)
128
changes = append(changes, params.EntityPassword{
130
Password: fmt.Sprintf("%spass", tag),
133
results, err := pc.SetPasswords(params.EntityPasswords{
136
c.Assert(err, jc.ErrorIsNil)
137
c.Assert(results, jc.DeepEquals, params.ErrorResults{
138
Results: []params.ErrorResult{
139
{apiservertesting.ErrUnauthorized},
141
{¶ms.Error{Message: "x2 error"}},
142
{¶ms.Error{Message: "x3 error"}},
148
c.Check(st.entities[u("x/0")].(*fakeAuthenticator).pass, gc.Equals, "")
149
c.Check(st.entities[u("x/1")].(*fakeAuthenticator).pass, gc.Equals, "unit-x-1pass")
150
c.Check(st.entities[u("x/2")].(*fakeAuthenticator).pass, gc.Equals, "")
151
c.Check(st.entities[u("x/4")].(*fakeUnitAuthenticator).pass, gc.Equals, "unit-x-4pass")
152
c.Check(st.entities[u("x/4")].(*fakeUnitAuthenticator).mongoPass, gc.Equals, "")
153
c.Check(st.entities[u("x/5")].(*fakeMachineAuthenticator).pass, gc.Equals, "unit-x-5pass")
154
c.Check(st.entities[u("x/5")].(*fakeMachineAuthenticator).mongoPass, gc.Equals, "")
155
c.Check(st.entities[u("x/6")].(*fakeMachineAuthenticator).pass, gc.Equals, "unit-x-6pass")
156
c.Check(st.entities[u("x/6")].(*fakeMachineAuthenticator).mongoPass, gc.Equals, "unit-x-6pass")
159
func (*passwordSuite) TestSetPasswordsError(c *gc.C) {
160
getCanChange := func() (common.AuthFunc, error) {
161
return nil, fmt.Errorf("splat")
163
pc := common.NewPasswordChanger(&fakeState{}, getCanChange)
164
var changes []params.EntityPassword
165
for i := 0; i < 4; i++ {
166
tag := fmt.Sprintf("x%d", i)
167
changes = append(changes, params.EntityPassword{
169
Password: fmt.Sprintf("%spass", tag),
172
_, err := pc.SetPasswords(params.EntityPasswords{Changes: changes})
173
c.Assert(err, gc.ErrorMatches, "splat")
176
func (*passwordSuite) TestSetPasswordsNoArgsNoError(c *gc.C) {
177
getCanChange := func() (common.AuthFunc, error) {
178
return nil, fmt.Errorf("splat")
180
pc := common.NewPasswordChanger(&fakeState{}, getCanChange)
181
result, err := pc.SetPasswords(params.EntityPasswords{})
182
c.Assert(err, jc.ErrorIsNil)
183
c.Assert(result.Results, gc.HasLen, 0)