auth
2015-12-14
Parent:8ecb60d29b0d
auth/request.go
Update nsq import path. go-nsq has moved to nsqio/go-nsq, so we need to update the import path appropriately.
| paddy@99 | 1 package auth |
| paddy@99 | 2 |
| paddy@104 | 3 import ( |
| paddy@104 | 4 "encoding/json" |
| paddy@104 | 5 "log" |
| paddy@104 | 6 "net/http" |
| paddy@104 | 7 |
| paddy@104 | 8 "bitbucket.org/ww/goautoneg" |
| paddy@104 | 9 ) |
| paddy@104 | 10 |
| paddy@99 | 11 const ( |
| paddy@172 | 12 RequestErrAccessDenied = "access_denied" |
| paddy@172 | 13 RequestErrInsufficient = "insufficient" |
| paddy@172 | 14 RequestErrOverflow = "overflow" |
| paddy@172 | 15 RequestErrInvalidValue = "invalid_value" |
| paddy@172 | 16 RequestErrInvalidFormat = "invalid_format" |
| paddy@172 | 17 RequestErrMissing = "missing" |
| paddy@172 | 18 RequestErrNotFound = "not_found" |
| paddy@172 | 19 RequestErrConflict = "conflict" |
| paddy@172 | 20 RequestErrActOfGod = "act_of_god" |
| paddy@99 | 21 ) |
| paddy@99 | 22 |
| paddy@104 | 23 var ( |
| paddy@172 | 24 actOfGodResponse = Response{Errors: []RequestError{RequestError{Slug: RequestErrActOfGod}}} |
| paddy@172 | 25 invalidFormatResponse = Response{Errors: []RequestError{RequestError{Slug: RequestErrInvalidFormat, Field: "/"}}} |
| paddy@104 | 26 |
| paddy@104 | 27 encoders = []string{"application/json"} |
| paddy@104 | 28 ) |
| paddy@104 | 29 |
| paddy@172 | 30 type Response struct { |
| paddy@172 | 31 Errors []RequestError `json:"errors,omitempty"` |
| paddy@108 | 32 Logins []Login `json:"logins,omitempty"` |
| paddy@108 | 33 Profiles []Profile `json:"profiles,omitempty"` |
| paddy@108 | 34 Clients []Client `json:"clients,omitempty"` |
| paddy@108 | 35 Endpoints []Endpoint `json:"endpoints,omitempty"` |
| paddy@159 | 36 Sessions []Session `json:"sessions,omitempty"` |
| paddy@104 | 37 } |
| paddy@104 | 38 |
| paddy@172 | 39 type RequestError struct { |
| paddy@99 | 40 Slug string `json:"error,omitempty"` |
| paddy@99 | 41 Field string `json:"field,omitempty"` |
| paddy@99 | 42 Param string `json:"param,omitempty"` |
| paddy@99 | 43 Header string `json:"header,omitempty"` |
| paddy@99 | 44 } |
| paddy@104 | 45 |
| paddy@104 | 46 func negotiate(h http.Handler) http.Handler { |
| paddy@104 | 47 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| paddy@110 | 48 if r.Header.Get("Accept") != "" { |
| paddy@110 | 49 contentType := goautoneg.Negotiate(r.Header.Get("Accept"), encoders) |
| paddy@110 | 50 if contentType == "" { |
| paddy@110 | 51 w.WriteHeader(http.StatusNotAcceptable) |
| paddy@110 | 52 w.Write([]byte("Unsupported content type requested: " + r.Header.Get("Accept"))) |
| paddy@110 | 53 return |
| paddy@110 | 54 } |
| paddy@104 | 55 } |
| paddy@104 | 56 h.ServeHTTP(w, r) |
| paddy@104 | 57 }) |
| paddy@104 | 58 } |
| paddy@104 | 59 |
| paddy@172 | 60 func encode(w http.ResponseWriter, r *http.Request, status int, resp Response) { |
| paddy@104 | 61 contentType := goautoneg.Negotiate(r.Header.Get("Accept"), encoders) |
| paddy@104 | 62 w.Header().Set("content-type", contentType) |
| paddy@104 | 63 w.WriteHeader(status) |
| paddy@104 | 64 var err error |
| paddy@104 | 65 switch contentType { |
| paddy@104 | 66 case "application/json": |
| paddy@104 | 67 enc := json.NewEncoder(w) |
| paddy@104 | 68 err = enc.Encode(resp) |
| paddy@110 | 69 default: |
| paddy@110 | 70 enc := json.NewEncoder(w) |
| paddy@110 | 71 err = enc.Encode(resp) |
| paddy@104 | 72 } |
| paddy@104 | 73 if err != nil { |
| paddy@104 | 74 log.Println(err) |
| paddy@104 | 75 } |
| paddy@104 | 76 } |
| paddy@104 | 77 |
| paddy@133 | 78 func decode(r *http.Request, target interface{}) error { |
| paddy@133 | 79 defer r.Body.Close() |
| paddy@133 | 80 switch r.Header.Get("Content-Type") { |
| paddy@133 | 81 case "application/json": |
| paddy@133 | 82 dec := json.NewDecoder(r.Body) |
| paddy@133 | 83 return dec.Decode(target) |
| paddy@133 | 84 default: |
| paddy@133 | 85 dec := json.NewDecoder(r.Body) |
| paddy@133 | 86 return dec.Decode(target) |
| paddy@133 | 87 } |
| paddy@133 | 88 } |
| paddy@133 | 89 |
| paddy@104 | 90 func wrap(context Context, f func(w http.ResponseWriter, r *http.Request, context Context)) http.Handler { |
| paddy@104 | 91 return negotiate(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| paddy@165 | 92 w.Header().Set("Access-Control-Allow-Origin", "*") |
| paddy@165 | 93 w.Header().Set("Access-Control-Allow-Headers", r.Header.Get("Access-Control-Request-Headers")) |
| paddy@165 | 94 w.Header().Set("Access-Control-Allow-Credentials", "true") |
| paddy@165 | 95 if r.Method == "OPTIONS" { |
| paddy@165 | 96 w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS") |
| paddy@165 | 97 w.Header().Set("Allow", "GET, POST, PUT, DELETE, PATCH, OPTIONS") |
| paddy@165 | 98 w.WriteHeader(http.StatusOK) |
| paddy@165 | 99 return |
| paddy@165 | 100 } |
| paddy@104 | 101 f(w, r, context) |
| paddy@104 | 102 })) |
| paddy@104 | 103 } |