110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package server
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.nefrace.ru/nefrace/nashboard/storage"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type registerForm struct {
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
func (s Server) handleRegister(c Context) error {
|
|
var form registerForm
|
|
err := DecodeJSON(c.R.Body, &form)
|
|
if err != nil {
|
|
return ApiError{Status: http.StatusBadRequest, Err: "bad credentials"}
|
|
}
|
|
_, err = s.Db.GetUser(&bson.D{{Key: "username", Value: form.Username}})
|
|
if err == nil {
|
|
return ApiError{Status: http.StatusBadRequest, Err: "user exists"}
|
|
}
|
|
password, err := bcrypt.GenerateFromPassword([]byte(form.Password), 0)
|
|
if err != nil {
|
|
log.Println("Can not generate hash from password: ", err)
|
|
return ApiError{Status: http.StatusInternalServerError, Err: "cannot register"}
|
|
}
|
|
userId := primitive.NewObjectID()
|
|
folderId := primitive.NewObjectID()
|
|
newFolder := storage.Folder{
|
|
Id: folderId,
|
|
UserID: userId,
|
|
Name: "root",
|
|
Created: time.Now(),
|
|
}
|
|
s.Db.CreateFolder(&newFolder)
|
|
newUser := storage.User{
|
|
Id: userId,
|
|
Username: form.Username,
|
|
Password: password,
|
|
IsAdmin: true,
|
|
RootFolderId: folderId,
|
|
}
|
|
if _, err = s.Db.CreateUser(&newUser); err != nil {
|
|
log.Println("Can not create user: ", err)
|
|
return ApiError{Status: http.StatusInternalServerError, Err: "cannot register"}
|
|
}
|
|
|
|
return c.WriteJSON(http.StatusCreated, &newUser)
|
|
}
|
|
|
|
type loginForm struct {
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
func (s Server) handleLogin(c Context) error {
|
|
var form loginForm
|
|
err := DecodeJSON(c.R.Body, &form)
|
|
if err != nil {
|
|
log.Println("Can not decode json from login: ", err)
|
|
return ErrBadRequest
|
|
}
|
|
user, err := s.Db.GetUser(&bson.D{{Key: "username", Value: form.Username}})
|
|
if err != nil {
|
|
log.Println("Can not find user: ", err)
|
|
return ErrBadRequest
|
|
}
|
|
err = bcrypt.CompareHashAndPassword(user.Password, []byte(form.Password))
|
|
if err != nil {
|
|
log.Println("Can not compare password and hash: ", err)
|
|
return ErrBadRequest
|
|
}
|
|
|
|
ses := storage.Session{
|
|
Id: primitive.NewObjectID(),
|
|
Token: storage.GenSessionToken(),
|
|
UserID: user.Id,
|
|
LoggedAt: time.Now(),
|
|
IsAdmin: true,
|
|
ExpiresAt: time.Now().Add(42 * time.Hour * 24),
|
|
IP: c.R.RemoteAddr,
|
|
}
|
|
user.LastLogin = time.Now()
|
|
if err := s.Db.UpdateUser(user); err != nil {
|
|
log.Println("Can not update user: ", err)
|
|
}
|
|
if _, err := s.Db.CreateSession(&ses); err != nil {
|
|
log.Println("Can not store session: ", err)
|
|
return ErrBadRequest
|
|
}
|
|
return c.WriteJSON(200, ses.Token)
|
|
}
|
|
|
|
func (s Server) handleLogout(c Context) error {
|
|
header := c.R.Header.Get("SessionID")
|
|
session, err := s.Db.GetSessionByToken(header)
|
|
if err != nil {
|
|
return ApiError{Status: 400, Err: "can't logout"}
|
|
}
|
|
s.Db.DeleteSession(session.Id)
|
|
return c.WriteJSON(200, "logged out succesfully")
|
|
}
|