forked from TykTechnologies/tyk-identity-broker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_handlers.go
152 lines (125 loc) · 4.21 KB
/
http_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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"encoding/json"
"errors"
"fmt"
"github.com/gorilla/mux"
"github.com/lonelycode/tyk-auth-proxy/providers"
"github.com/lonelycode/tyk-auth-proxy/tap"
"github.com/lonelycode/tyk-auth-proxy/tap/identity-handlers"
"net/http"
)
// APIErrorMessage is an object that defines when a generic error occurred
type APIErrorMessage struct {
Status string
Error string
}
// HandlerLogTag is a tag we are uing to identify log messages from the handler
var HandlerLogTag = "[AUTH HANDLERS]"
// Returns a profile ID
func getId(req *http.Request) (string, error) {
id := mux.Vars(req)["id"]
if id == "" {
id = mux.Vars(req)[":id"]
}
if id == "" {
return id, errors.New("No profile id detected")
}
return id, nil
}
// Maps an identity handler from an Action type, register new Identity Handlers and methods here
func getIdentityHandler(name tap.Action) tap.IdentityHandler {
var thisIdentityHandler tap.IdentityHandler
switch name {
case tap.GenerateOrLoginDeveloperProfile:
thisIdentityHandler = &identityHandlers.TykIdentityHandler{
API: &TykAPIHandler,
Store: IdentityKeyStore}
case tap.GenerateOrLoginUserProfile:
thisIdentityHandler = &identityHandlers.TykIdentityHandler{
API: &TykAPIHandler,
Store: IdentityKeyStore}
case tap.GenerateOAuthTokenForClient:
thisIdentityHandler = &identityHandlers.TykIdentityHandler{
API: &TykAPIHandler,
Store: IdentityKeyStore}
case tap.GenerateTemporaryAuthToken:
thisIdentityHandler = &identityHandlers.TykIdentityHandler{
API: &TykAPIHandler,
Store: IdentityKeyStore}
}
return thisIdentityHandler
}
// A hack to marshal a provider conf from map[string]interface{} intoa type without type checking, ugly, but effective
func hackProviderConf(conf interface{}) []byte {
thisConf, err := json.Marshal(conf)
if err != nil {
log.Warning("Failure in JSON conversion")
return []byte{}
}
return thisConf
}
// return a provider based on the name of the provider type, add new providers here
func getTAProvider(conf tap.Profile) tap.TAProvider {
var thisProvider tap.TAProvider
switch conf.ProviderName {
case "SocialProvider":
thisProvider = &providers.Social{}
case "ADProvider":
thisProvider = &providers.ADProvider{}
case "ProxyProvider":
thisProvider = &providers.ProxyProvider{}
}
var thisIdentityHandler tap.IdentityHandler = getIdentityHandler(conf.ActionType)
thisIdentityHandler.Init(conf)
thisProvider.Init(thisIdentityHandler, conf, hackProviderConf(conf.ProviderConfig))
return thisProvider
}
// HandleError is a generic error handler
func HandleError(tag string, errorMsg string, rawErr error, code int, w http.ResponseWriter, r *http.Request) {
log.Error(tag+" "+errorMsg+": ", rawErr)
errorObj := APIErrorMessage{"error", errorMsg}
responseMsg, err := json.Marshal(&errorObj)
if err != nil {
log.Error("[Error Handler] Couldn't marshal error stats: ", err)
fmt.Fprintf(w, "System Error")
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
fmt.Fprintf(w, string(responseMsg))
}
func getTapProfile(w http.ResponseWriter, r *http.Request) (tap.TAProvider, error) {
thisId, idErr := getId(r)
if idErr != nil {
HandleError(HandlerLogTag, "Could not retrieve ID", idErr, 400, w, r)
return nil, idErr
}
thisProfile := tap.Profile{}
log.Debug(HandlerLogTag+" --> Looking up profile ID:", thisId)
foundProfileErr := AuthConfigStore.GetKey(thisId, &thisProfile)
if foundProfileErr != nil {
HandleError(HandlerLogTag, "Profile not found", foundProfileErr, 404, w, r)
return nil, foundProfileErr
}
thisIdentityProvider := getTAProvider(thisProfile)
return thisIdentityProvider, nil
}
// HandleAuth is the main entrypoint handler for any profile (i.e. /auth/:profile-id/:provider)
func HandleAuth(w http.ResponseWriter, r *http.Request) {
thisIdentityProvider, err := getTapProfile(w, r)
if err != nil {
return
}
thisIdentityProvider.Handle(w, r)
return
}
// HandleAuthCallback Is a callback URL passed to OAuth providers such as Social, handles completing an auth request
func HandleAuthCallback(w http.ResponseWriter, r *http.Request) {
thisIdentityProvider, err := getTapProfile(w, r)
if err != nil {
return
}
thisIdentityProvider.HandleCallback(w, r, HandleError)
return
}