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