auth
2014-09-01
auth/session.go.old
Deprecate old implementations. Let's remove all of the osin stuff altogether, in favour of a more testable, unit-based approach. Leave all the old files around, for easy reference, but add the .old suffix so the go tools don't pick them up.
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 Profile uuid.ID
22 Expires time.Time
23 Created time.Time
24 IP string
25 }
27 type SessionStore interface {
28 GetSession(token string) (Session, error)
29 GetAllSessions(userID uuid.ID, num, page int) ([]Session, error)
30 SaveSession(session Session) error
31 DeleteSession(sessionID uuid.ID) error
32 }
34 func validateSession(r *http.Request, c Context) error {
35 cookie, err := r.Cookie(sessionCookie)
36 if err == http.ErrNoCookie {
37 return ErrSessionNotFound
38 }
39 _, err = c.Sessions.GetSession(cookie.Value)
40 return err
41 }
43 func HandleLoginRequest(w http.ResponseWriter, r *http.Request, ctx Context) {
44 if r.Method == "GET" {
45 ctx.RenderLogin(w, r)
46 return
47 } else if r.Method != "POST" {
48 // TODO: return bad method error
49 return
50 }
52 if r.FormValue("username") == "" || r.FormValue("password") == "" {
53 // TODO: return unauthenticated error
54 return
55 }
56 id, err := ctx.Profiles.GetProfile(r.FormValue("username"), r.FormValue("password"))
57 if err != nil {
58 if err == ErrProfileNotFound {
59 // TODO: return unauthenticated error
60 return
61 }
62 // TODO: return internal server error
63 return
64 }
65 session := Session{
66 Token: newToken(),
67 Profile: id,
68 Expires: time.Now().Add(ctx.Config.SessionLength),
69 Created: time.Now(),
70 IP: r.Header.Get(ctx.Config.RequestIPHeader),
71 }
72 err = ctx.Sessions.SetSession(session)
73 if err != nil {
74 // TODO: return internal server error
75 return
76 }
77 http.SetCookie(w, &http.Cookie{
78 Name: sessionCookie,
79 Value: session.Token,
80 Expires: session.Expires,
81 Secure: true,
82 HttpOnly: true,
83 })
85 redirectString := r.URL.Query().Get("redirect_to")
86 if redirectString != "" {
87 redirectURI, err := url.Parse(redirectString)
88 if err != nil {
89 // TODO: render a bad request error
90 return
91 }
92 if !strings.HasSuffix("."+ctx.Config.LoginRedirectDomain, redirectURI.Host) && redirectURI.Host != ctx.Config.LoginRedirectDomain {
93 // TODO: render a bad request error
94 return
95 }
96 } else {
97 redirectString = "https://" + ctx.Config.LoginRedirectDomain
98 }
99 http.Redirect(w, r, redirectString, http.StatusFound)
100 return
101 }