-
Notifications
You must be signed in to change notification settings - Fork 0
/
mytoken.go
225 lines (207 loc) · 8.36 KB
/
mytoken.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
package mytokenlib
import (
"github.com/oidc-mytoken/api/v0"
)
// MytokenEndpoint is type representing a mytoken server's Mytoken Endpoint and the actions that can be
// performed there.
type MytokenEndpoint struct {
endpoint string
}
func newMytokenEndpoint(endpoint string) *MytokenEndpoint {
return &MytokenEndpoint{
endpoint: endpoint,
}
}
// DoHTTPRequest performs an http request to the mytoken endpoint
func (my MytokenEndpoint) DoHTTPRequest(method string, req, resp interface{}) error {
return doHTTPRequest(method, my.endpoint, req, resp)
}
// APIFromRequest sends the passed request marshalled as json to the servers mytoken endpoint to obtain a mytoken and
// returns the api.MytokenResponse.
func (my MytokenEndpoint) APIFromRequest(request interface{}) (resp api.MytokenResponse, err error) {
err = my.DoHTTPRequest("POST", request, &resp)
return
}
// FromRequest sends the passed request marshalled as json to the servers mytoken endpoint to obtain a mytoken and
// returns the obtained mytoken and if a mytoken was used for authorization and it was rotated the updated mytoken.
func (my MytokenEndpoint) FromRequest(request interface{}) (string, *string, error) {
resp, err := my.APIFromRequest(request)
if err != nil {
return "", nil, err
}
var updatedMT *string
if resp.TokenUpdate != nil {
updatedMT = &resp.TokenUpdate.Mytoken
}
return resp.Mytoken, updatedMT, nil
}
// APIFromMytoken obtains a sub-mytoken by using an existing mytoken according to the passed parameters.
// If the used mytoken changes (due to token rotation), the new mytoken is included in the api.MytokenResponse
func (my MytokenEndpoint) APIFromMytoken(
mytoken string, issuer string, restrictions api.Restrictions, capabilities api.Capabilities, rotation *api.Rotation,
responseType, name string,
) (api.MytokenResponse, error) {
req := api.MytokenFromMytokenRequest{
GeneralMytokenRequest: api.GeneralMytokenRequest{
Issuer: issuer,
GrantType: api.GrantTypeMytoken,
Restrictions: restrictions,
Capabilities: capabilities,
Rotation: rotation,
Name: name,
ResponseType: responseType,
},
Mytoken: mytoken,
}
return my.APIFromRequest(req)
}
// FromMytoken obtains a sub-mytoken by using an existing mytoken according to the passed parameters.
// If the used mytoken changes (due to token rotation), the passed variable is updated accordingly.
func (my MytokenEndpoint) FromMytoken(
mytoken *string, issuer string, restrictions api.Restrictions, capabilities api.Capabilities,
rotation *api.Rotation, responseType, name string,
) (string, error) {
resp, err := my.APIFromMytoken(*mytoken, issuer, restrictions, capabilities, rotation, responseType, name)
if err != nil {
return "", err
}
if resp.TokenUpdate != nil {
*mytoken = resp.TokenUpdate.Mytoken
}
return resp.Mytoken, nil
}
// APIFromTransferCode exchanges the transferCode into the linked mytoken
func (my MytokenEndpoint) APIFromTransferCode(transferCode string) (api.MytokenResponse, error) {
req := api.ExchangeTransferCodeRequest{
GrantType: api.GrantTypeTransferCode,
TransferCode: transferCode,
}
return my.APIFromRequest(req)
}
// FromTransferCode exchanges the transferCode into the linked mytoken
func (my MytokenEndpoint) FromTransferCode(transferCode string) (string, error) {
resp, err := my.APIFromTransferCode(transferCode)
return resp.Mytoken, err
}
// APIFromAuthorizationFlow is a rather high level function that obtains a new mytoken using the authorization
// code flow. This function starts the flow with the passed parameters and performs the polling for the mytoken.
// The passed PollingCallbacks are called throughout the flow.
func (my MytokenEndpoint) APIFromAuthorizationFlow(
issuer string, restrictions api.Restrictions, capabilities api.Capabilities,
rotation *api.Rotation, responseType, name, applicationName string, callbacks PollingCallbacks,
) (api.MytokenResponse, error) {
return my.APIFromAuthorizationFlowReq(
api.GeneralMytokenRequest{
Issuer: issuer,
Restrictions: restrictions,
Capabilities: capabilities,
Name: name,
ResponseType: responseType,
Rotation: rotation,
ApplicationName: applicationName,
}, callbacks,
)
}
// APIFromAuthorizationFlowReq is a rather high level function that obtains a new mytoken using the authorization
// code flow. This function starts the flow with the passed request and performs the polling for the mytoken.
// The passed PollingCallbacks are called throughout the flow.
func (my MytokenEndpoint) APIFromAuthorizationFlowReq(
req api.GeneralMytokenRequest, callbacks PollingCallbacks,
) (api.MytokenResponse, error) {
authRes, err := my.APIInitAuthorizationFlow(req)
if err != nil {
return api.MytokenResponse{}, err
}
if err = callbacks.Init(authRes.ConsentURI); err != nil {
return api.MytokenResponse{}, err
}
resp, err := my.APIPoll(authRes.PollingInfo, callbacks.Callback)
if err != nil {
return api.MytokenResponse{}, err
}
callbacks.End()
return *resp, nil
}
// FromAuthorizationFlow is a rather high level function that obtains a new mytoken using the authorization
// code flow. This function starts the flow with the passed parameters and performs the polling for the mytoken.
// The passed PollingCallbacks are called throughout the flow.
func (my MytokenEndpoint) FromAuthorizationFlow(
issuer string, restrictions api.Restrictions, capabilities api.Capabilities,
rotation *api.Rotation, responseType, name, applicationName string, callbacks PollingCallbacks,
) (string, error) {
resp, err := my.APIFromAuthorizationFlow(
issuer, restrictions, capabilities, rotation, responseType, name, applicationName, callbacks,
)
return resp.Mytoken, err
}
// APIInitAuthorizationFlow starts the authorization code flow to obtain a mytoken with the passed parameters; it
// returns the api.AuthCodeFlowResponse
func (my MytokenEndpoint) APIInitAuthorizationFlow(req api.GeneralMytokenRequest) (
resp api.AuthCodeFlowResponse, err error,
) {
req.GrantType = api.GrantTypeOIDCFlow
flowReq := api.AuthCodeFlowRequest{
OIDCFlowRequest: api.OIDCFlowRequest{
GeneralMytokenRequest: req,
OIDCFlow: api.OIDCFlowAuthorizationCode,
},
ClientType: api.ClientTypeNative,
}
err = my.DoHTTPRequest("POST", flowReq, &resp)
return
}
// APIPoll performs the polling for the final mytoken in the authorization code flow using the passed
// api.PollingInfo.
// The callback function takes the polling interval and the number of iteration as parameters; it is called for each
// polling attempt where the final mytoken could not yet be obtained (but no error occurred); it is usually used to
// print progress output.
// At the end the api.MytokenResponse is returned.
func (my MytokenEndpoint) APIPoll(res api.PollingInfo, callback func(int64, int)) (*api.MytokenResponse, error) {
var resp api.MytokenResponse
set, err := poll(res, callback, my, &resp)
if err != nil {
return nil, err
}
if !set {
return nil, nil
}
return &resp, nil
}
// Poll performs the polling for the final mytoken in the authorization code flow using the passed
// api.PollingInfo.
// The callback function takes the polling interval and the number of iteration as parameters; it is called for each
// polling attempt where the final mytoken could not yet be obtained (but no error occurred); it is usually used to
// print progress output.
// At the end the mytoken is returned.
func (my MytokenEndpoint) Poll(res api.PollingInfo, callback func(int64, int)) (string, error) {
resp, err := my.APIPoll(res, callback)
if err != nil {
return "", err
}
return resp.Mytoken, nil
}
// APIPollOnce sends a single polling request with the passed pollingCode; it returns the api.
// MytokenResponse if obtained, or an error if an error occurred.
func (my MytokenEndpoint) APIPollOnce(pollingCode string) (*api.MytokenResponse, error) {
var resp api.MytokenResponse
set, err := pollOnce(pollingCode, my, &resp)
if err != nil {
return nil, err
}
if !set {
return nil, nil
}
return &resp, nil
}
// PollOnce sends a single polling request with the passed pollingCode; it returns the mytoken if obtained,
// a bool indicating if the mytoken was obtained, or an error if an error occurred.
func (my MytokenEndpoint) PollOnce(pollingCode string) (string, bool, error) {
resp, err := my.APIPollOnce(pollingCode)
if err != nil {
return "", false, err
}
if resp == nil {
return "", false, nil
}
return resp.Mytoken, true, nil
}