auth

Paddy 2014-08-16 Parent:51700827b6ee

22:e6a44cfda658 Go to Latest

auth/session.go

Redirect unauthenticated users to the login page. Redirect unauthenticated users to the login page, and encode the current URL in the redirect_to param so that the user returns to the OAuth2 flow after they log in.

History
paddy@6 1 package auth
paddy@1 2
paddy@19 3 import (
paddy@19 4 "errors"
paddy@19 5 "net/http"
paddy@21 6 "net/url"
paddy@19 7 "time"
paddy@19 8
paddy@21 9 "strings"
paddy@19 10 "secondbit.org/uuid"
paddy@19 11 )
paddy@19 12
paddy@19 13 const sessionCookie = "session"
paddy@19 14
paddy@19 15 var (
paddy@19 16 ErrSessionNotFound = errors.New("Session not found.")
paddy@19 17 )
paddy@19 18
paddy@19 19 type Session struct {
paddy@19 20 Token string
paddy@19 21 User uuid.ID
paddy@19 22 Expires time.Time
paddy@19 23 Created time.Time
paddy@19 24 IP string
paddy@19 25 }
paddy@1 26
paddy@2 27 func validateSession(r *http.Request, c Context) error {
paddy@19 28 cookie, err := r.Cookie(sessionCookie)
paddy@19 29 if err == http.ErrNoCookie {
paddy@19 30 return ErrSessionNotFound
paddy@19 31 }
paddy@19 32 _, err = c.Sessions.GetSession(cookie.Value)
paddy@19 33 return err
paddy@1 34 }
paddy@19 35
paddy@19 36 func HandleLoginRequest(w http.ResponseWriter, r *http.Request, ctx Context) {
paddy@19 37 if r.Method == "GET" {
paddy@19 38 ctx.RenderLogin(w, r)
paddy@19 39 return
paddy@19 40 } else if r.Method != "POST" {
paddy@19 41 // TODO: return bad method error
paddy@19 42 return
paddy@19 43 }
paddy@19 44
paddy@19 45 if r.FormValue("username") == "" || r.FormValue("password") == "" {
paddy@19 46 // TODO: return unauthenticated error
paddy@19 47 return
paddy@19 48 }
paddy@19 49 id, err := ctx.Profiles.GetProfile(r.FormValue("username"), r.FormValue("password"))
paddy@19 50 if err != nil {
paddy@19 51 if err == ErrProfileNotFound {
paddy@19 52 // TODO: return unauthenticated error
paddy@19 53 return
paddy@19 54 }
paddy@19 55 // TODO: return internal server error
paddy@19 56 return
paddy@19 57 }
paddy@19 58 session := Session{
paddy@19 59 Token: newToken(),
paddy@19 60 User: id,
paddy@19 61 Expires: time.Now().Add(ctx.Config.SessionLength),
paddy@19 62 Created: time.Now(),
paddy@19 63 IP: r.Header.Get(ctx.Config.RequestIPHeader),
paddy@19 64 }
paddy@19 65 err = ctx.Sessions.SetSession(session)
paddy@19 66 if err != nil {
paddy@19 67 // TODO: return internal server error
paddy@19 68 return
paddy@19 69 }
paddy@19 70 http.SetCookie(w, &http.Cookie{
paddy@19 71 Name: sessionCookie,
paddy@19 72 Value: session.Token,
paddy@19 73 Expires: session.Expires,
paddy@19 74 Secure: true,
paddy@19 75 HttpOnly: true,
paddy@19 76 })
paddy@21 77
paddy@21 78 redirectString := r.URL.Query().Get("redirect_to")
paddy@21 79 if redirectString != "" {
paddy@21 80 redirectURI, err := url.Parse(redirectString)
paddy@21 81 if err != nil {
paddy@21 82 // TODO: render a bad request error
paddy@21 83 return
paddy@21 84 }
paddy@21 85 if !strings.HasSuffix("."+ctx.Config.LoginRedirectDomain, redirectURI.Host) && redirectURI.Host != ctx.Config.LoginRedirectDomain {
paddy@21 86 // TODO: render a bad request error
paddy@21 87 return
paddy@21 88 }
paddy@21 89 } else {
paddy@21 90 redirectString = "https://" + ctx.Config.LoginRedirectDomain
paddy@21 91 }
paddy@21 92 http.Redirect(w, r, redirectString, http.StatusFound)
paddy@21 93 return
paddy@19 94 }