forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
osinserver.go
129 lines (106 loc) · 3.35 KB
/
osinserver.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package osinserver
import (
"fmt"
"net/http"
"path"
"github.com/RangelReale/osin"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
)
const (
AuthorizePath = "/authorize"
TokenPath = "/token"
InfoPath = "/info"
)
type Server struct {
config *osin.ServerConfig
server *osin.Server
authorize AuthorizeHandler
access AccessHandler
errorHandler ErrorHandler
}
func New(config *osin.ServerConfig, storage osin.Storage, authorize AuthorizeHandler, access AccessHandler, errorHandler ErrorHandler) *Server {
server := osin.NewServer(config, storage)
// Override tokengen to ensure we get valid length tokens
server.AuthorizeTokenGen = TokenGen{}
server.AccessTokenGen = TokenGen{}
return &Server{
config: config,
server: server,
authorize: authorize,
access: access,
errorHandler: errorHandler,
}
}
// Install registers the Server OAuth handlers into a mux. It is expected that the
// provided prefix will serve all operations
func (s *Server) Install(mux Mux, paths ...string) {
for _, prefix := range paths {
mux.HandleFunc(path.Join(prefix, AuthorizePath), s.handleAuthorize)
mux.HandleFunc(path.Join(prefix, TokenPath), s.handleToken)
mux.HandleFunc(path.Join(prefix, InfoPath), s.handleInfo)
}
}
// AuthorizationHandler returns an http.Handler capable of authorizing.
// Used for implicit authorization special flows.
func (s *Server) AuthorizationHandler() http.Handler {
return http.HandlerFunc(s.handleAuthorize)
}
// TokenHandler returns an http.Handler capable of granting tokens. Used for
// implicit token granting special flows.
func (s *Server) TokenHandler() http.Handler {
return http.HandlerFunc(s.handleToken)
}
func (s *Server) handleAuthorize(w http.ResponseWriter, r *http.Request) {
resp := s.server.NewResponse()
defer resp.Close()
if ar := s.server.HandleAuthorizeRequest(resp, r); ar != nil {
if errorCode := r.FormValue("error"); len(errorCode) != 0 {
// The request already has an error parameter, return directly to the user
resp.SetErrorUri(
r.FormValue("error"),
r.FormValue("error_description"),
r.FormValue("error_uri"),
r.FormValue("state"),
)
// force redirect response
resp.SetRedirect(ar.RedirectUri)
} else {
handled, err := s.authorize.HandleAuthorize(ar, resp, w)
if err != nil {
s.errorHandler.HandleError(err, w, r)
return
}
if handled {
return
}
s.server.FinishAuthorizeRequest(resp, r, ar)
}
}
if resp.IsError && resp.InternalError != nil {
utilruntime.HandleError(fmt.Errorf("internal error: %s", resp.InternalError))
}
osin.OutputJSON(resp, w, r)
}
func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) {
resp := s.server.NewResponse()
defer resp.Close()
if ar := s.server.HandleAccessRequest(resp, r); ar != nil {
if err := s.access.HandleAccess(ar, w); err != nil {
s.errorHandler.HandleError(err, w, r)
return
}
s.server.FinishAccessRequest(resp, r, ar)
}
if resp.IsError && resp.InternalError != nil {
utilruntime.HandleError(fmt.Errorf("internal error: %s", resp.InternalError))
}
osin.OutputJSON(resp, w, r)
}
func (s *Server) handleInfo(w http.ResponseWriter, r *http.Request) {
resp := s.server.NewResponse()
defer resp.Close()
if ir := s.server.HandleInfoRequest(resp, r); ir != nil {
s.server.FinishInfoRequest(resp, r, ir)
}
osin.OutputJSON(resp, w, r)
}