change db user password should be a separate command

pull/144/head v0.4.0.rc4
John Shahid 2013-12-12 13:04:46 -05:00
parent 9785ec85b4
commit b0e893c073
8 changed files with 75 additions and 30 deletions

View File

@ -353,6 +353,20 @@ func (self *ClusterConfiguration) SaveDbUser(u *dbUser) {
dbUsers[u.GetName()] = u
}
func (self *ClusterConfiguration) ChangeDbUserPassword(db, username, hash string) error {
self.usersLock.Lock()
defer self.usersLock.Unlock()
dbUsers := self.dbUsers[db]
if dbUsers == nil {
return fmt.Errorf("Invalid database name %s", db)
}
if dbUsers[username] == nil {
return fmt.Errorf("Invalid username %s", username)
}
dbUsers[username].changePassword(hash)
return nil
}
func (self *ClusterConfiguration) GetClusterAdmins() (names []string) {
self.usersLock.RLock()
defer self.usersLock.RUnlock()

View File

@ -1,6 +1,7 @@
package coordinator
import (
log "code.google.com/p/log4go"
"github.com/goraft/raft"
)
@ -61,6 +62,30 @@ func (c *SaveDbUserCommand) Apply(server raft.Server) (interface{}, error) {
return nil, nil
}
type ChangeDbUserPassword struct {
Database string
Username string
Hash string
}
func NewChangeDbUserPasswordCommand(db, username, hash string) *ChangeDbUserPassword {
return &ChangeDbUserPassword{
Database: db,
Username: username,
Hash: hash,
}
}
func (c *ChangeDbUserPassword) CommandName() string {
return "change_db_user_password"
}
func (c *ChangeDbUserPassword) Apply(server raft.Server) (interface{}, error) {
log.Debug("(raft:%s) changing db user password for %s:%s", server.Name(), c.Database, c.Username)
config := server.Context().(*ClusterConfiguration)
return nil, config.ChangeDbUserPassword(c.Database, c.Username, c.Hash)
}
type SaveClusterAdminCommand struct {
User *clusterAdmin `json:"user"`
}

View File

@ -672,7 +672,11 @@ func (self *CoordinatorImpl) ChangeClusterAdminPassword(requester common.User, u
return fmt.Errorf("Invalid user name %s", username)
}
user.changePassword(password)
hash, err := hashPassword(password)
if err != nil {
return err
}
user.changePassword(string(hash))
return self.raftServer.SaveClusterAdminUser(user)
}
@ -722,21 +726,11 @@ func (self *CoordinatorImpl) ChangeDbUserPassword(requester common.User, db, use
return common.NewAuthorizationError("Insufficient permissions")
}
dbUsers := self.clusterConfiguration.dbUsers[db]
if dbUsers == nil {
return fmt.Errorf("Invalid database name %s", db)
}
if dbUsers[username] == nil {
return fmt.Errorf("Invalid username %s", username)
}
user := *dbUsers[username]
err := user.changePassword(password)
hash, err := hashPassword(password)
if err != nil {
return err
}
return self.raftServer.SaveDbUser(&user)
return self.raftServer.ChangeDbUserPassword(db, username, hash)
}
func (self *CoordinatorImpl) SetDbAdmin(requester common.User, db, username string, isAdmin bool) error {

View File

@ -60,6 +60,7 @@ type ClusterConsensus interface {
DropDatabase(name string) error
SaveClusterAdminUser(u *clusterAdmin) error
SaveDbUser(user *dbUser) error
ChangeDbUserPassword(db, username string, hash []byte) error
// an insert index of -1 will append to the end of the ring
AddServer(server *ClusterServer, insertIndex int) error

View File

@ -56,6 +56,7 @@ func NewRaftServer(config *configuration.Configuration, clusterConfig *ClusterCo
raft.RegisterCommand(&DropDatabaseCommand{})
raft.RegisterCommand(&SaveDbUserCommand{})
raft.RegisterCommand(&SaveClusterAdminCommand{})
raft.RegisterCommand(&ChangeDbUserPassword{})
}
s := &RaftServer{
@ -151,6 +152,12 @@ func (s *RaftServer) SaveDbUser(u *dbUser) error {
return err
}
func (s *RaftServer) ChangeDbUserPassword(db, username string, hash []byte) error {
command := NewChangeDbUserPasswordCommand(db, username, string(hash))
_, err := s.doOrProxyCommand(command, "change_db_user_password")
return err
}
func (s *RaftServer) SaveClusterAdminUser(u *clusterAdmin) error {
command := NewSaveClusterAdminCommand(u)
_, err := s.doOrProxyCommand(command, "save_cluster_admin_user")
@ -159,7 +166,8 @@ func (s *RaftServer) SaveClusterAdminUser(u *clusterAdmin) error {
func (s *RaftServer) CreateRootUser() error {
u := &clusterAdmin{CommonUser{"root", "", false}}
u.changePassword(DEFAULT_ROOT_PWD)
hash, _ := hashPassword(DEFAULT_ROOT_PWD)
u.changePassword(string(hash))
return s.SaveClusterAdminUser(u)
}
@ -398,20 +406,23 @@ func (s *RaftServer) processCommandHandler(w http.ResponseWriter, req *http.Requ
vars := mux.Vars(req)
value := vars["command_type"]
var command raft.Command
if value == "create_db" {
switch value {
case "create_db":
command = &CreateDatabaseCommand{}
} else if value == "drop_db" {
case "drop_db":
command = &DropDatabaseCommand{}
} else if value == "save_db_user" {
case "save_db_user":
command = &SaveDbUserCommand{}
} else if value == "save_cluster_admin_user" {
case "save_cluster_admin_user":
command = &SaveClusterAdminCommand{}
} else if value == "update_state" {
case "update_state":
command = &UpdateServerStateCommand{}
} else if value == "add_server" {
fmt.Println("add_server: ", s.name)
case "add_server":
command = &AddPotentialServerCommand{}
case "change_db_user_password":
command = &ChangeDbUserPassword{}
}
if result, err := s.marshalAndDoCommandFromBody(command, req); err != nil {
log.Error("command %T failed: %s", command, err)
http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@ -39,12 +39,8 @@ func (self *CommonUser) IsDeleted() bool {
return self.IsUserDeleted
}
func (self *CommonUser) changePassword(password string) error {
hash, err := hashPassword(password)
if err != nil {
return err
}
self.Hash = string(hash)
func (self *CommonUser) changePassword(hash string) error {
self.Hash = hash
userCache.Delete(self.Name)
return nil
}

View File

@ -21,7 +21,9 @@ func (self *UserSuite) TestProperties(c *C) {
u := clusterAdmin{CommonUser{Name: "root"}}
c.Assert(u.IsClusterAdmin(), Equals, true)
c.Assert(u.GetName(), Equals, "root")
c.Assert(u.changePassword("foobar"), IsNil)
hash, err := hashPassword("foobar")
c.Assert(err, IsNil)
c.Assert(u.changePassword(string(hash)), IsNil)
c.Assert(u.isValidPwd("foobar"), Equals, true)
c.Assert(u.isValidPwd("password"), Equals, false)
@ -29,7 +31,9 @@ func (self *UserSuite) TestProperties(c *C) {
c.Assert(dbUser.IsClusterAdmin(), Equals, false)
c.Assert(dbUser.IsDbAdmin("db"), Equals, true)
c.Assert(dbUser.GetName(), Equals, "db_user")
c.Assert(dbUser.changePassword("password"), IsNil)
hash, err = hashPassword("password")
c.Assert(err, IsNil)
c.Assert(dbUser.changePassword(string(hash)), IsNil)
c.Assert(dbUser.isValidPwd("password"), Equals, true)
c.Assert(dbUser.isValidPwd("password1"), Equals, false)
}

View File

@ -319,7 +319,7 @@ func (self *ServerSuite) TestCrossClusterQueries(c *C) {
func (self *ServerSuite) TestFailureAndReplicationReplays(c *C) {
servers := self.servers
err := servers[0].RaftServer.CreateDatabase("full_rep", uint8(3))
_, err := self.postToServer(self.servers[0], "/db?u=root&p=root", `{"name": "full_rep", "replicationFactor": 3}`, c)
c.Assert(err, IsNil)
time.Sleep(time.Millisecond * 10)
_, err = self.postToServer(self.servers[0], "/db/full_rep/users?u=root&p=root", `{"name": "paul", "password": "pass"}`, c)