generated from resonatecoop/id-server-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
handlers.go
97 lines (82 loc) · 2.46 KB
/
handlers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package oauth
import (
"errors"
"net/http"
"github.com/resonatecoop/id/util/response"
"github.com/resonatecoop/user-api/model"
)
var (
// ErrInvalidGrantType ...
ErrInvalidGrantType = errors.New("Invalid grant type")
// ErrInvalidClientIDOrSecret ...
ErrInvalidClientIDOrSecret = errors.New("Invalid client ID or secret")
)
// tokensHandler handles all OAuth 2.0 grant types
// (POST /v1/oauth/tokens)
func (s *Service) tokensHandler(w http.ResponseWriter, r *http.Request) {
// Parse the form so r.Form becomes available
if err := r.ParseForm(); err != nil {
response.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Map of grant types against handler functions
grantTypes := map[string]func(r *http.Request, client *model.Client) (*AccessTokenResponse, error){
"authorization_code": s.authorizationCodeGrant,
"password": s.passwordGrant,
"client_credentials": s.clientCredentialsGrant,
"refresh_token": s.refreshTokenGrant,
}
// Check the grant type
grantHandler, ok := grantTypes[r.Form.Get("grant_type")]
if !ok {
response.Error(w, ErrInvalidGrantType.Error(), http.StatusBadRequest)
return
}
// Client auth
client, err := s.basicAuthClient(r)
if err != nil {
response.UnauthorizedError(w, err.Error())
return
}
// Grant processing
resp, err := grantHandler(r, client)
if err != nil {
response.Error(w, err.Error(), getErrStatusCode(err))
return
}
// Write response to json
response.WriteJSON(w, resp, 200)
}
// introspectHandler handles OAuth 2.0 introspect request
// (POST /v1/oauth/introspect)
func (s *Service) introspectHandler(w http.ResponseWriter, r *http.Request) {
// Client auth
client, err := s.basicAuthClient(r)
if err != nil {
response.UnauthorizedError(w, err.Error())
return
}
// Introspect the token
resp, err := s.introspectToken(r, client)
if err != nil {
response.Error(w, err.Error(), getErrStatusCode(err))
return
}
// Write response to json
response.WriteJSON(w, resp, 200)
}
// Get client credentials from basic auth and try to authenticate client
func (s *Service) basicAuthClient(r *http.Request) (*model.Client, error) {
// Get client credentials from basic auth
clientID, secret, ok := r.BasicAuth()
if !ok {
return nil, ErrInvalidClientIDOrSecret
}
// Authenticate the client
client, err := s.AuthClient(clientID, secret)
if err != nil {
// For security reasons, return a general error message
return nil, ErrInvalidClientIDOrSecret
}
return client, nil
}