Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
add users to the handlers
Loading branch information
Showing
7 changed files
with
76 additions
and
15 deletions .
+14
−2
context.go
+39
−7
handlers.go
+3
−0
http.go
+8
−0
main.go
+6
−5
templates/index.html
+5
−0
templates/login.html
+1
−1
user.go
@@ -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 () {
@@ -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
}
@@ -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
@@ -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."
}
@@ -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
}
@@ -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
}
defer ctx .Close ()
@@ -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
}
//save the session
if err = ctx .Session .Save (req , buf ); err != nil {
http .Error (w , err .Error (), http .StatusInternalServerError )
return
}
//apply the buffered response to the writer
@@ -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"
)
@@ -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
@@ -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" )
@@ -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 >
@@ -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 }}
@@ -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 >
@@ -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 )
if err != nil {
return
}
Toggle all file notes
Whoops! If there's an error, we should just print it and exit instead of continuing with the handler.