Improvements to Session State code (#536)

* Drop SessionStateJSON wrapper
* Use EncrpytInto/DecryptInto to reduce sessionstate

Co-authored-by: Henry Jenkins <henry@henryjenkins.name>
This commit is contained in:
Joel Speed
2020-05-30 08:53:38 +01:00
committed by GitHub
co-authored by Henry Jenkins
parent 6a88da7f7a
commit f7b28cb1d3
17 changed files with 185 additions and 164 deletions
+4 -2
View File
@@ -126,11 +126,13 @@ func (p *AzureProvider) Redeem(ctx context.Context, redirectURL, code string) (s
return
}
created := time.Now()
expires := time.Unix(jsonResponse.ExpiresOn, 0)
s = &sessions.SessionState{
AccessToken: jsonResponse.AccessToken,
IDToken: jsonResponse.IDToken,
CreatedAt: time.Now(),
ExpiresOn: time.Unix(jsonResponse.ExpiresOn, 0),
CreatedAt: &created,
ExpiresOn: &expires,
RefreshToken: jsonResponse.RefreshToken,
}
return
+4 -3
View File
@@ -67,7 +67,7 @@ func (p *GitLabProvider) Redeem(ctx context.Context, redirectURL, code string) (
// RefreshSessionIfNeeded checks if the session has expired and uses the
// RefreshToken to fetch a new ID token if required
func (p *GitLabProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error) {
if s == nil || s.ExpiresOn.After(time.Now()) || s.RefreshToken == "" {
if s == nil || (s.ExpiresOn != nil && s.ExpiresOn.After(time.Now())) || s.RefreshToken == "" {
return false, nil
}
@@ -209,12 +209,13 @@ func (p *GitLabProvider) createSessionState(ctx context.Context, token *oauth2.T
return nil, fmt.Errorf("could not verify id_token: %v", err)
}
created := time.Now()
return &sessions.SessionState{
AccessToken: token.AccessToken,
IDToken: rawIDToken,
RefreshToken: token.RefreshToken,
CreatedAt: time.Now(),
ExpiresOn: idToken.Expiry,
CreatedAt: &created,
ExpiresOn: &idToken.Expiry,
}, nil
}
+8 -4
View File
@@ -153,11 +153,14 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code string) (
if err != nil {
return
}
created := time.Now()
expires := time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second)
s = &sessions.SessionState{
AccessToken: jsonResponse.AccessToken,
IDToken: jsonResponse.IDToken,
CreatedAt: time.Now(),
ExpiresOn: time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second),
CreatedAt: &created,
ExpiresOn: &expires,
RefreshToken: jsonResponse.RefreshToken,
Email: c.Email,
User: c.Subject,
@@ -245,7 +248,7 @@ func (p *GoogleProvider) ValidateGroup(email string) bool {
// RefreshSessionIfNeeded checks if the session has expired and uses the
// RefreshToken to fetch a new ID token if required
func (p *GoogleProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error) {
if s == nil || s.ExpiresOn.After(time.Now()) || s.RefreshToken == "" {
if s == nil || (s.ExpiresOn != nil && s.ExpiresOn.After(time.Now())) || s.RefreshToken == "" {
return false, nil
}
@@ -260,9 +263,10 @@ func (p *GoogleProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions
}
origExpiration := s.ExpiresOn
expires := time.Now().Add(duration).Truncate(time.Second)
s.AccessToken = newToken
s.IDToken = newIDToken
s.ExpiresOn = time.Now().Add(duration).Truncate(time.Second)
s.ExpiresOn = &expires
logger.Printf("refreshed access token %s (expired on %s)", s, origExpiration)
return true, nil
}
+5 -2
View File
@@ -250,12 +250,15 @@ func (p *LoginGovProvider) Redeem(ctx context.Context, redirectURL, code string)
return
}
created := time.Now()
expires := time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second)
// Store the data that we found in the session state
s = &sessions.SessionState{
AccessToken: jsonResponse.AccessToken,
IDToken: jsonResponse.IDToken,
CreatedAt: time.Now(),
ExpiresOn: time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second),
CreatedAt: &created,
ExpiresOn: &expires,
Email: email,
}
return
+5 -4
View File
@@ -72,7 +72,7 @@ func (p *OIDCProvider) Redeem(ctx context.Context, redirectURL, code string) (s
// RefreshSessionIfNeeded checks if the session has expired and uses the
// RefreshToken to fetch a new Access Token (and optional ID token) if required
func (p *OIDCProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error) {
if s == nil || s.ExpiresOn.After(time.Now()) || s.RefreshToken == "" {
if s == nil || (s.ExpiresOn != nil && s.ExpiresOn.After(time.Now())) || s.RefreshToken == "" {
return false, nil
}
@@ -163,10 +163,11 @@ func (p *OIDCProvider) createSessionState(ctx context.Context, token *oauth2.Tok
}
}
created := time.Now()
newSession.AccessToken = token.AccessToken
newSession.RefreshToken = token.RefreshToken
newSession.CreatedAt = time.Now()
newSession.ExpiresOn = token.Expiry
newSession.CreatedAt = &created
newSession.ExpiresOn = &token.Expiry
return newSession, nil
}
@@ -179,7 +180,7 @@ func (p *OIDCProvider) CreateSessionStateFromBearerToken(ctx context.Context, ra
newSession.AccessToken = rawIDToken
newSession.IDToken = rawIDToken
newSession.RefreshToken = ""
newSession.ExpiresOn = idToken.Expiry
newSession.ExpiresOn = &idToken.Expiry
return newSession, nil
}
+4 -4
View File
@@ -204,8 +204,8 @@ func TestOIDCProviderRefreshSessionIfNeededWithoutIdToken(t *testing.T) {
existingSession := &sessions.SessionState{
AccessToken: "changeit",
IDToken: idToken,
CreatedAt: time.Time{},
ExpiresOn: time.Time{},
CreatedAt: nil,
ExpiresOn: nil,
RefreshToken: refreshToken,
Email: "janedoe@example.com",
User: "11223344",
@@ -238,8 +238,8 @@ func TestOIDCProviderRefreshSessionIfNeededWithIdToken(t *testing.T) {
existingSession := &sessions.SessionState{
AccessToken: "changeit",
IDToken: "changeit",
CreatedAt: time.Time{},
ExpiresOn: time.Time{},
CreatedAt: nil,
ExpiresOn: nil,
RefreshToken: refreshToken,
Email: "changeit",
User: "changeit",
+3 -2
View File
@@ -81,7 +81,8 @@ func (p *ProviderData) Redeem(ctx context.Context, redirectURL, code string) (s
return
}
if a := v.Get("access_token"); a != "" {
s = &sessions.SessionState{AccessToken: a, CreatedAt: time.Now()}
created := time.Now()
s = &sessions.SessionState{AccessToken: a, CreatedAt: &created}
} else {
err = fmt.Errorf("no access token found %s", body)
}
@@ -168,7 +169,7 @@ func (p *ProviderData) CreateSessionStateFromBearerToken(ctx context.Context, ra
newSession.AccessToken = rawIDToken
newSession.IDToken = rawIDToken
newSession.RefreshToken = ""
newSession.ExpiresOn = idToken.Expiry
newSession.ExpiresOn = &idToken.Expiry
return newSession, nil
}
+3 -1
View File
@@ -11,8 +11,10 @@ import (
func TestRefresh(t *testing.T) {
p := &ProviderData{}
expires := time.Now().Add(time.Duration(-11) * time.Minute)
refreshed, err := p.RefreshSessionIfNeeded(context.Background(), &sessions.SessionState{
ExpiresOn: time.Now().Add(time.Duration(-11) * time.Minute),
ExpiresOn: &expires,
})
assert.Equal(t, false, refreshed)
assert.Equal(t, nil, err)