Skip to content

Commit

Permalink
add users to the handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
zeebo committed Sep 5, 2012
1 parent 85b30a6 commit 7c2ff89
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 15 deletions.
16 changes: 14 additions & 2 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package main
import (
"code.google.com/p/gorilla/sessions"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
)

type Context struct {
Database *mgo.Database
Session *sessions.Session
User *User
}

func (c *Context) Close() {
Expand All @@ -22,8 +24,18 @@ func (c *Context) C(name string) *mgo.Collection {

func NewContext(req *http.Request) (*Context, error) {
sess, err := store.Get(req, "gostbook")
return &Context{
ctx := &Context{
Database: session.Clone().DB(database),
Session: sess,
}, err
}
if err != nil {
return ctx, err
}

//try to fill in the user from the session
if uid, ok := sess.Values["user"].(bson.ObjectId); ok {
err = ctx.C("users").Find(bson.M{"_id": uid}).One(&ctx.User)
}

return ctx, err
}
46 changes: 39 additions & 7 deletions handlers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package main

import "net/http"
import (
"errors"
"net/http"
)

func hello(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
//set up the collection and query
Expand All @@ -15,17 +18,23 @@ func hello(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
}

//execute the template
return T("index.html").Execute(w, entries)
return T("index.html").Execute(w, map[string]interface{}{
"entries": entries,
"ctx": ctx,
})
}

func sign(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
//we need a user to sign to
if ctx.User == nil {
err = errors.New("Can't sign without being logged in")
return
}

entry := NewEntry()
entry.Name = req.FormValue("name")
entry.Name = ctx.User.Username
entry.Message = req.FormValue("message")

if entry.Name == "" {
entry.Name = "Some dummy who forgot a name"
}
if entry.Message == "" {
entry.Message = "Some dummy who forgot a message."
}
Expand All @@ -40,5 +49,28 @@ func sign(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
}

func loginForm(w http.ResponseWriter, req *http.Request, ctx *Context) (err error) {
return T("login.html").Execute(w, nil)
return T("login.html").Execute(w, map[string]interface{}{
"ctx": ctx,
})
}

func login(w http.ResponseWriter, req *http.Request, ctx *Context) error {
username, password := req.FormValue("username"), req.FormValue("password")

user, e := Login(ctx, username, password)
if e != nil {
ctx.Session.AddFlash("Invalid Username/Password")
return loginForm(w, req, ctx)
}

//store the user id in the values and redirect to index
ctx.Session.Values["user"] = user.ID
http.Redirect(w, req, reverse("index"), http.StatusSeeOther)
return nil
}

func logout(w http.ResponseWriter, req *http.Request, ctx *Context) error {
delete(ctx.Session.Values, "user")
http.Redirect(w, req, reverse("index"), http.StatusSeeOther)
return nil
}
3 changes: 3 additions & 0 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
ctx, err := NewContext(req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

This comment has been minimized.

Copy link
@zeebo

zeebo Sep 5, 2012

Author Owner

Whoops! If there's an error, we should just print it and exit instead of continuing with the handler.

}
defer ctx.Close()

Expand All @@ -20,11 +21,13 @@ func (h handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
err = h(buf, req, ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

This comment has been minimized.

Copy link
@zeebo

zeebo Sep 5, 2012

Author Owner

Same as above.

}

//save the session
if err = ctx.Session.Save(req, buf); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

This comment has been minimized.

Copy link
@zeebo

zeebo Sep 5, 2012

Author Owner

Same as above.

}

//apply the buffered response to the writer
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package main
import (
"code.google.com/p/gorilla/pat"
"code.google.com/p/gorilla/sessions"
"encoding/gob"
"fmt"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"net/http"
"os"
)
Expand All @@ -23,6 +25,10 @@ func reverse(name string, things ...interface{}) string {
return u.Path
}

func init() {
gob.Register(bson.ObjectId(""))
}

var store sessions.Store
var session *mgo.Session
var database string
Expand All @@ -40,6 +46,8 @@ func main() {

router = pat.New()
router.Add("GET", "/login", handler(loginForm)).Name("login")
router.Add("GET", "/logout", handler(logout)).Name("logout")
router.Add("POST", "/login", handler(login))
router.Add("GET", "/", handler(hello)).Name("index")
router.Add("POST", "/sign", handler(sign)).Name("sign")

Expand Down
11 changes: 6 additions & 5 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h1>Guestbook</h1>
<p>Hello, and welcome to my guestbook, because it's 1997!</p>

<ul class="guests">
{{ range . }}
{{ range .entries }}
<li>
<blockquote>{{ .Message }}</blockquote>
<p>- <cite>{{ .Name }}</cite>, <time>{{ .Timestamp }}</time></p>
Expand All @@ -15,12 +15,13 @@ <h1>Guestbook</h1>
</ul>

<hr>
<a href="{{ reverse "login" }}">login</a>
<hr>

{{ if .ctx.User }}
<form action="{{ reverse "sign" }}" method="POST">
<p>Name: <input type="text" name="name"></p>
<p>Name: {{ .ctx.User.Username }} (<a href="{{ reverse "logout" }}">Logout</a>)</p>
<p>Message: <textarea name="message" rows="10" cols="40"></textarea></p>
<p><button>Sign</button></p>
</form>
{{ else }}
<h1>Please <a href="{{ reverse "login" }}">login</a> to sign.</h1>
{{ end }}
{{ end }}
5 changes: 5 additions & 0 deletions templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

{{ define "content" }}
<h1>Login</h1>

{{ range .ctx.Session.Flashes }}
<h2>{{ . }}</h2>
{{ end }}

<form action="{{ reverse "login" }}" method="POST">
<p>Username: <input type="text" name="username"></p>
<p>Password: <input type="password" name="password"></p>
Expand Down
2 changes: 1 addition & 1 deletion user.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (u *User) SetPassword(password string) {

//Login validates and returns a user object if they exist in the database.
func Login(ctx *Context, username, password string) (u *User, err error) {
err = ctx.C("users").Find(bson.M{"username": username}).One(u)
err = ctx.C("users").Find(bson.M{"username": username}).One(&u)

This comment has been minimized.

Copy link
@zeebo

zeebo Sep 5, 2012

Author Owner

Oops! I forgot to pass in the address of the user and it would cause an error. This actually is what caused me to find the return cases above. One thing I'm missing in this is tests that would fix issues like this before they got into commits! :)

if err != nil {
return
}
Expand Down

0 comments on commit 7c2ff89

Please sign in to comment.