auth
auth/config.go
Refactor verifyClient, implement refresh tokens. Refactor verifyClient into verifyClient and getClientAuth. We moved verifyClient out of each of the GrantType's validation functions and into the access token endpoint, where it will be called before the GrantType's validation function. Yay, less code repetition. And seeing as we always want to verify the client, that seems like a good way to prevent things like 118a69954621 from happening. This did, however, force us to add an AllowsPublic property to the GrantType, so the token endpoint knows whether or not a public Client is valid for any given GrantType. We also implemented the refresh token grant type, which required adding ClientID and RefreshRevoked as properties on the Token type. We need ClientID because we need to constrain refresh tokens to the client that issued them. We also should probably keep track of which tokens belong to which clients, just as a general rule of thumb. RefreshRevoked had to be created, next to Revoked, because the AccessToken could be revoked and the RefreshToken still valid, or vice versa. Notably, when you issue a new refresh token, the old one is revoked, but the access token is still valid. It remains to be seen whether this is a good way to track things or not. The number of duplicated properties lead me to believe our type is not a great representation of the underlying concepts.
| 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@96 | 27 } |
| paddy@101 | 28 |
| paddy@102 | 29 // Init is a function that preps the Config object to be used for Context creation, setting variables |
| paddy@102 | 30 // that are determined at the beginning of program execution. |
| paddy@101 | 31 func (c *Config) Init() error { |
| paddy@101 | 32 scheme, ok := passphraseSchemes[CurPassphraseScheme] |
| paddy@101 | 33 if !ok { |
| paddy@101 | 34 return ErrInvalidPassphraseScheme |
| paddy@101 | 35 } |
| paddy@101 | 36 var err error |
| paddy@101 | 37 c.iterations, err = scheme.calculateIterations() |
| paddy@101 | 38 if err != nil { |
| paddy@101 | 39 return err |
| paddy@101 | 40 } |
| paddy@101 | 41 log.Printf("Generating passphrases with %d iterations...\n", c.iterations) |
| paddy@101 | 42 return nil |
| paddy@101 | 43 } |