@@ -3,6 +3,7 @@ package manager
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "math"
6
7
"net"
7
8
"os"
8
9
"time"
@@ -13,6 +14,7 @@ import (
13
14
)
14
15
15
16
const (
17
+ DefaultRequestTimeout = 30 * time .Second
16
18
DefaultExpirationRefreshRatio = 0.7
17
19
DefaultRetryOptionsMaxAttempts = 3
18
20
DefaultRetryOptionsBackoffMultiplier = 2.0
@@ -85,91 +87,79 @@ func defaultTokenManagerOptionsOr(options TokenManagerOptions) TokenManagerOptio
85
87
if options .ExpirationRefreshRatio == 0 {
86
88
options .ExpirationRefreshRatio = DefaultExpirationRefreshRatio
87
89
}
90
+ if options .RequestTimeout == 0 {
91
+ options .RequestTimeout = DefaultRequestTimeout
92
+ }
88
93
return options
89
94
}
90
95
91
96
type defaultIdentityProviderResponseParser struct {}
92
97
93
98
// ParseResponse parses the response from the identity provider and extracts the token.
94
99
// It takes an IdentityProviderResponse as an argument and returns a Token and an error if any.
95
- // The IdentityProviderResponse contains the raw token and the expiration time.
100
+ // The raw token is extracted based on the IdentityProviderResponse Type and then
101
+ // is parsed as a JWT token to extract the claims.
96
102
func (* defaultIdentityProviderResponseParser ) ParseResponse (response shared.IdentityProviderResponse ) (* token.Token , error ) {
97
103
if response == nil {
98
104
return nil , fmt .Errorf ("identity provider response cannot be nil" )
99
105
}
100
106
101
107
var username , password , rawToken string
102
108
var expiresOn time.Time
103
- now := time .Now ().UTC ()
109
+ now := time .Now ().UTC (). Truncate ( time . Second ). Add ( time . Second )
104
110
105
111
switch response .Type () {
106
112
case shared .ResponseTypeAuthResult :
107
113
authResult , err := response .(shared.AuthResultIDPResponse ).AuthResult ()
108
114
if err != nil {
109
115
return nil , fmt .Errorf ("failed to get auth result: %w" , err )
110
116
}
111
- if authResult .ExpiresOn .IsZero () {
112
- return nil , fmt .Errorf ("auth result expiration time is not set" )
113
- }
114
- if authResult .IDToken .Oid == "" {
115
- return nil , fmt .Errorf ("auth result OID is empty" )
116
- }
117
- rawToken = authResult .IDToken .RawToken
118
- username = authResult .IDToken .Oid
119
- password = rawToken
120
- expiresOn = authResult .ExpiresOn .UTC ()
121
117
122
- case shared .ResponseTypeRawToken , shared .ResponseTypeAccessToken :
123
- var tokenStr string
124
- var err error
125
- if response .Type () == shared .ResponseTypeRawToken {
126
- tokenStr , err = response .(shared.RawTokenIDPResponse ).RawToken ()
127
- if err != nil {
128
- return nil , fmt .Errorf ("failed to get raw token: %w" , err )
129
- }
130
- }
131
- if response .Type () == shared .ResponseTypeAccessToken {
132
- accessToken , err := response .(shared.AccessTokenIDPResponse ).AccessToken ()
133
- if err != nil {
134
- return nil , fmt .Errorf ("failed to get access token: %w" , err )
135
- }
136
- if accessToken .Token == "" {
137
- return nil , fmt .Errorf ("access token value is empty" )
138
- }
139
- tokenStr = accessToken .Token
140
- expiresOn = accessToken .ExpiresOn .UTC ()
141
- }
142
-
143
- if tokenStr == "" {
144
- return nil , fmt .Errorf ("raw token is empty" )
118
+ expiresOn = authResult .ExpiresOn .UTC ()
119
+ rawToken = authResult .AccessToken
120
+ case shared .ResponseTypeAccessToken :
121
+ accessToken , err := response .(shared.AccessTokenIDPResponse ).AccessToken ()
122
+ if err != nil {
123
+ return nil , fmt .Errorf ("failed to get access token: %w" , err )
145
124
}
146
125
147
- claims := struct {
148
- jwt.RegisteredClaims
149
- Oid string `json:"oid,omitempty"`
150
- }{}
151
-
152
- // Parse the token to extract claims, but note that signature verification
153
- // should be handled by the identity provider
154
- _ , _ , err = jwt .NewParser ().ParseUnverified (tokenStr , & claims )
126
+ rawToken = accessToken .Token
127
+ expiresOn = accessToken .ExpiresOn .UTC ()
128
+ case shared .ResponseTypeRawToken :
129
+ tokenStr , err := response .(shared.RawTokenIDPResponse ).RawToken ()
155
130
if err != nil {
156
- return nil , fmt .Errorf ("failed to parse JWT token: %w" , err )
131
+ return nil , fmt .Errorf ("failed to get raw token: %w" , err )
157
132
}
133
+ rawToken = tokenStr
134
+ default :
135
+ return nil , fmt .Errorf ("unsupported response type: %s" , response .Type ())
136
+ }
158
137
159
- if claims . Oid == "" {
160
- return nil , fmt .Errorf ("JWT token does not contain OID claim " )
161
- }
138
+ if rawToken == "" {
139
+ return nil , fmt .Errorf ("raw token is empty " )
140
+ }
162
141
163
- rawToken = tokenStr
164
- username = claims .Oid
165
- password = rawToken
142
+ // Parse JWT
143
+ claims := struct {
144
+ jwt.RegisteredClaims
145
+ Oid string `json:"oid,omitempty"`
146
+ }{}
147
+
148
+ // Parse the token to extract claims, but note that signature verification
149
+ // should be handled by the identity provider
150
+ _ , _ , err := jwt .NewParser ().ParseUnverified (rawToken , & claims )
151
+ if err != nil {
152
+ return nil , fmt .Errorf ("failed to parse JWT token: %w" , err )
153
+ }
166
154
167
- if expiresOn . IsZero () && claims .ExpiresAt != nil {
168
- expiresOn = claims . ExpiresAt . UTC ( )
169
- }
155
+ if claims .Oid == "" {
156
+ return nil , fmt . Errorf ( "JWT token does not contain OID claim" )
157
+ }
170
158
171
- default :
172
- return nil , fmt .Errorf ("unsupported response type: %s" , response .Type ())
159
+ username = claims .Oid
160
+ password = rawToken
161
+ if expiresOn .IsZero () && claims .ExpiresAt != nil {
162
+ expiresOn = claims .ExpiresAt .UTC ()
173
163
}
174
164
175
165
if expiresOn .IsZero () {
@@ -187,6 +177,6 @@ func (*defaultIdentityProviderResponseParser) ParseResponse(response shared.Iden
187
177
rawToken ,
188
178
expiresOn ,
189
179
now ,
190
- int64 (time .Until (expiresOn ).Seconds ()),
180
+ int64 (math . Ceil ( time .Until (expiresOn ).Seconds () )),
191
181
), nil
192
182
}
0 commit comments