user.go 2.25 KB
package main

import (
	"encoding/json"
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-sql-driver/mysql"
	"golang.org/x/crypto/sha3"
)

type User struct {
	No        uint64    `json:"no"`
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"created_at"`
	ExpiredAt time.Time `json:"expired_at"`
}

func (app *App) PostUsers(w http.ResponseWriter, r *http.Request) {
	body := make(map[string]interface{})
	err := json.NewDecoder(r.Body).Decode(&body)
	if err != nil {
		WriteJson(w, http.StatusBadRequest, map[string]interface{}{"msg": "Failed to parse request json"})
		return
	}

	hash := sha3.Sum256([]byte(body["password"].(string)))

	res, err := app.db.Exec("INSERT INTO users (`id`, `password`, `name`) VALUES (?, ?, ?)", body["id"], hash[:], body["name"])
	if err != nil {
		if merr, ok := err.(*mysql.MySQLError); ok {
			if merr.Number == 1062 {
				WriteJson(w, http.StatusConflict, map[string]interface{}{"msg": "Already registered"})
				return
			}
		}

		WriteJson(w, http.StatusInternalServerError, map[string]interface{}{"msg": "Failed to register"})
		return
	}

	no, _ := res.LastInsertId()
	WriteJson(w, http.StatusOK, map[string]interface{}{"user_no": no})
}

func (app *App) PostTokens(w http.ResponseWriter, r *http.Request) {
	body := make(map[string]interface{})
	err := json.NewDecoder(r.Body).Decode(&body)
	if err != nil {
		WriteJson(w, http.StatusBadRequest, map[string]interface{}{"msg": "Failed to parse request json"})
		return
	}

	hash := sha3.Sum256([]byte(body["password"].(string)))
	rows, err := app.db.Query("SELECT `no` FROM users WHERE `id`=? AND `password`=?", body["id"], hash[:])
	if err != nil {
		WriteJson(w, http.StatusInternalServerError, map[string]interface{}{"msg": "Failed to register"})
		return
	}

	if !rows.Next() {
		WriteJson(w, http.StatusUnauthorized, map[string]interface{}{"msg": "Login failed"})
		return
	}

	no := uint64(0)
	rows.Scan(&no)

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{"no": no})
	auth, err := token.SignedString([]byte(app.Config.TokenSecret))
	if err != nil {
		WriteJson(w, http.StatusInternalServerError, map[string]interface{}{"msg": "Login failed"})
		return
	}

	WriteJson(w, http.StatusOK, map[string]interface{}{"token": auth})
}