11package iap
22
33import (
4+ "bufio"
45 "fmt"
56 "net/url"
67 "os"
78 "path/filepath"
9+ "strings"
10+ "time"
811
912 jwt "github.com/dgrijalva/jwt-go"
1013
@@ -25,6 +28,68 @@ type Cookie struct {
2528 Claims jwt.StandardClaims
2629}
2730
31+ // ReadCookie lookup the http.cookieFile for a given domain and try to load it from the filesystem
32+ func ReadCookie (domain string ) (* Cookie , error ) {
33+ cookieFile := git .ConfigGetURLMatch ("http.cookieFile" , domain )
34+
35+ url , err := url .Parse (domain )
36+ if err != nil {
37+ return nil , err
38+ }
39+
40+ c := Cookie {
41+ JarPath : cookieFile ,
42+ Domain : url .Host ,
43+ }
44+
45+ rawToken , err := c .readRawTokenFromJar ()
46+ if err != nil {
47+ return nil , err
48+ }
49+
50+ token , claims , err := parseJWToken (rawToken )
51+ if err != nil {
52+ return nil , err
53+ }
54+
55+ c .Token = token
56+ c .Claims = claims
57+
58+ return & c , nil
59+ }
60+
61+ func (c * Cookie ) readRawTokenFromJar () (string , error ) {
62+ path := expandHome (c .JarPath )
63+
64+ file , err := os .Open (path )
65+ if err != nil {
66+ return "" , err
67+ }
68+ defer file .Close ()
69+
70+ scanner := bufio .NewScanner (file )
71+ for scanner .Scan () {
72+ line := scanner .Text ()
73+ if strings .HasPrefix (line , "#" ) || line == "" {
74+ continue
75+ }
76+ fields := strings .Split (line , "\t " )
77+ if len (fields ) != 7 {
78+ log .Warn ().Msgf ("readRawTokenFromJar - unexpected format while parsing IAP cookie: %v" , line )
79+ continue
80+ }
81+ // see: https://curl.haxx.se/docs/http-cookies.html
82+ cookieName , cookieValue := fields [5 ], strings .TrimSpace (fields [6 ])
83+ if cookieName != IAPCookieName {
84+ log .Debug ().Msgf ("readRawTokenFromJar - skip '%s' while parsing IAP cookie" , cookieName )
85+ continue
86+ }
87+
88+ return cookieValue , nil
89+ }
90+ return "" , fmt .Errorf ("readRawTokenFromJar - %s not found" , IAPCookieName )
91+ }
92+
2893// NewCookie takes care of the authentication workflow and creates the relevant IAP Cookie on the filesystem
2994func NewCookie (domain string ) (* Cookie , error ) {
3095
@@ -81,6 +146,11 @@ func (c *Cookie) write(token string, exp int64) error {
81146 return nil
82147}
83148
149+ // Expired returns a boolean that indicate if the expires-at claim is in the future
150+ func (c * Cookie ) Expired () bool {
151+ return c .Claims .ExpiresAt < time .Now ().Unix ()
152+ }
153+
84154func parseJWToken (rawToken string ) (jwt.Token , jwt.StandardClaims , error ) {
85155 var p jwt.Parser
86156 var claims jwt.StandardClaims
0 commit comments