auth
auth/session.go
Check session before rendering confirmation page. The confirmation page should not be rendered until the session is set. Check the request method, then check the session, then finally render the confirmation page, should we need to.
| paddy@6 | 1 package auth |
| paddy@1 | 2 |
| paddy@19 | 3 import ( |
| paddy@19 | 4 "errors" |
| paddy@19 | 5 "net/http" |
| paddy@19 | 6 "time" |
| paddy@19 | 7 |
| paddy@19 | 8 "secondbit.org/uuid" |
| paddy@19 | 9 ) |
| paddy@19 | 10 |
| paddy@19 | 11 const sessionCookie = "session" |
| paddy@19 | 12 |
| paddy@19 | 13 var ( |
| paddy@19 | 14 ErrSessionNotFound = errors.New("Session not found.") |
| paddy@19 | 15 ) |
| paddy@19 | 16 |
| paddy@19 | 17 type Session struct { |
| paddy@19 | 18 Token string |
| paddy@19 | 19 User uuid.ID |
| paddy@19 | 20 Expires time.Time |
| paddy@19 | 21 Created time.Time |
| paddy@19 | 22 IP string |
| paddy@19 | 23 } |
| paddy@1 | 24 |
| paddy@2 | 25 func validateSession(r *http.Request, c Context) error { |
| paddy@19 | 26 cookie, err := r.Cookie(sessionCookie) |
| paddy@19 | 27 if err == http.ErrNoCookie { |
| paddy@19 | 28 return ErrSessionNotFound |
| paddy@19 | 29 } |
| paddy@19 | 30 _, err = c.Sessions.GetSession(cookie.Value) |
| paddy@19 | 31 return err |
| paddy@1 | 32 } |
| paddy@19 | 33 |
| paddy@19 | 34 func HandleLoginRequest(w http.ResponseWriter, r *http.Request, ctx Context) { |
| paddy@19 | 35 if r.Method == "GET" { |
| paddy@19 | 36 ctx.RenderLogin(w, r) |
| paddy@19 | 37 return |
| paddy@19 | 38 } else if r.Method != "POST" { |
| paddy@19 | 39 // TODO: return bad method error |
| paddy@19 | 40 return |
| paddy@19 | 41 } |
| paddy@19 | 42 |
| paddy@19 | 43 if r.FormValue("username") == "" || r.FormValue("password") == "" { |
| paddy@19 | 44 // TODO: return unauthenticated error |
| paddy@19 | 45 return |
| paddy@19 | 46 } |
| paddy@19 | 47 id, err := ctx.Profiles.GetProfile(r.FormValue("username"), r.FormValue("password")) |
| paddy@19 | 48 if err != nil { |
| paddy@19 | 49 if err == ErrProfileNotFound { |
| paddy@19 | 50 // TODO: return unauthenticated error |
| paddy@19 | 51 return |
| paddy@19 | 52 } |
| paddy@19 | 53 // TODO: return internal server error |
| paddy@19 | 54 return |
| paddy@19 | 55 } |
| paddy@19 | 56 session := Session{ |
| paddy@19 | 57 Token: newToken(), |
| paddy@19 | 58 User: id, |
| paddy@19 | 59 Expires: time.Now().Add(ctx.Config.SessionLength), |
| paddy@19 | 60 Created: time.Now(), |
| paddy@19 | 61 IP: r.Header.Get(ctx.Config.RequestIPHeader), |
| paddy@19 | 62 } |
| paddy@19 | 63 err = ctx.Sessions.SetSession(session) |
| paddy@19 | 64 if err != nil { |
| paddy@19 | 65 // TODO: return internal server error |
| paddy@19 | 66 return |
| paddy@19 | 67 } |
| paddy@19 | 68 http.SetCookie(w, &http.Cookie{ |
| paddy@19 | 69 Name: sessionCookie, |
| paddy@19 | 70 Value: session.Token, |
| paddy@19 | 71 Expires: session.Expires, |
| paddy@19 | 72 Secure: true, |
| paddy@19 | 73 HttpOnly: true, |
| paddy@19 | 74 }) |
| paddy@19 | 75 // TODO: redirect |
| paddy@19 | 76 } |