auth
2014-08-13
Parent:3423c552e249
auth/util.go
Add logging. Log errors when obtaining and saving access tokens.
| paddy@6 | 1 package auth |
| paddy@0 | 2 |
| paddy@0 | 3 import ( |
| paddy@0 | 4 "encoding/base64" |
| paddy@0 | 5 "errors" |
| paddy@1 | 6 "fmt" |
| paddy@0 | 7 "net/http" |
| paddy@1 | 8 "net/url" |
| paddy@0 | 9 "strings" |
| paddy@1 | 10 |
| paddy@1 | 11 "code.google.com/p/go-uuid/uuid" |
| paddy@0 | 12 ) |
| paddy@0 | 13 |
| paddy@0 | 14 var ( |
| paddy@0 | 15 BasicAuthNotSetError = errors.New("Authorization header not set.") |
| paddy@0 | 16 InvalidBasicAuthTypeError = errors.New("Invalid basic auth type.") |
| paddy@0 | 17 InvalidBasicAuthMessage = errors.New("Invalid basic auth format.") |
| paddy@0 | 18 ) |
| paddy@0 | 19 |
| paddy@0 | 20 // Parse basic authentication header |
| paddy@0 | 21 type BasicAuth struct { |
| paddy@0 | 22 Username string |
| paddy@0 | 23 Password string |
| paddy@0 | 24 } |
| paddy@0 | 25 |
| paddy@0 | 26 // Return authorization header data |
| paddy@0 | 27 func CheckBasicAuth(r *http.Request) (BasicAuth, error) { |
| paddy@0 | 28 if r.Header.Get("Authorization") == "" { |
| paddy@0 | 29 return BasicAuth{}, BasicAuthNotSetError |
| paddy@0 | 30 } |
| paddy@0 | 31 |
| paddy@0 | 32 s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) |
| paddy@0 | 33 if len(s) != 2 || s[0] != "Basic" { |
| paddy@0 | 34 return BasicAuth{}, InvalidBasicAuthTypeError |
| paddy@0 | 35 } |
| paddy@0 | 36 |
| paddy@0 | 37 b, err := base64.StdEncoding.DecodeString(s[1]) |
| paddy@0 | 38 if err != nil { |
| paddy@0 | 39 return BasicAuth{}, err |
| paddy@0 | 40 } |
| paddy@0 | 41 pair := strings.SplitN(string(b), ":", 2) |
| paddy@0 | 42 if len(pair) != 2 { |
| paddy@0 | 43 return BasicAuth{}, InvalidBasicAuthMessage |
| paddy@0 | 44 } |
| paddy@0 | 45 |
| paddy@0 | 46 return BasicAuth{Username: pair[0], Password: pair[1]}, nil |
| paddy@0 | 47 } |
| paddy@0 | 48 |
| paddy@0 | 49 // getClientAuth checks client basic authentication in params if allowed, |
| paddy@0 | 50 // otherwise gets it from the header. |
| paddy@0 | 51 func getClientAuth(r *http.Request, allowQueryParams bool) (BasicAuth, error) { |
| paddy@0 | 52 |
| paddy@0 | 53 if allowQueryParams { |
| paddy@0 | 54 // Allow for auth without password |
| paddy@0 | 55 if _, hasSecret := r.Form["client_secret"]; hasSecret { |
| paddy@0 | 56 auth := BasicAuth{ |
| paddy@0 | 57 Username: r.Form.Get("client_id"), |
| paddy@0 | 58 Password: r.Form.Get("client_secret"), |
| paddy@0 | 59 } |
| paddy@0 | 60 if auth.Username != "" { |
| paddy@0 | 61 return auth, nil |
| paddy@0 | 62 } |
| paddy@0 | 63 } |
| paddy@0 | 64 } |
| paddy@0 | 65 |
| paddy@0 | 66 return CheckBasicAuth(r) |
| paddy@0 | 67 } |
| paddy@1 | 68 |
| paddy@1 | 69 func newToken() string { |
| paddy@1 | 70 return base64.StdEncoding.EncodeToString([]byte(uuid.New())) |
| paddy@1 | 71 } |
| paddy@1 | 72 |
| paddy@1 | 73 // validateURI validates that redirectURI is contained in baseURI |
| paddy@1 | 74 func validateURI(baseURI string, redirectURI string) error { |
| paddy@1 | 75 if baseURI == "" || redirectURI == "" { |
| paddy@1 | 76 return errors.New("urls cannot be blank.") |
| paddy@1 | 77 } |
| paddy@1 | 78 |
| paddy@1 | 79 // parse base url |
| paddy@1 | 80 base, err := url.Parse(baseURI) |
| paddy@1 | 81 if err != nil { |
| paddy@1 | 82 return err |
| paddy@1 | 83 } |
| paddy@1 | 84 |
| paddy@1 | 85 // parse passed url |
| paddy@1 | 86 redirect, err := url.Parse(redirectURI) |
| paddy@1 | 87 if err != nil { |
| paddy@1 | 88 return err |
| paddy@1 | 89 } |
| paddy@1 | 90 |
| paddy@1 | 91 // must not have fragment |
| paddy@1 | 92 if base.Fragment != "" || redirect.Fragment != "" { |
| paddy@1 | 93 return errors.New("url must not include fragment.") |
| paddy@1 | 94 } |
| paddy@1 | 95 |
| paddy@1 | 96 // check if urls match |
| paddy@1 | 97 if base.Scheme == redirect.Scheme && base.Host == redirect.Host && len(redirect.Path) >= len(base.Path) && strings.HasPrefix(redirect.Path, base.Path) { |
| paddy@1 | 98 return nil |
| paddy@1 | 99 } |
| paddy@1 | 100 |
| paddy@1 | 101 return errors.New(fmt.Sprintf("urls don't validate: %s / %s\n", baseURI, redirectURI)) |
| paddy@1 | 102 } |