auth
auth/request.go
Add support for registering Clients. Add an API endpoint to register Clients, which was the last step necessary before the OAuth2 integration could be tried out.
| 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@99 | 12 requestErrAccessDenied = "access_denied" |
| paddy@99 | 13 requestErrInsufficient = "insufficient" |
| paddy@99 | 14 requestErrOverflow = "overflow" |
| paddy@99 | 15 requestErrInvalidValue = "invalid_value" |
| paddy@99 | 16 requestErrInvalidFormat = "invalid_format" |
| paddy@99 | 17 requestErrMissing = "missing" |
| paddy@99 | 18 requestErrNotFound = "not_found" |
| paddy@104 | 19 requestErrConflict = "conflict" |
| paddy@99 | 20 requestErrActOfGod = "act_of_god" |
| paddy@99 | 21 ) |
| paddy@99 | 22 |
| paddy@104 | 23 var ( |
| paddy@104 | 24 actOfGodResponse = response{Errors: []requestError{requestError{Slug: requestErrActOfGod}}} |
| paddy@104 | 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@104 | 30 type response struct { |
| paddy@108 | 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@104 | 36 } |
| paddy@104 | 37 |
| paddy@99 | 38 type requestError struct { |
| paddy@99 | 39 Slug string `json:"error,omitempty"` |
| paddy@99 | 40 Field string `json:"field,omitempty"` |
| paddy@99 | 41 Param string `json:"param,omitempty"` |
| paddy@99 | 42 Header string `json:"header,omitempty"` |
| paddy@99 | 43 } |
| paddy@104 | 44 |
| paddy@104 | 45 func negotiate(h http.Handler) http.Handler { |
| paddy@104 | 46 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| paddy@104 | 47 contentType := goautoneg.Negotiate(r.Header.Get("Accept"), encoders) |
| paddy@104 | 48 if contentType == "" { |
| paddy@104 | 49 w.WriteHeader(http.StatusNotAcceptable) |
| paddy@104 | 50 log.Println("Unsupported Accept header:", r.Header.Get("Accept")) |
| paddy@104 | 51 w.Write([]byte("Unsupported content type requested: " + r.Header.Get("Accept"))) |
| paddy@104 | 52 return |
| paddy@104 | 53 } |
| paddy@104 | 54 h.ServeHTTP(w, r) |
| paddy@104 | 55 }) |
| paddy@104 | 56 } |
| paddy@104 | 57 |
| paddy@104 | 58 func encode(w http.ResponseWriter, r *http.Request, status int, resp response) { |
| paddy@104 | 59 contentType := goautoneg.Negotiate(r.Header.Get("Accept"), encoders) |
| paddy@104 | 60 w.Header().Set("content-type", contentType) |
| paddy@104 | 61 w.WriteHeader(status) |
| paddy@104 | 62 var err error |
| paddy@104 | 63 switch contentType { |
| paddy@104 | 64 case "application/json": |
| paddy@104 | 65 enc := json.NewEncoder(w) |
| paddy@104 | 66 err = enc.Encode(resp) |
| paddy@104 | 67 } |
| paddy@104 | 68 if err != nil { |
| paddy@104 | 69 log.Println(err) |
| paddy@104 | 70 } |
| paddy@104 | 71 } |
| paddy@104 | 72 |
| paddy@104 | 73 func wrap(context Context, f func(w http.ResponseWriter, r *http.Request, context Context)) http.Handler { |
| paddy@104 | 74 return negotiate(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| paddy@104 | 75 f(w, r, context) |
| paddy@104 | 76 })) |
| paddy@104 | 77 } |