Skip to content

Commit b85778a

Browse files
committed
login user
1 parent 63db516 commit b85778a

File tree

4 files changed

+132
-3
lines changed

4 files changed

+132
-3
lines changed

cmd/web/handlers.go

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,54 @@ func (app *App) CreateUser(w http.ResponseWriter, r *http.Request) {
161161
}
162162

163163
func (app *App) LoginUser(w http.ResponseWriter, r *http.Request) {
164-
fmt.Fprint(w, "LoginUser")
164+
session := app.sessions.Load(r)
165+
flash, err := session.PopString(w, "flash")
166+
if err != nil {
167+
app.ServerError(w, err)
168+
return
169+
}
170+
171+
app.RenderHtml(w, r, "login.page.html", &HtmlData{
172+
Form: &forms.LoginUser{},
173+
Flash: flash,
174+
})
165175
}
166176

167177
func (app *App) VerifyUser(w http.ResponseWriter, r *http.Request) {
168-
fmt.Fprint(w, "VerifyUser")
178+
err := r.ParseForm()
179+
if err != nil {
180+
app.ClientError(w, http.StatusBadRequest)
181+
return
182+
}
183+
184+
form := &forms.LoginUser{
185+
Email: r.PostForm.Get("email"),
186+
Password: r.PostForm.Get("password"),
187+
}
188+
189+
if !form.Valid() {
190+
app.RenderHtml(w, r, "login.page.html", &HtmlData{Form: form})
191+
return
192+
}
193+
194+
currentUserId, err := app.database.VerifyUser(form.Email, form.Password)
195+
if err == models.ErrInvalidCredentials {
196+
form.Failures["Generic"] = "Email or Password incorret"
197+
app.RenderHtml(w, r, "login.page.html", &HtmlData{Form: form})
198+
return
199+
} else if err != nil {
200+
app.ServerError(w, err)
201+
return
202+
}
203+
204+
session := app.sessions.Load(r)
205+
err = session.PutInt(w, "currentUserId", currentUserId)
206+
if err != nil {
207+
app.ServerError(w, err)
208+
return
209+
}
210+
211+
http.Redirect(w, r, "/snippet/new", http.StatusSeeOther)
169212
}
170213

171214
func (app *App) LogoutUser(w http.ResponseWriter, r *http.Request) {

pkg/forms/forms.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ type SignupUser struct {
2222
Failures map[string]string
2323
}
2424

25+
type LoginUser struct {
26+
Email string
27+
Password string
28+
Failures map[string]string
29+
}
30+
2531
func (ns *NewSnippet) Valid() bool {
2632
ns.Failures = make(map[string]string)
2733

@@ -68,3 +74,21 @@ func (su *SignupUser) Valid() bool {
6874

6975
return len(su.Failures) == 0
7076
}
77+
78+
func (lu *LoginUser) Valid() bool {
79+
lu.Failures = make(map[string]string)
80+
81+
if len(strings.TrimSpace(lu.Email)) == 0 {
82+
lu.Failures["Email"] = "Email is required"
83+
} else if len(strings.TrimSpace(lu.Email)) > 254 || !rxEmail.MatchString(lu.Email) {
84+
lu.Failures["Email"] = "Email is not valid"
85+
}
86+
87+
if len(strings.TrimSpace(lu.Password)) == 0 {
88+
lu.Failures["Password"] = "Password is required"
89+
} else if utf8.RuneCountInString(lu.Password) < 8 {
90+
lu.Failures["Password"] = "Password is too short"
91+
}
92+
93+
return len(lu.Failures) == 0
94+
}

pkg/models/database.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ type Database struct {
1212
*sql.DB
1313
}
1414

15-
var ErrDuplicateEmail = errors.New("models: email address already in use")
15+
var (
16+
ErrDuplicateEmail = errors.New("models: email address already in use")
17+
ErrInvalidCredentials = errors.New("models: invalid credentials")
18+
)
1619

1720
func (db *Database) GetSnippet(id int) (*Snippet, error) {
1821
stmt := `SELECT id, title, content, created, expires FROM snippets
@@ -153,3 +156,27 @@ func (db *Database) InsertUser(name, email, password string) error {
153156
}
154157
return err
155158
}
159+
160+
func (db *Database) VerifyUser(email, password string) (int, error) {
161+
stmt := `SELECT id, password FROM users
162+
WHERE email = ?`
163+
164+
var id int
165+
var hashedPassword []byte
166+
row := db.QueryRow(stmt, email)
167+
err := row.Scan(&id, &hashedPassword)
168+
if err == sql.ErrNoRows {
169+
return 0, ErrInvalidCredentials
170+
} else if err != nil {
171+
return 0, err
172+
}
173+
174+
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password))
175+
if err == bcrypt.ErrMismatchedHashAndPassword {
176+
return 0, ErrInvalidCredentials
177+
} else if err != nil {
178+
return 0, err
179+
}
180+
181+
return id, nil
182+
}

ui/html/login.page.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{{define "page-title"}}Login{{end}}
2+
3+
{{define "page-body"}}
4+
{{with .Flash}}
5+
<div class="flash">{{.}}</div>
6+
{{end}}
7+
<form action="/user/login" method="POST" novalidate>
8+
{{with .Form}}
9+
{{with .Failures.Generic}}
10+
<div class="error">{{.}}</div>
11+
{{end}}
12+
<div>
13+
<label>Email:</label>
14+
{{with .Failures.Email}}
15+
<label class="error">{{.}}</label>
16+
{{end}}
17+
<input type="email" name="email" value="{{.Email}}">
18+
</div>
19+
<div>
20+
<label>Password:</label>
21+
{{with .Failures.Password}}
22+
<label class="error">{{.}}</label>
23+
{{end}}
24+
<input type="password" name="password">
25+
</div>
26+
<div>
27+
<input type="submit" value="Submit">
28+
</div>
29+
{{end}}
30+
</form>
31+
{{end}}
32+
33+
{{define "page-footer"}}
34+
Entrance to a heaven
35+
{{- end}}

0 commit comments

Comments
 (0)