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