Add registration/login/logout
This commit is contained in:
parent
8b054e454a
commit
9425061964
10 changed files with 260 additions and 6 deletions
|
|
@ -12,6 +12,17 @@ func (s *Storage) queryUser(q string, params ...interface{}) (user model.User, e
|
|||
return
|
||||
}
|
||||
|
||||
func (s *Storage) VerifyUser(user model.User) (model.User, error) {
|
||||
u, err := s.queryUser(queryFindName, user.Name)
|
||||
if err != nil {
|
||||
return u, err
|
||||
}
|
||||
if err := user.CompareHashToPassword(u.Hash); err != nil {
|
||||
return u, err
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *Storage) UserExists(name string) bool {
|
||||
var rv bool
|
||||
s.db.QueryRow(`SELECT true FROM users WHERE name=lower($1)`, name).Scan(&rv)
|
||||
|
|
@ -66,4 +77,3 @@ func (s *Storage) DeleteUser(username string) error {
|
|||
_, err = stmt.Exec(username)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http
|
|||
|
||||
// Index
|
||||
router.HandleFunc("/", h.showIndexView).Methods(http.MethodGet)
|
||||
//router.HandleFunc("/login", h.showLoginView).Methods(http.MethodGet)
|
||||
//router.HandleFunc("/check-login", h.checkLogin).Methods(http.MethodPost)
|
||||
router.HandleFunc("/login", h.showLoginView).Methods(http.MethodGet)
|
||||
router.HandleFunc("/check-login", h.checkLogin).Methods(http.MethodPost)
|
||||
//router.HandleFunc("/help", h.showHelpView).Methods(http.MethodGet)
|
||||
//router.HandleFunc("/profile/{username}", h.showProfileView).Methods(http.MethodGet)
|
||||
//router.HandleFunc("/register", h.handleRegister)
|
||||
router.HandleFunc("/register", h.handleRegister)
|
||||
//router.HandleFunc("/editor", h.handleEditor)
|
||||
//router.HandleFunc("/upload", h.upload)
|
||||
//router.HandleFunc("/files", h.handleFiles)
|
||||
|
|
@ -71,7 +71,7 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http
|
|||
//router.HandleFunc("/homepages", h.showHomepagesView).Methods(http.MethodGet)
|
||||
//router.HandleFunc("/rename", h.handleRename)
|
||||
//router.HandleFunc("/delete", h.handleDelete).Methods(http.MethodPost)
|
||||
//router.HandleFunc("/logout", h.logout).Methods(http.MethodGet)
|
||||
router.HandleFunc("/logout", h.logout).Methods(http.MethodGet)
|
||||
//router.PathPrefix("/").Handler(http.FileServer(http.Dir(cfg.AssetsDir)))
|
||||
|
||||
return router, nil
|
||||
|
|
|
|||
|
|
@ -5,5 +5,45 @@ package handler
|
|||
var TplMap = map[string]string{
|
||||
"index": `{{ define "content" }}
|
||||
<p>This is the index</p>
|
||||
{{ end }}`,
|
||||
"login": `{{ define "content" }}
|
||||
<h1>Login</h1>
|
||||
{{ if .form.Error }}
|
||||
<p>{{ .form.Error }}</p>
|
||||
{{ end }}
|
||||
<form action="/check-login" method="post" class="auth-form">
|
||||
<div class="field">
|
||||
<label for="name">Username</label>
|
||||
<input type="text" id="name" name="name" autocomplete="off" required autofocus/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required/>
|
||||
</div>
|
||||
<br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
{{ end }}`,
|
||||
"register": `{{ define "content" }}
|
||||
<h1>Register</h1>
|
||||
{{ if .form.Error }}
|
||||
<p>{{ .form.Error }}</p>
|
||||
{{ end }}
|
||||
<form action="/register" method="post" class="auth-form">
|
||||
<div class="field">
|
||||
<label for="name">Username</label>
|
||||
<input type="text" id="name" name="name" autocomplete="off" required autofocus/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password-confirm">Confirm password</label>
|
||||
<input type="password" id="password-confirm" name="password-confirm" required/>
|
||||
</div>
|
||||
<br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
{{ end }}`,
|
||||
}
|
||||
|
|
|
|||
18
web/handler/html/login.html
Normal file
18
web/handler/html/login.html
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{{ define "content" }}
|
||||
<h1>Login</h1>
|
||||
{{ if .form.Error }}
|
||||
<p>{{ .form.Error }}</p>
|
||||
{{ end }}
|
||||
<form action="/check-login" method="post" class="auth-form">
|
||||
<div class="field">
|
||||
<label for="name">Username</label>
|
||||
<input type="text" id="name" name="name" autocomplete="off" required autofocus/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required/>
|
||||
</div>
|
||||
<br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
{{ end }}
|
||||
22
web/handler/html/register.html
Normal file
22
web/handler/html/register.html
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{{ define "content" }}
|
||||
<h1>Register</h1>
|
||||
{{ if .form.Error }}
|
||||
<p>{{ .form.Error }}</p>
|
||||
{{ end }}
|
||||
<form action="/register" method="post" class="auth-form">
|
||||
<div class="field">
|
||||
<label for="name">Username</label>
|
||||
<input type="text" id="name" name="name" autocomplete="off" required autofocus/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" required/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="password-confirm">Confirm password</label>
|
||||
<input type="password" id="password-confirm" name="password-confirm" required/>
|
||||
</div>
|
||||
<br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
{{ end }}
|
||||
|
|
@ -18,5 +18,5 @@ func (h *Handler) showIndexView(w http.ResponseWriter, r *http.Request) {
|
|||
// "News": news,
|
||||
//}, user)
|
||||
|
||||
h.renderLayout(w, "index", map[string]interface{}{}, "")
|
||||
h.renderLayout(w, "index", nil, "")
|
||||
}
|
||||
|
|
|
|||
27
web/handler/login_check.go
Normal file
27
web/handler/login_check.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"status/model"
|
||||
"status/web/handler/form"
|
||||
)
|
||||
|
||||
func (h *Handler) checkLogin(w http.ResponseWriter, r *http.Request) {
|
||||
f := form.NewLoginForm(r)
|
||||
user, err := h.storage.VerifyUser(model.User{
|
||||
Name: f.Username,
|
||||
Password: f.Password,
|
||||
})
|
||||
if err != nil {
|
||||
f.Error = "incorrect password"
|
||||
h.renderLayout(w, "login", map[string]interface{}{
|
||||
"form": f,
|
||||
}, "")
|
||||
return
|
||||
}
|
||||
if err := h.sess.Save(r, w, user.Name); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
}
|
||||
9
web/handler/login_show.go
Normal file
9
web/handler/login_show.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) showLoginView(w http.ResponseWriter, r *http.Request) {
|
||||
h.renderLayout(w, "login", nil, "")
|
||||
}
|
||||
11
web/handler/logout.go
Normal file
11
web/handler/logout.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package handler
|
||||
|
||||
import "net/http"
|
||||
|
||||
func (h *Handler) logout(w http.ResponseWriter, r *http.Request) {
|
||||
if err := h.sess.Delete(w, r); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
}
|
||||
117
web/handler/register.go
Normal file
117
web/handler/register.go
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"status/model"
|
||||
"status/web/handler/form"
|
||||
)
|
||||
|
||||
func (h *Handler) handleRegister(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
h.showRegisterView(w, r)
|
||||
case "POST":
|
||||
h.register(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) showRegisterView(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
h.renderLayout(w, "register", nil, "")
|
||||
}
|
||||
}
|
||||
|
||||
type keyStatus struct {
|
||||
Success bool `json:"success"`
|
||||
Uses int `json:"uses"`
|
||||
}
|
||||
|
||||
//func verifyKey(key string) error {
|
||||
// hc := http.Client{}
|
||||
//
|
||||
// f := url.Values{}
|
||||
// f.Add("product_permalink", "YccHL")
|
||||
// f.Add("license_key", key)
|
||||
// req, err := http.NewRequest("POST", "https://api.gumroad.com/v2/licenses/verify", strings.NewReader(f.Encode()))
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||
//
|
||||
// resp, err := hc.Do(req)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// if resp.Body != nil {
|
||||
// defer resp.Body.Close()
|
||||
// }
|
||||
//
|
||||
// body, readErr := ioutil.ReadAll(resp.Body)
|
||||
// if readErr != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// ks := keyStatus{}
|
||||
// jsonErr := json.Unmarshal(body, &ks)
|
||||
// if jsonErr != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// if ks.Success != true || ks.Uses > 1 {
|
||||
// return errors.New("invalid license key")
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func buildIndex(t *template.Template, name string) []byte {
|
||||
html := bytes.NewBufferString("")
|
||||
err := t.Execute(html, name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return html.Bytes()
|
||||
}
|
||||
|
||||
func (h *Handler) register(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case "POST":
|
||||
f := form.NewHomepageForm(r)
|
||||
showError := func(err error) {
|
||||
f.Error = err.Error()
|
||||
h.renderLayout(w, "register", map[string]interface{}{"form": *f}, "")
|
||||
return
|
||||
}
|
||||
if err := f.Validate(); err != nil {
|
||||
showError(err)
|
||||
return
|
||||
}
|
||||
user := model.User{
|
||||
Name: f.Username,
|
||||
Password: f.Password,
|
||||
}
|
||||
if err := user.Validate(); err != nil {
|
||||
showError(err)
|
||||
return
|
||||
}
|
||||
if h.storage.UserExists(user.Name) {
|
||||
showError(errors.New("username already exists"))
|
||||
return
|
||||
}
|
||||
if err := h.storage.CreateUser(user); err != nil {
|
||||
showError(err)
|
||||
return
|
||||
}
|
||||
if err := h.sess.Save(r, w, r.FormValue("name")); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
h.renderLayout(w, "index", nil, user.Name)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue