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