auth

Paddy 2014-08-13 Parent:3423c552e249

12:63e86d129238 Go to Latest

auth/util.go

Consistently handle context in client storage interface. Let's at least be consistent about passing or not passing context to the client storage interface. Most our methods don't take the context, so let's just remove it.

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