71 lines
2.1 KiB
Go
71 lines
2.1 KiB
Go
// Copyright (c) 2016, 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
|
// This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
|
|
|
|
package auth
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/oracle/oci-go-sdk/common"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type jwtToken struct {
|
|
raw string
|
|
header map[string]interface{}
|
|
payload map[string]interface{}
|
|
}
|
|
|
|
const bufferTimeBeforeTokenExpiration = 5 * time.Minute
|
|
|
|
func (t *jwtToken) expired() bool {
|
|
exp := int64(t.payload["exp"].(float64))
|
|
expTime := time.Unix(exp, 0)
|
|
expired := exp <= time.Now().Unix()+int64(bufferTimeBeforeTokenExpiration.Seconds())
|
|
if expired {
|
|
common.Debugf("Token expires at: %v, currently expired due to bufferTime: %v", expTime.Format("15:04:05.000"), expired)
|
|
}
|
|
return expired
|
|
}
|
|
|
|
func parseJwt(tokenString string) (*jwtToken, error) {
|
|
parts := strings.Split(tokenString, ".")
|
|
if len(parts) != 3 {
|
|
return nil, fmt.Errorf("the given token string contains an invalid number of parts")
|
|
}
|
|
|
|
token := &jwtToken{raw: tokenString}
|
|
var err error
|
|
|
|
// Parse Header part
|
|
var headerBytes []byte
|
|
if headerBytes, err = decodePart(parts[0]); err != nil {
|
|
return nil, fmt.Errorf("failed to decode the header bytes: %s", err.Error())
|
|
}
|
|
if err = json.Unmarshal(headerBytes, &token.header); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Parse Payload part
|
|
var payloadBytes []byte
|
|
if payloadBytes, err = decodePart(parts[1]); err != nil {
|
|
return nil, fmt.Errorf("failed to decode the payload bytes: %s", err.Error())
|
|
}
|
|
decoder := json.NewDecoder(bytes.NewBuffer(payloadBytes))
|
|
if err = decoder.Decode(&token.payload); err != nil {
|
|
return nil, fmt.Errorf("failed to decode the payload json: %s", err.Error())
|
|
}
|
|
|
|
return token, nil
|
|
}
|
|
|
|
func decodePart(partString string) ([]byte, error) {
|
|
if l := len(partString) % 4; 0 < l {
|
|
partString += strings.Repeat("=", 4-l)
|
|
}
|
|
return base64.URLEncoding.DecodeString(partString)
|
|
}
|