// GetReqUser gets the actor making the request. If use-auth is not on, always // returns the admin user. func GetReqUser(name string) (Actor, util.Gerror) { /* If UseAuth is turned off, use the automatically created admin user */ if !config.Config.UseAuth { name = "admin" } var c Actor var err error c, err = client.Get(name) if err != nil { /* Theoretically it should be hard to reach this point, since * if the signed request was accepted the user ought to exist. * Still, best to be cautious. */ u, cerr := user.Get(name) if cerr != nil { gerr := util.Errorf("Neither a client nor a user named '%s' could be found. In addition, the following errors were reported: %s -- %s", name, err.Error(), cerr.Error()) gerr.SetStatus(http.StatusUnauthorized) return nil, gerr } c = u } return c, nil }
func validateLogin(auth *authenticator) authResponse { // Check passwords and such later. // Automatically validate if UseAuth is not on var resp authResponse resp.Name = auth.Name if !config.Config.UseAuth { resp.Verified = true return resp } u, err := user.Get(auth.Name) if err != nil { resp.Verified = false return resp } perr := u.CheckPasswd(auth.Password) if perr != nil { resp.Verified = false } else { resp.Verified = true } return resp }
func userHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") path := splitPath(r.URL.Path) userName := path[1] opUser, oerr := actor.GetReqUser(r.Header.Get("X-OPS-USERID")) if oerr != nil { jsonErrorReport(w, r, oerr.Error(), oerr.Status()) return } switch r.Method { case "DELETE": chefUser, err := user.Get(userName) if err != nil { jsonErrorReport(w, r, err.Error(), http.StatusNotFound) return } if !opUser.IsAdmin() && !opUser.IsSelf(chefUser) { jsonErrorReport(w, r, "Deleting that user is forbidden", http.StatusForbidden) return } /* Docs were incorrect. It does want the body of the * deleted object. */ jsonUser := chefUser.ToJSON() /* Log the delete event *before* deleting the user, in * case the user is deleting itself. */ if lerr := loginfo.LogEvent(opUser, chefUser, "delete"); lerr != nil { jsonErrorReport(w, r, lerr.Error(), http.StatusInternalServerError) return } err = chefUser.Delete() if err != nil { jsonErrorReport(w, r, err.Error(), http.StatusForbidden) return } enc := json.NewEncoder(w) if encerr := enc.Encode(&jsonUser); encerr != nil { jsonErrorReport(w, r, encerr.Error(), http.StatusInternalServerError) return } case "GET": chefUser, err := user.Get(userName) if err != nil { jsonErrorReport(w, r, err.Error(), http.StatusNotFound) return } if !opUser.IsAdmin() && !opUser.IsSelf(chefUser) { jsonErrorReport(w, r, "You are not allowed to perform that action.", http.StatusForbidden) return } /* API docs are wrong here re: public_key vs. * certificate. Also orgname (at least w/ open source) * and clientname, and it wants chef_type and * json_class */ jsonUser := chefUser.ToJSON() enc := json.NewEncoder(w) if encerr := enc.Encode(&jsonUser); encerr != nil { jsonErrorReport(w, r, encerr.Error(), http.StatusInternalServerError) return } case "PUT": userData, jerr := parseObjJSON(r.Body) if jerr != nil { jsonErrorReport(w, r, jerr.Error(), http.StatusBadRequest) return } chefUser, err := user.Get(userName) if err != nil { jsonErrorReport(w, r, err.Error(), http.StatusNotFound) return } /* Makes chef-pedant happy. I suppose it is, after all, * pedantic. */ if averr := util.CheckAdminPlusValidator(userData); averr != nil { jsonErrorReport(w, r, averr.Error(), averr.Status()) return } if !opUser.IsAdmin() && !opUser.IsSelf(chefUser) { jsonErrorReport(w, r, "You are not allowed to perform that action.", http.StatusForbidden) return } if !opUser.IsAdmin() { aerr := opUser.CheckPermEdit(userData, "admin") if aerr != nil { jsonErrorReport(w, r, aerr.Error(), aerr.Status()) return } } jsonName, sterr := util.ValidateAsString(userData["name"]) if sterr != nil { jsonErrorReport(w, r, sterr.Error(), http.StatusBadRequest) return } /* If userName and userData["name"] aren't the * same, we're renaming. Check the new name doesn't * already exist. */ jsonUser := chefUser.ToJSON() delete(jsonUser, "public_key") if userName != jsonName { err := chefUser.Rename(jsonName) if err != nil { jsonErrorReport(w, r, err.Error(), err.Status()) return } w.WriteHeader(http.StatusCreated) } if uerr := chefUser.UpdateFromJSON(userData); uerr != nil { jsonErrorReport(w, r, uerr.Error(), uerr.Status()) return } if pk, pkfound := userData["public_key"]; pkfound { switch pk := pk.(type) { case string: if pkok, pkerr := user.ValidatePublicKey(pk); !pkok { jsonErrorReport(w, r, pkerr.Error(), http.StatusBadRequest) return } chefUser.SetPublicKey(pk) jsonUser["public_key"] = pk case nil: //show_public_key = false default: jsonErrorReport(w, r, "Bad request", http.StatusBadRequest) return } } if p, pfound := userData["private_key"]; pfound { switch p := p.(type) { case bool: if p { var perr error if jsonUser["private_key"], perr = chefUser.GenerateKeys(); perr != nil { jsonErrorReport(w, r, perr.Error(), http.StatusInternalServerError) return } // make sure the json // client gets the new // public key jsonUser["public_key"] = chefUser.PublicKey() } default: jsonErrorReport(w, r, "Bad request", http.StatusBadRequest) return } } serr := chefUser.Save() if serr != nil { jsonErrorReport(w, r, serr.Error(), serr.Status()) return } if lerr := loginfo.LogEvent(opUser, chefUser, "modify"); lerr != nil { jsonErrorReport(w, r, lerr.Error(), http.StatusInternalServerError) return } enc := json.NewEncoder(w) if encerr := enc.Encode(&jsonUser); encerr != nil { jsonErrorReport(w, r, encerr.Error(), http.StatusInternalServerError) return } default: jsonErrorReport(w, r, "Unrecognized method for user!", http.StatusMethodNotAllowed) } }
func createDefaultActors() { if cwebui, _ := client.Get("chef-webui"); cwebui == nil { if webui, nerr := client.New("chef-webui"); nerr != nil { logger.Criticalf(nerr.Error()) os.Exit(1) } else { webui.Admin = true pem, err := webui.GenerateKeys() if err != nil { logger.Criticalf(err.Error()) os.Exit(1) } if config.Config.UseAuth { if fp, ferr := os.Create(fmt.Sprintf("%s/%s.pem", config.Config.ConfRoot, webui.Name)); ferr == nil { fp.Chmod(0600) fp.WriteString(pem) fp.Close() } else { logger.Criticalf(ferr.Error()) os.Exit(1) } } webui.Save() } } if cvalid, _ := client.Get("chef-validator"); cvalid == nil { if validator, verr := client.New("chef-validator"); verr != nil { logger.Criticalf(verr.Error()) os.Exit(1) } else { validator.Validator = true pem, err := validator.GenerateKeys() if err != nil { logger.Criticalf(err.Error()) os.Exit(1) } if config.Config.UseAuth { if fp, ferr := os.Create(fmt.Sprintf("%s/%s.pem", config.Config.ConfRoot, validator.Name)); ferr == nil { fp.Chmod(0600) fp.WriteString(pem) fp.Close() } else { logger.Criticalf(ferr.Error()) os.Exit(1) } } validator.Save() } } if uadmin, _ := user.Get("admin"); uadmin == nil { if admin, aerr := user.New("admin"); aerr != nil { logger.Criticalf(aerr.Error()) os.Exit(1) } else { admin.Admin = true pem, err := admin.GenerateKeys() if err != nil { logger.Criticalf(err.Error()) os.Exit(1) } if config.Config.UseAuth { if fp, ferr := os.Create(fmt.Sprintf("%s/%s.pem", config.Config.ConfRoot, admin.Name)); ferr == nil { fp.Chmod(0600) fp.WriteString(pem) fp.Close() } else { logger.Criticalf(ferr.Error()) os.Exit(1) } } if aerr := admin.Save(); aerr != nil { logger.Criticalf(aerr.Error()) os.Exit(1) } } } environment.MakeDefaultEnvironment() return }