phase 2 initial test
This commit is contained in:
@@ -5,24 +5,91 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/forgeo/forgebucket/internal/api/middleware"
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
)
|
||||
|
||||
type UserHandler struct {
|
||||
db *xorm.Engine
|
||||
store sessions.Store
|
||||
}
|
||||
|
||||
func NewUserHandler(store sessions.Store) *UserHandler {
|
||||
return &UserHandler{store: store}
|
||||
func NewUserHandler(db *xorm.Engine, store sessions.Store) *UserHandler {
|
||||
return &UserHandler{db: db, store: store}
|
||||
}
|
||||
|
||||
func (h *UserHandler) Me(w http.ResponseWriter, r *http.Request) {
|
||||
func (h *UserHandler) Register(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
jsonError(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if body.Username == "" || body.Email == "" || body.Password == "" {
|
||||
jsonError(w, "username, email, and password are required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
jsonError(w, "internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
user := &models.User{
|
||||
Username: body.Username,
|
||||
Email: body.Email,
|
||||
PasswordHash: string(hash),
|
||||
}
|
||||
if _, err := h.db.Insert(user); err != nil {
|
||||
jsonError(w, "username or email already taken", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func (h *UserHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
jsonError(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var user models.User
|
||||
found, err := h.db.Where("username = ?", body.Username).Get(&user)
|
||||
if err != nil || !found {
|
||||
jsonError(w, "invalid credentials", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(body.Password)); err != nil {
|
||||
jsonError(w, "invalid credentials", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
session, _ := h.store.Get(r, "fb_session")
|
||||
session.Values["userID"] = user.ID
|
||||
session.Values["username"] = user.Username
|
||||
session.Values["isAdmin"] = user.IsAdmin
|
||||
if err := session.Save(r, w); err != nil {
|
||||
jsonError(w, "could not save session", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func (h *UserHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -31,3 +98,21 @@ func (h *UserHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
session.Save(r, w)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (h *UserHandler) Me(w http.ResponseWriter, r *http.Request) {
|
||||
userID, ok := middleware.UserIDFromContext(r.Context())
|
||||
if !ok {
|
||||
jsonError(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
var user models.User
|
||||
found, err := h.db.ID(userID).Get(&user)
|
||||
if err != nil || !found {
|
||||
jsonError(w, "user not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user