etcdhttp: improve user endpoint validation

Giving both roles and grant/revoke is not allowed.
Creating an existing user is not allowed.
Updating a non-existing user is not allowed.
This commit is contained in:
Xiang Li 2015-06-23 14:35:10 -07:00
parent 37933cffa4
commit e291dfd748
2 changed files with 38 additions and 9 deletions

View File

@ -177,12 +177,12 @@ func (s *Store) GetUser(name string) (User, error) {
return u, nil
}
// CreateOrUpdateUser should be only used for creating the new user or when you are not
// sure if it is a create or update. (When only password is passed in, we are not sure
// if it is a update or create)
func (s *Store) CreateOrUpdateUser(user User) (out User, created bool, err error) {
_, err = s.GetUser(user.User)
if err == nil {
// Remove the update-user roles from updating downstream.
// Roles are granted or revoked, not changed directly.
user.Roles = nil
out, err := s.UpdateUser(user)
return out, false, err
}

View File

@ -333,19 +333,48 @@ func (sh *authHandler) forUser(w http.ResponseWriter, r *http.Request, user stri
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON name does not match the name in the URL"))
return
}
newuser, created, err := sh.sec.CreateOrUpdateUser(u)
if err != nil {
writeError(w, err)
return
var (
out auth.User
created bool
)
if len(u.Grant) == 0 && len(u.Revoke) == 0 {
// create or update
if len(u.Roles) != 0 {
out, err = sh.sec.CreateUser(u)
} else {
// if user passes in both password and roles, we are unsure about his/her
// intention.
out, created, err = sh.sec.CreateOrUpdateUser(u)
}
if err != nil {
writeError(w, err)
return
}
} else {
// update case
if len(u.Roles) != 0 {
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON contains both roles and grant/revoke"))
return
}
out, err = sh.sec.UpdateUser(u)
if err != nil {
writeError(w, err)
return
}
}
newuser.Password = ""
if created {
w.WriteHeader(http.StatusCreated)
} else {
w.WriteHeader(http.StatusOK)
}
err = json.NewEncoder(w).Encode(newuser)
out.Password = ""
err = json.NewEncoder(w).Encode(out)
if err != nil {
plog.Warningf("forUser error encoding on %s", r.URL)
return