github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/common/password_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 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/common" 15 "github.com/juju/juju/apiserver/params" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/state" 18 ) 19 20 type passwordSuite struct{} 21 22 var _ = gc.Suite(&passwordSuite{}) 23 24 type entityWithError interface { 25 state.Entity 26 error() error 27 } 28 29 type fakeState struct { 30 entities map[names.Tag]entityWithError 31 } 32 33 func (st *fakeState) FindEntity(tag names.Tag) (state.Entity, error) { 34 entity, ok := st.entities[tag] 35 if !ok { 36 return nil, errors.NotFoundf("entity %q", tag) 37 } 38 if err := entity.error(); err != nil { 39 return nil, err 40 } 41 return entity, nil 42 } 43 44 type fetchError string 45 46 func (f fetchError) error() error { 47 if f == "" { 48 return nil 49 } 50 return fmt.Errorf("%s", string(f)) 51 } 52 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. 56 state.Authenticator 57 state.Entity 58 err error 59 pass string 60 fetchError 61 } 62 63 func (a *fakeAuthenticator) SetPassword(pass string) error { 64 if a.err != nil { 65 return a.err 66 } 67 a.pass = pass 68 return nil 69 } 70 71 // fakeUnitAuthenticator simulates a unit entity. 72 type fakeUnitAuthenticator struct { 73 fakeAuthenticator 74 mongoPass string 75 } 76 77 func (a *fakeUnitAuthenticator) Tag() names.Tag { 78 return names.NewUnitTag("fake/0") 79 } 80 81 func (a *fakeUnitAuthenticator) SetMongoPassword(pass string) error { 82 if a.err != nil { 83 return a.err 84 } 85 a.mongoPass = pass 86 return nil 87 } 88 89 // fakeMachineAuthenticator simulates a machine entity. 90 type fakeMachineAuthenticator struct { 91 fakeUnitAuthenticator 92 jobs []state.MachineJob 93 } 94 95 func (a *fakeMachineAuthenticator) Jobs() []state.MachineJob { 96 return a.jobs 97 } 98 99 func (a *fakeMachineAuthenticator) Tag() names.Tag { 100 return names.NewMachineTag("0") 101 } 102 103 func (*passwordSuite) TestSetPasswords(c *gc.C) { 104 st := &fakeState{ 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"), 110 }, 111 u("x/3"): &fakeAuthenticator{ 112 fetchError: "x3 error", 113 }, 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}}, 117 }, 118 } 119 getCanChange := func() (common.AuthFunc, error) { 120 return func(tag names.Tag) bool { 121 return tag != names.NewUnitTag("x/0") 122 }, nil 123 } 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{ 129 Tag: tag, 130 Password: fmt.Sprintf("%spass", tag), 131 }) 132 } 133 results, err := pc.SetPasswords(params.EntityPasswords{ 134 Changes: changes, 135 }) 136 c.Assert(err, jc.ErrorIsNil) 137 c.Assert(results, jc.DeepEquals, params.ErrorResults{ 138 Results: []params.ErrorResult{ 139 {apiservertesting.ErrUnauthorized}, 140 {nil}, 141 {¶ms.Error{Message: "x2 error"}}, 142 {¶ms.Error{Message: "x3 error"}}, 143 {nil}, 144 {nil}, 145 {nil}, 146 }, 147 }) 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") 157 } 158 159 func (*passwordSuite) TestSetPasswordsError(c *gc.C) { 160 getCanChange := func() (common.AuthFunc, error) { 161 return nil, fmt.Errorf("splat") 162 } 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{ 168 Tag: tag, 169 Password: fmt.Sprintf("%spass", tag), 170 }) 171 } 172 _, err := pc.SetPasswords(params.EntityPasswords{Changes: changes}) 173 c.Assert(err, gc.ErrorMatches, "splat") 174 } 175 176 func (*passwordSuite) TestSetPasswordsNoArgsNoError(c *gc.C) { 177 getCanChange := func() (common.AuthFunc, error) { 178 return nil, fmt.Errorf("splat") 179 } 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) 184 }