canape/backend/users/handlers.go
Grégoire Delattre 1197e6ce6c Move the tokens into the models
By the way, move he sqly package in the models as well
2020-03-02 13:07:04 +01:00

233 lines
5.9 KiB
Go

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)
}