package users import ( "database/sql" "encoding/json" "fmt" "net/http" "git.quimbo.fr/odwrtw/canape/backend/auth" "git.quimbo.fr/odwrtw/canape/backend/config" "git.quimbo.fr/odwrtw/canape/backend/events" "git.quimbo.fr/odwrtw/canape/backend/models" "git.quimbo.fr/odwrtw/canape/backend/web" "github.com/gorilla/mux" ) // SignupPOSTHandler handles the user's Signup func SignupPOSTHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { var data struct { Username string `json:"username"` Password string `json:"password"` PasswordConfirm string `json:"password_confirm"` } if err := json.NewDecoder(r.Body).Decode(&data); err != nil { return err } e.Log.Debugf("creating new user ...") if data.Username == "" { return e.RenderError(w, fmt.Errorf("empty username")) } if data.Password == "" || data.PasswordConfirm == "" { return e.RenderError(w, fmt.Errorf("empty password")) } if data.Password != data.PasswordConfirm { return e.RenderError(w, fmt.Errorf("passwords missmatch")) } user := models.User{Name: data.Username} var err error user.Hash, err = e.Auth.GenHash(data.Password) if err != nil { return err } if err = user.Add(e.Database); err != nil { return err } e.Log.Debugf("new user %s created ...", data.Username) return e.RenderOK(w, "User created") } // LoginPOSTHandler handles the login proccess func LoginPOSTHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { var data struct { Username string `json:"username"` Password string `json:"password"` } if err := json.NewDecoder(r.Body).Decode(&data); err != nil { return err } token, err := e.Auth.Login(r, data.Username, data.Password) if err != nil { if err == auth.ErrInvalidPassword || err == models.ErrUnknownUser { return e.RenderError(w, fmt.Errorf("error invalid user or password")) } return err } e.Log.Debugf("logged %s", token.Username) // TODO: add token expiration / keep me login stuff var out = struct { Token string `json:"token"` }{ Token: token.Token, } return e.RenderJSON(w, out) } // DetailsHandler show user details func DetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { user := auth.GetCurrentUser(r, e.Log) var polochonConfig config.UserPolochon if user.PolochonID.Valid && user.PolochonID.String != "" { polochon, err := models.GetPolochonByID(e.Database, user.PolochonID.String) if err != nil { return e.RenderError(w, fmt.Errorf("could not find such polochon")) } polochonConfig.Name = polochon.Name polochonConfig.URL = polochon.URL } polochonConfig.Token = user.Token polochonConfig.Activated = user.PolochonActivated polochonConfig.ID = user.PolochonID.String return e.RenderJSON(w, polochonConfig) } // EditHandler allow editing user info and configuration func EditHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { user := auth.GetCurrentUser(r, e.Log) var data struct { PolochonID string `json:"polochon_id"` Password string `json:"password"` PasswordConfirm string `json:"password_confirm"` } if err := json.NewDecoder(r.Body).Decode(&data); err != nil { return err } // If passwords are not empty, update if data.Password != "" && data.PasswordConfirm != "" { if data.Password != data.PasswordConfirm { return e.RenderError(w, fmt.Errorf("passwords empty or missmatch")) } // Update the user password var err error user.Hash, err = e.Auth.GenHash(data.Password) if err != nil { return err } } // If we changed polochon, we need to unsubscribe it from previous events if data.PolochonID != "" && user.PolochonID.String != data.PolochonID { e.Log.Info("unsubscribing user...") _, err := models.GetPolochonByID(e.Database, data.PolochonID) if err != nil { return e.RenderError(w, fmt.Errorf("could not find such polochon")) } // Need to unsubscribe the user from all the eventers events.Unsubscribe(user) user.PolochonID = sql.NullString{ String: data.PolochonID, Valid: true, } user.PolochonActivated = false } // Save the user with the new configurations if err := user.Update(e.Database); err != nil { return e.RenderInternalError(w, "Error while updating user", err) } return e.RenderOK(w, "user updated") } // GetTokensHandler lists the tokens of a user func GetTokensHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { user := auth.GetCurrentUser(r, e.Log) tokens, err := models.GetUserTokens(e.Database, user.Name) if err != nil { return err } return e.RenderJSON(w, tokens) } // DeleteTokenHandler helps delete a token func DeleteTokenHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) token := vars["token"] user := auth.GetCurrentUser(r, e.Log) if err := models.DeleteToken(e.Database, user.Name, token); err != nil { return err } return e.RenderOK(w, "token deleted") } // EditTokenHandler helps delete a token func EditTokenHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) token := vars["token"] user := auth.GetCurrentUser(r, e.Log) t, err := models.GetUserToken(e.Database, user.Name, token) if err != nil { return err } data := struct { Description string `json:"description"` }{} if err := json.NewDecoder(r.Body).Decode(&data); err != nil { return err } t.Description = data.Description if err := t.Update(e.Database); err != nil { return err } return e.RenderJSON(w, t) } // GetModulesStatus returns the status of the modules func GetModulesStatus(e *web.Env, w http.ResponseWriter, r *http.Request) error { // Get the user from the request user := auth.GetCurrentUser(r, e.Log) // Create a papi client client, err := user.NewPapiClient(e.Database) if err != nil { return e.RenderError(w, fmt.Errorf("error while getting user")) } status, err := client.GetModulesStatus() if err != nil { return e.RenderError(w, fmt.Errorf("error while getting modules status %q", err)) } return e.RenderJSON(w, status) }