auth
auth/config.go
Enable CSRF protection, add expiration to sessions. Sessions gain a CSRF token, which is passed as a parameter to the login page. The login page now checks for that CSRF token, and logs a CSRF attempt if the token does not match. I also added an expiration to sessions, so they don't last forever. Sessions should be pretty short--we just need to stay logged in for long enough to approve the OAuth request. Everything after that should be cookie based. Finally, I added a configuration parameter to control whether the session cookie should be set to Secure, requiring the use of HTTPS. For production use, this flag is a requirement, but it makes testing extremely difficult, so we need a way to disable it.
| paddy@96 | 1 package auth |
| paddy@96 | 2 |
| paddy@96 | 3 import ( |
| paddy@96 | 4 "errors" |
| paddy@96 | 5 "html/template" |
| paddy@101 | 6 "log" |
| paddy@96 | 7 ) |
| paddy@96 | 8 |
| paddy@96 | 9 var ( |
| paddy@96 | 10 // ErrInvalidLoginURI is returned when a Context is instantiated with a Config object that specifies a LoginURI that can't be parsed as a URL. |
| paddy@96 | 11 ErrInvalidLoginURI = errors.New("invalid login URI") |
| paddy@102 | 12 // ErrConfigNotInitialized is returned when a Context is instantiated with a Config object that hasn't had its Init function called. |
| paddy@102 | 13 ErrConfigNotInitialized = errors.New("config not initialized") |
| paddy@96 | 14 ) |
| paddy@96 | 15 |
| paddy@96 | 16 // Config holds the configuration values necessary to run a server. A Config |
| paddy@96 | 17 // instance is the only way to instantiate a Context variable. |
| paddy@96 | 18 type Config struct { |
| paddy@96 | 19 ClientStore clientStore |
| paddy@96 | 20 AuthCodeStore authorizationCodeStore |
| paddy@96 | 21 ProfileStore profileStore |
| paddy@96 | 22 TokenStore tokenStore |
| paddy@96 | 23 SessionStore sessionStore |
| paddy@96 | 24 Template *template.Template |
| paddy@96 | 25 LoginURI string |
| paddy@96 | 26 iterations int |
| paddy@132 | 27 secureCookie bool |
| paddy@96 | 28 } |
| paddy@101 | 29 |
| paddy@102 | 30 // Init is a function that preps the Config object to be used for Context creation, setting variables |
| paddy@102 | 31 // that are determined at the beginning of program execution. |
| paddy@101 | 32 func (c *Config) Init() error { |
| paddy@101 | 33 scheme, ok := passphraseSchemes[CurPassphraseScheme] |
| paddy@101 | 34 if !ok { |
| paddy@101 | 35 return ErrInvalidPassphraseScheme |
| paddy@101 | 36 } |
| paddy@101 | 37 var err error |
| paddy@101 | 38 c.iterations, err = scheme.calculateIterations() |
| paddy@101 | 39 if err != nil { |
| paddy@101 | 40 return err |
| paddy@101 | 41 } |
| paddy@101 | 42 log.Printf("Generating passphrases with %d iterations...\n", c.iterations) |
| paddy@101 | 43 return nil |
| paddy@101 | 44 } |