auth
2014-08-16
Parent:1f04b1146cad
auth/context.go
Implement session management and move login. Add a session store interface to validate and retrieve data about sessions. Implement session management in endpoints that need session support. Move the login functionality from inlined into the OAuth flow into its own handler, that the OAuth flow will redirect to. The login functionality should take a redirect URL parameter to return to the OAuth flow when login is completed.
| paddy@6 | 1 package auth |
| paddy@0 | 2 |
| paddy@10 | 3 import ( |
| paddy@15 | 4 "encoding/json" |
| paddy@15 | 5 "html/template" |
| paddy@10 | 6 "io" |
| paddy@10 | 7 "log" |
| paddy@17 | 8 "net/http" |
| paddy@17 | 9 |
| paddy@17 | 10 "github.com/justinas/nosurf" |
| paddy@10 | 11 ) |
| paddy@1 | 12 |
| paddy@0 | 13 type Context struct { |
| paddy@15 | 14 Config ServerConfig |
| paddy@15 | 15 Clients ClientStore |
| paddy@15 | 16 Tokens TokenStore |
| paddy@15 | 17 Profiles ProfileStore |
| paddy@19 | 18 Sessions SessionStore |
| paddy@15 | 19 Log *log.Logger |
| paddy@15 | 20 Templates Templates |
| paddy@15 | 21 } |
| paddy@15 | 22 |
| paddy@15 | 23 type Templates struct { |
| paddy@15 | 24 Error *template.Template |
| paddy@15 | 25 Confirmation *template.Template |
| paddy@15 | 26 Login *template.Template |
| paddy@15 | 27 } |
| paddy@15 | 28 |
| paddy@15 | 29 type jsonError struct { |
| paddy@15 | 30 Error string `json:"error,omitempty"` |
| paddy@15 | 31 Description string `json:"error_description,omitempty"` |
| paddy@15 | 32 URI string `json:"error_uri,omitempty"` |
| paddy@15 | 33 State string `json:"state,omitempty"` |
| paddy@0 | 34 } |
| paddy@1 | 35 |
| paddy@1 | 36 func (c Context) RenderError(w io.Writer, err error) { |
| paddy@15 | 37 if c.Templates.Error == nil { |
| paddy@15 | 38 log.Println("Error template is nil, can't render error.") |
| paddy@15 | 39 return |
| paddy@15 | 40 } |
| paddy@15 | 41 renderErr := c.Templates.Error.Execute(w, map[string]interface{}{ |
| paddy@15 | 42 "err": err, |
| paddy@15 | 43 }) |
| paddy@15 | 44 if renderErr != nil { |
| paddy@15 | 45 log.Printf("Error executing error template (oh, the irony): %s\n", renderErr) |
| paddy@15 | 46 return |
| paddy@15 | 47 } |
| paddy@1 | 48 } |
| paddy@1 | 49 |
| paddy@3 | 50 func (c Context) RenderJSONError(w io.Writer, code, description, baseURI string) { |
| paddy@15 | 51 d, err := json.Marshal(jsonError{ |
| paddy@15 | 52 Error: code, |
| paddy@15 | 53 Description: description, |
| paddy@15 | 54 URI: baseURI, |
| paddy@15 | 55 }) |
| paddy@15 | 56 if err != nil { |
| paddy@15 | 57 log.Printf("Error marshalling json error (oh, the irony): %s\n", err) |
| paddy@15 | 58 return |
| paddy@15 | 59 } |
| paddy@15 | 60 _, err = w.Write(d) |
| paddy@15 | 61 if err != nil { |
| paddy@15 | 62 log.Printf("Error writing json error: %s\n", err) |
| paddy@15 | 63 return |
| paddy@15 | 64 } |
| paddy@3 | 65 } |
| paddy@3 | 66 |
| paddy@17 | 67 func (c Context) RenderConfirmation(w io.Writer, r *http.Request, req AuthRequest) { |
| paddy@15 | 68 if c.Templates.Confirmation == nil { |
| paddy@15 | 69 log.Println("Confirmation template is nil, can't render confirmation.") |
| paddy@15 | 70 return |
| paddy@15 | 71 } |
| paddy@17 | 72 err := c.Templates.Confirmation.Execute(w, map[string]interface{}{ |
| paddy@17 | 73 "scope": req.Scope, |
| paddy@17 | 74 "client": req.Client, |
| paddy@17 | 75 "csrf_token": nosurf.Token(r), |
| paddy@17 | 76 }) |
| paddy@15 | 77 if err != nil { |
| paddy@15 | 78 log.Printf("Error executing confirmation template: %s\n", err) |
| paddy@15 | 79 return |
| paddy@15 | 80 } |
| paddy@1 | 81 } |
| paddy@1 | 82 |
| paddy@17 | 83 func (c Context) RenderLogin(w io.Writer, r *http.Request) { |
| paddy@15 | 84 if c.Templates.Login == nil { |
| paddy@15 | 85 log.Println("Login template is nil, can't render confirmation.") |
| paddy@15 | 86 return |
| paddy@15 | 87 } |
| paddy@17 | 88 err := c.Templates.Login.Execute(w, map[string]interface{}{ |
| paddy@17 | 89 "csrf_token": nosurf.Token(r), |
| paddy@17 | 90 }) |
| paddy@15 | 91 if err != nil { |
| paddy@15 | 92 log.Printf("Error executing login template: %s\n", err) |
| paddy@15 | 93 return |
| paddy@15 | 94 } |
| paddy@1 | 95 } |
| paddy@4 | 96 |
| paddy@4 | 97 func (c Context) RenderJSONToken(w io.Writer, data AccessData) { |
| paddy@15 | 98 d, err := json.Marshal(data) |
| paddy@15 | 99 if err != nil { |
| paddy@15 | 100 log.Printf("Error marshalling json token: %s\n", err) |
| paddy@15 | 101 return |
| paddy@15 | 102 } |
| paddy@15 | 103 _, err = w.Write(d) |
| paddy@15 | 104 if err != nil { |
| paddy@15 | 105 log.Printf("Error writing json token: %s\n", err) |
| paddy@15 | 106 return |
| paddy@15 | 107 } |
| paddy@4 | 108 } |