/
main.go
95 lines (72 loc) · 2.13 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package main
import (
"database/sql"
"net/http"
"code.google.com/p/go.crypto/bcrypt"
"github.com/go-martini/martini"
_ "github.com/lib/pq"
"github.com/martini-contrib/sessions"
)
type User struct {
Name string
Email string
}
func SetupDB() *sql.DB {
db, err := sql.Open("postgres", "dbname=lesson7 sslmode=disable")
PanicIf(err)
return db
}
func PanicIf(err error) {
if err != nil {
panic(err)
}
}
func main() {
m := martini.Classic()
m.Map(SetupDB())
// Sessions
store := sessions.NewCookieStore([]byte("secret123"))
m.Use(sessions.Sessions("lesson8", store))
m.Get("/", RequireLogin, SecretPath)
m.Post("/login", PostLogin)
m.Get("/logout", Logout)
m.Post("/signup", Signup)
m.Run()
}
func Signup(rw http.ResponseWriter, r *http.Request, db *sql.DB) {
name, email, password := r.FormValue("name"), r.FormValue("email"), r.FormValue("password")
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
PanicIf(err)
_, err = db.Exec("insert into users (name, email, password) values ($1, $2, $3)",
name, email, hashedPassword)
PanicIf(err)
http.Redirect(rw, r, "/login", http.StatusFound)
}
func Logout(rw http.ResponseWriter, req *http.Request, s sessions.Session) {
s.Delete("userId")
http.Redirect(rw, req, "/", http.StatusFound)
}
func RequireLogin(rw http.ResponseWriter, req *http.Request,
s sessions.Session, db *sql.DB, c martini.Context) {
user := &User{}
err := db.QueryRow("select name, email from users where id=$1", s.Get("userId")).Scan(&user.Name, &user.Email)
if err != nil {
http.Redirect(rw, req, "/login", http.StatusFound)
return
}
c.Map(user)
}
func SecretPath(user *User) string {
return "Great Job " + user.Name
}
func PostLogin(req *http.Request, db *sql.DB, s sessions.Session) (int, string) {
var id string
var pw string
email, password := req.FormValue("email"), req.FormValue("password")
err := db.QueryRow("select id, password from users where email=$1", email).Scan(&id, &pw)
if err != nil || bcrypt.CompareHashAndPassword([]byte(pw), []byte(password)) != nil {
return 401, "Unauthorized"
}
s.Set("userId", id)
return 200, "User id is " + id
}