auth

Paddy 2014-10-26 Parent:b3cd7765a7c8 Child:0cc717e02c9b

59:03c9890f99c5 Go to Latest

auth/http.go

Catch ErrClientNotFound. It's not a 500 error if the user specifies a Client that doesn't exist in the clientStore. That's a 400, with an error that should be rendered for the user.

History
paddy@51 1 package auth
paddy@51 2
paddy@51 3 import (
paddy@51 4 "net/http"
paddy@56 5
paddy@56 6 "code.secondbit.org/uuid"
paddy@51 7 )
paddy@51 8
paddy@51 9 const getGrantTemplateName = "get_grant"
paddy@51 10
paddy@57 11 // GetGrantHandler presents and processes the page for asking a user to grant access
paddy@57 12 // to their data. See RFC 6749, Section 4.1.
paddy@51 13 func GetGrantHandler(w http.ResponseWriter, r *http.Request, context Context) {
paddy@56 14 if r.URL.Query().Get("client_id") == "" {
paddy@56 15 w.WriteHeader(http.StatusBadRequest)
paddy@56 16 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 17 "error": "Client ID must be specified in the request.",
paddy@56 18 })
paddy@56 19 return
paddy@56 20 }
paddy@56 21 clientID, err := uuid.Parse(r.URL.Query().Get("client_id"))
paddy@56 22 if err != nil {
paddy@56 23 w.WriteHeader(http.StatusBadRequest)
paddy@56 24 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 25 "error": "client_id is not a valid Client ID.",
paddy@56 26 })
paddy@56 27 return
paddy@56 28 }
paddy@56 29 client, err := context.GetClient(clientID)
paddy@56 30 if err != nil {
paddy@59 31 if err == ErrClientNotFound {
paddy@59 32 w.WriteHeader(http.StatusBadRequest)
paddy@59 33 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@59 34 "error": "The Client specified couldn't be found.",
paddy@59 35 })
paddy@59 36 } else {
paddy@59 37 w.WriteHeader(http.StatusInternalServerError)
paddy@59 38 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@59 39 "internal_error": err,
paddy@59 40 })
paddy@59 41 }
paddy@56 42 return
paddy@56 43 }
paddy@56 44 // whether a redirect URI is valid or not depends on the number of endpoints
paddy@56 45 // the client has registered
paddy@56 46 numEndpoints, err := context.CountEndpoints(clientID)
paddy@56 47 if err != nil {
paddy@56 48 w.WriteHeader(http.StatusInternalServerError)
paddy@56 49 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 50 "internal_error": err,
paddy@56 51 })
paddy@56 52 return
paddy@56 53 }
paddy@56 54 redirectURI := r.URL.Query().Get("redirect_uri")
paddy@56 55 var validURI bool
paddy@58 56 if redirectURI != "" {
paddy@58 57 // BUG(paddy): We really should normalize URIs before trying to compare them.
paddy@58 58 validURI, err = context.CheckEndpoint(clientID, redirectURI)
paddy@56 59 if err != nil {
paddy@56 60 w.WriteHeader(http.StatusInternalServerError)
paddy@56 61 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 62 "internal_error": err,
paddy@56 63 })
paddy@56 64 return
paddy@56 65 }
paddy@56 66 } else if redirectURI == "" && numEndpoints == 1 {
paddy@56 67 // if we don't specify the endpoint and there's only one endpoint, the
paddy@56 68 // request is valid, and we're redirecting to that one endpoint
paddy@56 69 validURI = true
paddy@56 70 endpoints, err := context.ListEndpoints(clientID, 1, 0)
paddy@56 71 if err != nil {
paddy@56 72 w.WriteHeader(http.StatusInternalServerError)
paddy@56 73 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 74 "internal_error": err,
paddy@56 75 })
paddy@56 76 return
paddy@56 77 }
paddy@56 78 if len(endpoints) != 1 {
paddy@56 79 validURI = false
paddy@56 80 } else {
paddy@56 81 redirectURI = endpoints[0].URI.String()
paddy@56 82 }
paddy@56 83 } else {
paddy@56 84 validURI = false
paddy@56 85 }
paddy@56 86 if !validURI {
paddy@56 87 w.WriteHeader(http.StatusBadRequest)
paddy@56 88 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 89 "error": "The redirect_uri specified is not valid.",
paddy@56 90 })
paddy@56 91 return
paddy@56 92 }
paddy@56 93 if r.URL.Query().Get("response_type") != "code" {
paddy@56 94 // TODO: redirect error
paddy@56 95 }
paddy@56 96 //scope := r.URL.Query().Get("scope")
paddy@56 97 //state := r.URL.Query().Get("state")
paddy@56 98 if r.Method == "POST" {
paddy@56 99 // TODO: CSRF protection
paddy@56 100 if r.PostFormValue("grant") == "approved" {
paddy@56 101 // TODO: redirect
paddy@56 102 } else {
paddy@56 103 // TODO: redirect error
paddy@56 104 }
paddy@56 105 }
paddy@51 106 w.WriteHeader(http.StatusOK)
paddy@56 107 context.Render(w, getGrantTemplateName, map[string]interface{}{
paddy@56 108 "client": client,
paddy@56 109 })
paddy@51 110 }