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