package user
import (
"log"
"net/http"
"strconv"
"git.sr.ht/~evanj/cms/internal/c"
"git.sr.ht/~evanj/cms/internal/m/space"
"git.sr.ht/~evanj/cms/internal/m/user"
"git.sr.ht/~evanj/cms/internal/s/tmpl"
)
var (
indexHTML = tmpl.MustParse("html/index.html")
)
type User struct {
*c.Controller
log *log.Logger
db dber
}
type dber interface {
UserNew(username, password, verifyPassword string) (user.User, error)
UserGet(username, password string) (user.User, error)
UserGetFromToken(token string) (user.User, error)
SpacesPerUser(user user.User, page int) ([]space.Space, error)
}
func New(log *log.Logger, db dber) *User {
return &User{
c.New(log, db),
log,
db,
}
}
func (l *User) logout(w http.ResponseWriter, r *http.Request) {
l.SetCookieUser(w, r, nil)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
func (l *User) login(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
user, err := l.db.UserGet(username, password)
if err != nil {
l.Error(w, r, http.StatusBadRequest, "incorrect user credentials")
return
}
l.SetCookieUser(w, r, user)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
func (l *User) signup(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
verify := r.FormValue("verify")
user, err := l.db.UserNew(username, password, verify)
if err != nil {
l.log.Println(err)
l.Error(w, r, http.StatusBadRequest, err.Error())
return
}
l.SetCookieUser(w, r, user)
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}
func (l *User) home(w http.ResponseWriter, r *http.Request) {
user, err := l.GetCookieUser(w, r)
if err != nil {
l.HTML(w, r, indexHTML, map[string]interface{}{
"User": user,
})
return
}
page, err := strconv.Atoi(r.URL.Query().Get("page"))
if err != nil || page < 1 {
page = 1
}
page-- // Show one to user but start counting at zero for us.
spaces, err := l.db.SpacesPerUser(user, page)
if err != nil {
l.Error(w, r, http.StatusInternalServerError, "filed to find spaces for user")
return
}
l.HTML(w, r, indexHTML, map[string]interface{}{
"User": user,
"Spaces": spaces,
})
}
func (l *User) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/":
l.home(w, r)
return
case "/user/login":
l.login(w, r)
return
case "/user/logout":
l.logout(w, r)
return
case "/user/signup":
l.signup(w, r)
return
}
http.NotFound(w, r)
}