Skip to content

Commit

Permalink
Revert "State remove setmongopassword"
Browse files Browse the repository at this point in the history
  • Loading branch information
axw committed Aug 12, 2014
1 parent 232097e commit 3f84778
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 63 deletions.
6 changes: 3 additions & 3 deletions agent/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (s *bootstrapSuite) TestInitializeState(c *gc.C) {
mcfg := agent.BootstrapMachineConfig{
Addresses: network.NewAddresses("zeroonetwothree", "0.1.2.3"),
Constraints: expectConstraints,
Jobs: []params.MachineJob{params.JobManageEnviron},
Jobs: []params.MachineJob{params.JobHostUnits},
InstanceId: "i-bootstrap",
Characteristics: expectHW,
SharedSecret: "abc123",
Expand Down Expand Up @@ -114,7 +114,7 @@ func (s *bootstrapSuite) TestInitializeState(c *gc.C) {

// Check that the bootstrap machine looks correct.
c.Assert(m.Id(), gc.Equals, "0")
c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobManageEnviron})
c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobHostUnits})
c.Assert(m.Series(), gc.Equals, version.Current.Series)
c.Assert(m.CheckProvisioned(agent.BootstrapNonce), jc.IsTrue)
c.Assert(m.Addresses(), gc.DeepEquals, mcfg.Addresses)
Expand Down Expand Up @@ -210,7 +210,7 @@ func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(c *gc.C) {
expectHW := instance.MustParseHardware("mem=2048M")
mcfg := agent.BootstrapMachineConfig{
Constraints: expectConstraints,
Jobs: []params.MachineJob{params.JobManageEnviron},
Jobs: []params.MachineJob{params.JobHostUnits},
InstanceId: "i-bootstrap",
Characteristics: expectHW,
}
Expand Down
1 change: 1 addition & 0 deletions cmd/jujud/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ type AgentState interface {
// currently running.
SetAgentVersion(v version.Binary) error
Tag() string
SetMongoPassword(password string) error
Life() state.Life
}

Expand Down
16 changes: 16 additions & 0 deletions mongo/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,19 @@ func SetAdminMongoPassword(session *mgo.Session, user, password string) error {
}
return nil
}

// SetMongoPassword sets the mongo password in the specified databases for the given user name.
// Previous passwords are invalidated.
func SetMongoPassword(name, password string, dbs ...*mgo.Database) error {
user := &mgo.User{
Username: name,
Password: password,
Roles: []mgo.Role{mgo.RoleReadWriteAny, mgo.RoleUserAdmin, mgo.RoleClusterAdmin},
}
for _, db := range dbs {
if err := db.UpsertUser(user); err != nil {
return fmt.Errorf("cannot set password in juju db %q for %q: %v", db.Name, name, err)
}
}
return nil
}
28 changes: 23 additions & 5 deletions mongo/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,37 @@ func (s *adminSuite) TestSetAdminMongoPassword(c *gc.C) {

// Check that we can SetAdminMongoPassword to nothing when there's
// no password currently set.
err = mongo.SetAdminMongoPassword(session, "auser", "")
err = mongo.SetAdminMongoPassword(session, "admin", "")
c.Assert(err, gc.IsNil)

err = mongo.SetAdminMongoPassword(session, "auser", "foo")
err = mongo.SetAdminMongoPassword(session, "admin", "foo")
c.Assert(err, gc.IsNil)
err = admin.Login("auser", "")
err = admin.Login("admin", "")
c.Assert(err, gc.ErrorMatches, "auth fails")
err = admin.Login("auser", "foo")
err = admin.Login("admin", "foo")
c.Assert(err, gc.IsNil)
checkRoles(c, admin, "auser",
checkRoles(c, admin, "admin",
[]interface{}{
string(mgo.RoleReadWriteAny),
string(mgo.RoleDBAdminAny),
string(mgo.RoleUserAdminAny),
string(mgo.RoleClusterAdmin)})
}

func (s *adminSuite) TestSetMongoPassword(c *gc.C) {
dialInfo := s.setUpMongo(c)
session, err := mgo.DialWithInfo(dialInfo)
c.Assert(err, gc.IsNil)
defer session.Close()
db := session.DB("juju")

err = db.Login("foo", "bar")
c.Assert(err, gc.ErrorMatches, "auth fails")

err = mongo.SetMongoPassword("foo", "bar", db)
c.Assert(err, gc.IsNil)
err = db.Login("foo", "bar")
c.Assert(err, gc.IsNil)
checkRoles(c, db, "foo",
[]interface{}{string(mgo.RoleReadWriteAny), string(mgo.RoleUserAdmin), string(mgo.RoleClusterAdmin)})
}
12 changes: 12 additions & 0 deletions state/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ var (
_ Authenticator = (*User)(nil)
)

// MongoPassworder represents an entity that can
// have a mongo password set for it.
type MongoPassworder interface {
SetMongoPassword(password string) error
}

var (
_ MongoPassworder = (*Machine)(nil)
_ MongoPassworder = (*Unit)(nil)
)

// Annotator represents entities capable of handling annotations.
type Annotator interface {
Annotation(key string) (string, error)
Expand Down Expand Up @@ -138,6 +149,7 @@ type AgentEntity interface {
Entity
Lifer
Authenticator
MongoPassworder
AgentTooler
StatusSetter
EnsureDeader
Expand Down
6 changes: 1 addition & 5 deletions state/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

"github.com/juju/juju/constraints"
"github.com/juju/juju/instance"
"github.com/juju/juju/mongo"
"github.com/juju/juju/network"
"github.com/juju/juju/state/api/params"
"github.com/juju/juju/state/presence"
Expand Down Expand Up @@ -333,10 +332,7 @@ func (m *Machine) SetAgentVersion(v version.Binary) (err error) {
// should use to communicate with the state servers. Previous passwords
// are invalidated.
func (m *Machine) SetMongoPassword(password string) error {
if !m.IsManager() {
return errors.NotSupportedf("setting mongo password for non-manager machine %v", m)
}
return mongo.SetAdminMongoPassword(m.st.db.Session, m.Tag().String(), password)
return m.st.setMongoPassword(m.Tag().String(), password)
}

// SetPassword sets the password for the machine's agent.
Expand Down
50 changes: 3 additions & 47 deletions state/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/juju/errors"
"github.com/juju/loggo"
jujutesting "github.com/juju/testing"
jc "github.com/juju/testing/checkers"
"github.com/juju/txn"
"gopkg.in/mgo.v2/bson"
Expand Down Expand Up @@ -345,52 +344,9 @@ func (s *MachineSuite) TestTag(c *gc.C) {
}

func (s *MachineSuite) TestSetMongoPassword(c *gc.C) {
info := state.TestingMongoInfo()
st, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil))
c.Assert(err, gc.IsNil)
defer st.Close()
// Turn on fully-authenticated mode.
err = st.SetAdminMongoPassword(jujutesting.DefaultMongoPassword)
c.Assert(err, gc.IsNil)

// Set the password for the machine.
m, err := st.Machine("0")
c.Assert(err, gc.IsNil)
err = m.SetMongoPassword("foo")
c.Assert(err, gc.IsNil)

// Check that we cannot log in with the wrong password.
info.Tag = m.Tag()
info.Password = "bar"
err = tryOpenState(info)
c.Assert(err, jc.Satisfies, errors.IsUnauthorized)

// Check that we can log in with the correct password.
info.Password = "foo"
err = tryOpenState(info)
c.Assert(err, gc.IsNil)

// Change the password with an entity derived from the newly
// opened and authenticated state.
m, err = st.Machine("0")
c.Assert(err, gc.IsNil)
err = m.SetMongoPassword("bar")
c.Assert(err, gc.IsNil)

// Check that we cannot log in with the old password.
info.Password = "foo"
err = tryOpenState(info)
c.Assert(err, jc.Satisfies, errors.IsUnauthorized)

// Check that we can log in with the new password.
info.Password = "bar"
err = tryOpenState(info)
c.Assert(err, gc.IsNil)

// Check that the administrator can still log in.
info.Tag, info.Password = nil, jujutesting.DefaultMongoPassword
err = tryOpenState(info)
c.Assert(err, gc.IsNil)
testSetMongoPassword(c, func(st *state.State) (entity, error) {
return st.Machine(s.machine.Id())
})
}

func (s *MachineSuite) TestSetPassword(c *gc.C) {
Expand Down
10 changes: 8 additions & 2 deletions state/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,17 @@ func isUnauthorized(err error) bool {
}

func newState(session *mgo.Session, mongoInfo *authentication.MongoInfo, policy Policy) (st *State, resultErr error) {
db := session.DB("juju")
pdb := session.DB("presence")
admin := session.DB("admin")
authenticated := false
if mongoInfo.Tag != nil {
if err := db.Login(mongoInfo.Tag.String(), mongoInfo.Password); err != nil {
return nil, maybeUnauthorized(err, fmt.Sprintf("cannot log in to juju database as %q", mongoInfo.Tag))
}
if err := pdb.Login(mongoInfo.Tag.String(), mongoInfo.Password); err != nil {
return nil, maybeUnauthorized(err, fmt.Sprintf("cannot log in to presence database as %q", mongoInfo.Tag))
}
if err := admin.Login(mongoInfo.Tag.String(), mongoInfo.Password); err != nil {
return nil, maybeUnauthorized(err, fmt.Sprintf("cannot log in to admin database as %q", mongoInfo.Tag))
}
Expand All @@ -182,8 +190,6 @@ func newState(session *mgo.Session, mongoInfo *authentication.MongoInfo, policy
authenticated = true
}

db := session.DB("juju")
pdb := session.DB("presence")
st = &State{
mongoInfo: mongoInfo,
policy: policy,
Expand Down
12 changes: 11 additions & 1 deletion state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1626,11 +1626,21 @@ func (st *State) StartSync() {
st.pwatcher.Sync()
}

// SetAdminMongoPassword sets the administrative password to access the state.
// SetAdminMongoPassword sets the administrative password
// to access the state. If the password is non-empty,
// all subsequent attempts to access the state must
// be authorized; otherwise no authorization is required.
func (st *State) SetAdminMongoPassword(password string) error {
return mongo.SetAdminMongoPassword(st.db.Session, AdminUser, password)
}

func (st *State) setMongoPassword(name, password string) error {
return mongo.SetMongoPassword(name, password,
st.db,
st.db.Session.DB("presence"),
st.db.Session.DB("admin"))
}

type stateServersDoc struct {
Id string `bson:"_id"`
MachineIds []string
Expand Down
61 changes: 61 additions & 0 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,67 @@ func testSetAgentCompatPassword(c *gc.C, entity state.Authenticator) {
c.Assert(entity.PasswordValid("short"), jc.IsTrue)
}

type entity interface {
state.Entity
state.Lifer
state.Authenticator
state.MongoPassworder
}

func testSetMongoPassword(c *gc.C, getEntity func(st *state.State) (entity, error)) {
info := state.TestingMongoInfo()
st, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil))
c.Assert(err, gc.IsNil)
defer st.Close()
// Turn on fully-authenticated mode.
err = st.SetAdminMongoPassword("admin-secret")
c.Assert(err, gc.IsNil)

// Set the password for the entity
ent, err := getEntity(st)
c.Assert(err, gc.IsNil)
err = ent.SetMongoPassword("foo")
c.Assert(err, gc.IsNil)

// Check that we cannot log in with the wrong password.
info.Tag = ent.Tag()
info.Password = "bar"
err = tryOpenState(info)
c.Assert(err, jc.Satisfies, errors.IsUnauthorized)

// Check that we can log in with the correct password.
info.Password = "foo"
st1, err := state.Open(info, state.TestingDialOpts(), state.Policy(nil))
c.Assert(err, gc.IsNil)
defer st1.Close()

// Change the password with an entity derived from the newly
// opened and authenticated state.
ent, err = getEntity(st)
c.Assert(err, gc.IsNil)
err = ent.SetMongoPassword("bar")
c.Assert(err, gc.IsNil)

// Check that we cannot log in with the old password.
info.Password = "foo"
err = tryOpenState(info)
c.Assert(err, jc.Satisfies, errors.IsUnauthorized)

// Check that we can log in with the correct password.
info.Password = "bar"
err = tryOpenState(info)
c.Assert(err, gc.IsNil)

// Check that the administrator can still log in.
info.Tag, info.Password = nil, "admin-secret"
err = tryOpenState(info)
c.Assert(err, gc.IsNil)

// Remove the admin password so that the test harness can reset the state.
err = st.SetAdminMongoPassword("")
c.Assert(err, gc.IsNil)
}

func (s *StateSuite) TestSetAdminMongoPassword(c *gc.C) {
// Check that we can SetAdminMongoPassword to nothing when there's
// no password currently set.
Expand Down
7 changes: 7 additions & 0 deletions state/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ func (u *Unit) SetAgentVersion(v version.Binary) (err error) {
return nil
}

// SetMongoPassword sets the password the agent responsible for the unit
// should use to communicate with the state servers. Previous passwords
// are invalidated.
func (u *Unit) SetMongoPassword(password string) error {
return u.st.setMongoPassword(u.Tag().String(), password)
}

// SetPassword sets the password for the machine's agent.
func (u *Unit) SetPassword(password string) error {
if len(password) < utils.MinAgentPasswordLength {
Expand Down
Loading

0 comments on commit 3f84778

Please sign in to comment.