|
6 | 6 | "fmt"
|
7 | 7 | "log"
|
8 | 8 | "net/http"
|
| 9 | + "strings" |
9 | 10 | "sync"
|
10 | 11 | "sync/atomic"
|
11 | 12 | "time"
|
@@ -75,6 +76,38 @@ type OAuth2TokenResponse struct {
|
75 | 76 | ExpiresIn int `json:"expires_in"`
|
76 | 77 | }
|
77 | 78 |
|
| 79 | +func HandleOAuth2InspectToken(w http.ResponseWriter, r *http.Request) { |
| 80 | + enc := json.NewEncoder(w) |
| 81 | + enc.SetIndent("", " ") |
| 82 | + w.Header().Set("Content-Type", "application/json") |
| 83 | + |
| 84 | + authz := r.Header.Get("Authorization") |
| 85 | + if authz == "" { |
| 86 | + http.Error(w, `{"error": "unauthorized"}`, http.StatusUnauthorized) |
| 87 | + return |
| 88 | + } |
| 89 | + if !strings.HasPrefix(authz, "Bearer ") { |
| 90 | + http.Error(w, `{"error": "invalid authorization"}`, http.StatusBadRequest) |
| 91 | + return |
| 92 | + } |
| 93 | + |
| 94 | + token := authz[len("Bearer "):] |
| 95 | + claims, err := ParseToken(token) |
| 96 | + if err != nil { |
| 97 | + http.Error(w, `{"error": "invalid token"}`, http.StatusBadRequest) |
| 98 | + return |
| 99 | + } |
| 100 | + |
| 101 | + updatedExpiry := GetTokenExpiry(claims) |
| 102 | + |
| 103 | + claims["exp"] = float64(updatedExpiry.Unix()) |
| 104 | + |
| 105 | + if err := enc.Encode(claims); err != nil { |
| 106 | + http.Error(w, `{"error": "failed to encode response"}`, http.StatusInternalServerError) |
| 107 | + return |
| 108 | + } |
| 109 | +} |
| 110 | + |
78 | 111 | func HandleOAuth2(w http.ResponseWriter, r *http.Request) {
|
79 | 112 | enc := json.NewEncoder(w)
|
80 | 113 | enc.SetIndent("", " ")
|
@@ -165,6 +198,10 @@ func HandleOAuth2(w http.ResponseWriter, r *http.Request) {
|
165 | 198 |
|
166 | 199 | now := time.Now()
|
167 | 200 | expires := now.Add(time.Hour)
|
| 201 | + forcedExpiry := r.Header.Get("x-oauth2-expire-at") |
| 202 | + if exp, err := time.Parse(time.RFC3339, forcedExpiry); err == nil { |
| 203 | + expires = exp |
| 204 | + } |
168 | 205 |
|
169 | 206 | accessTokenID := gofakeit.UUID()
|
170 | 207 | accessTokenClaims := jwt.MapClaims{
|
@@ -248,6 +285,24 @@ func RefreshToken(refreshClaims jwt.MapClaims) {
|
248 | 285 | tokenDB.Store(tokenID, expiry)
|
249 | 286 | }
|
250 | 287 |
|
| 288 | +func GetTokenExpiry(tokenClaims jwt.MapClaims) time.Time { |
| 289 | + tokenDBLastAccess.Store(time.Now()) |
| 290 | + |
| 291 | + tokenID := tokenClaims["id"].(string) |
| 292 | + |
| 293 | + exp, found := tokenDB.Load(tokenID) |
| 294 | + if found { |
| 295 | + return exp.(time.Time) |
| 296 | + } |
| 297 | + |
| 298 | + expiryClaim, err := tokenClaims.GetExpirationTime() |
| 299 | + if err != nil { |
| 300 | + panic(err) |
| 301 | + } |
| 302 | + |
| 303 | + return expiryClaim.Time |
| 304 | +} |
| 305 | + |
251 | 306 | func IsTokenExpired(tokenClaims jwt.MapClaims) bool {
|
252 | 307 | tokenDBLastAccess.Store(time.Now())
|
253 | 308 |
|
|
0 commit comments