canape/backend/users/handlers.go

170 lines
4.0 KiB
Go

package users
import (
"encoding/json"
"fmt"
"net/http"
"time"
jwt "github.com/dgrijalva/jwt-go"
"gitlab.quimbo.fr/odwrtw/canape/backend/auth"
"gitlab.quimbo.fr/odwrtw/canape/backend/config"
"gitlab.quimbo.fr/odwrtw/canape/backend/web"
)
// 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.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 := User{Name: data.Username}
var err error
user.Hash, err = e.Auth.GenHash(data.Password)
if err != nil {
return err
}
err = user.NewConfig()
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
}
user, err := e.Auth.Login(w, r, data.Username, data.Password)
if err != nil {
if err == auth.ErrInvalidPassword || err == ErrUnknownUser {
return e.RenderError(w, fmt.Errorf("Error invalid user or password"))
}
return err
}
e.Log.Debugf("logged %s", user.GetName())
// Create a jwt token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
// Not before
"nbf": time.Now().Unix(),
// Issued at
"iat": time.Now().Unix(),
// Private claims
"username": user.GetName(),
"isAdmin": user.IsAdmin(),
"isActivated": user.IsActivated(),
})
// Sign the token
ss, err := token.SignedString([]byte(e.Auth.Secret))
if err != nil {
return err
}
var out = struct {
Token string `json:"token"`
}{
Token: ss,
}
return e.RenderJSON(w, out)
}
// DetailsHandler show user details
func DetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r, e.Log)
user, ok := v.(*User)
if !ok {
return fmt.Errorf("invalid user type")
}
var polochonConfig config.UserPolochon
err := user.GetConfig("polochon", &polochonConfig)
if err != nil {
return err
}
return e.RenderJSON(w, polochonConfig)
}
// EditHandler allow editing user info and configuration
func EditHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
v := auth.GetCurrentUser(r, e.Log)
user, ok := v.(*User)
if !ok {
return fmt.Errorf("invalid user type")
}
var data struct {
PolochonURL string `json:"polochon_url"`
PolochonToken string `json:"polochon_token"`
Password string `json:"password"`
PasswordConfirm string `json:"password_confirm"`
}
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
return err
}
if data.Password != "" && data.PasswordConfirm != "" {
if data.Password != data.PasswordConfirm {
return e.RenderError(w, fmt.Errorf("Passwords empty or missmatch"))
}
// Update the user config
var err error
user.Hash, err = e.Auth.GenHash(data.Password)
if err != nil {
return err
}
}
// Update the polochon config
var polochonConfig config.UserPolochon
if err := user.GetConfig("polochon", &polochonConfig); err != nil {
return err
}
polochonConfig.URL = data.PolochonURL
polochonConfig.Token = data.PolochonToken
if err := user.SetConfig("polochon", polochonConfig); err != nil {
return err
}
// Save the user with the new configurations
if err := user.Update(e.Database); err != nil {
return err
}
return e.RenderOK(w, "user updated")
}