auth
108:2e4b5722eed0 Browse Files
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.
authd/server.go authd/templates/simple.gotmpl client.go request.go
1.1 --- a/authd/server.go Wed Dec 17 22:27:44 2014 -0500 1.2 +++ b/authd/server.go Sun Jan 04 00:07:27 2015 -0500 1.3 @@ -33,6 +33,7 @@ 1.4 auth.RegisterOAuth2(router, context) 1.5 auth.RegisterSessionHandlers(router, context) 1.6 auth.RegisterProfileHandlers(router, context) 1.7 + auth.RegisterClientHandlers(router, context) 1.8 http.Handle("/", router) 1.9 log.Fatal(http.ListenAndServe(":8080", nil)) 1.10 }
2.1 --- a/authd/templates/simple.gotmpl Wed Dec 17 22:27:44 2014 -0500 2.2 +++ b/authd/templates/simple.gotmpl Sun Jan 04 00:07:27 2015 -0500 2.3 @@ -25,6 +25,9 @@ 2.4 <p>{{ .error }}</p>{{ end }}{{ if .internal_error }} 2.5 <h1>Error</h1> 2.6 <p>{{ .internal_error }}</p>{{ end }}{{ if not .error }}{{ if not .internal_error }}<h1>Grant access</h1> 2.7 - <p>{{ .client }} is requesting access to your account. if you grant it, you'll be redirected to {{ .redirectURL }}. Their access will be limited to {{ .scope }}. You are granting access for {{ .profile }}.</p>{{ end }}{{ end }} 2.8 + <p>{{ .client.Name }} is requesting access to your account. if you grant it, you'll be redirected to {{ .redirectURL }}. Their access will be limited to {{ .scope }}. You are granting access for {{ .profile.Name }}.</p>{{ end }}{{ end }} 2.9 + <form method="POST"> 2.10 + <input type="submit" name="grant" value="approved"> 2.11 + </form> 2.12 </body> 2.13 </html>{{ end }}
3.1 --- a/client.go Wed Dec 17 22:27:44 2014 -0500 3.2 +++ b/client.go Sun Jan 04 00:07:27 2015 -0500 3.3 @@ -1,8 +1,11 @@ 3.4 package auth 3.5 3.6 import ( 3.7 + "crypto/rand" 3.8 + "encoding/hex" 3.9 "encoding/json" 3.10 "errors" 3.11 + "github.com/gorilla/mux" 3.12 "net/http" 3.13 "net/url" 3.14 "time" 3.15 @@ -313,3 +316,80 @@ 3.16 defer m.endpointLock.RUnlock() 3.17 return int64(len(m.endpoints[client.String()])), nil 3.18 } 3.19 + 3.20 +type newClientReq struct { 3.21 + Name string `json:"name"` 3.22 + Logo string `json:"logo"` 3.23 + Website string `json:"website"` 3.24 + Type string `json:"type"` 3.25 + Endpoints []string `json:"endpoints"` 3.26 +} 3.27 + 3.28 +func RegisterClientHandlers(r *mux.Router, context Context) { 3.29 + r.Handle("/clients", wrap(context, CreateClientHandler)).Methods("POST") 3.30 +} 3.31 + 3.32 +func CreateClientHandler(w http.ResponseWriter, r *http.Request, c Context) { 3.33 + username, password, ok := r.BasicAuth() 3.34 + if !ok { 3.35 + // TODO(paddy): return error 3.36 + return 3.37 + } 3.38 + profile, err := authenticate(username, password, c) 3.39 + if err != nil { 3.40 + // TODO(paddy): return error 3.41 + return 3.42 + } 3.43 + var req newClientReq 3.44 + decoder := json.NewDecoder(r.Body) 3.45 + err = decoder.Decode(&req) 3.46 + if err != nil { 3.47 + encode(w, r, http.StatusBadRequest, invalidFormatResponse) 3.48 + return 3.49 + } 3.50 + secret := make([]byte, 32) 3.51 + _, err = rand.Read(secret) 3.52 + if err != nil { 3.53 + // TODO(paddy): return error 3.54 + return 3.55 + } 3.56 + client := Client{ 3.57 + ID: uuid.NewID(), 3.58 + Secret: hex.EncodeToString(secret), 3.59 + OwnerID: profile.ID, 3.60 + Name: req.Name, 3.61 + Logo: req.Logo, 3.62 + Website: req.Website, 3.63 + Type: req.Type, 3.64 + } 3.65 + err = c.SaveClient(client) 3.66 + if err != nil { 3.67 + // TODO(paddy): return error 3.68 + return 3.69 + } 3.70 + endpoints := []Endpoint{} 3.71 + for _, u := range req.Endpoints { 3.72 + uri, err := url.Parse(u) 3.73 + if err != nil { 3.74 + // TODO(paddy): add error to response 3.75 + continue 3.76 + } 3.77 + endpoint := Endpoint{ 3.78 + ID: uuid.NewID(), 3.79 + ClientID: client.ID, 3.80 + URI: *uri, 3.81 + Added: time.Now(), 3.82 + } 3.83 + err = c.AddEndpoint(client.ID, endpoint) 3.84 + if err != nil { 3.85 + // TODO(paddy): return error 3.86 + return 3.87 + } 3.88 + endpoints = append(endpoints, endpoint) 3.89 + } 3.90 + resp := response{ 3.91 + Clients: []Client{client}, 3.92 + Endpoints: endpoints, 3.93 + } 3.94 + encode(w, r, http.StatusCreated, resp) 3.95 +}
4.1 --- a/request.go Wed Dec 17 22:27:44 2014 -0500 4.2 +++ b/request.go Sun Jan 04 00:07:27 2015 -0500 4.3 @@ -28,9 +28,11 @@ 4.4 ) 4.5 4.6 type response struct { 4.7 - Errors []requestError `json:"errors,omitempty"` 4.8 - Logins []Login `json:"logins,omitempty"` 4.9 - Profiles []Profile `json:"profiles,omitempty"` 4.10 + Errors []requestError `json:"errors,omitempty"` 4.11 + Logins []Login `json:"logins,omitempty"` 4.12 + Profiles []Profile `json:"profiles,omitempty"` 4.13 + Clients []Client `json:"clients,omitempty"` 4.14 + Endpoints []Endpoint `json:"endpoints,omitempty"` 4.15 } 4.16 4.17 type requestError struct {