From bf0945eaef2fe1e65d269278e641318fadaf168d Mon Sep 17 00:00:00 2001 From: James Houlahan Date: Thu, 16 Jul 2020 10:19:50 +0200 Subject: [PATCH] fix: race condition in AuthRefresh that could cause user to be logged out --- Changelog.md | 1 + pkg/pmapi/auth.go | 3 +++ pkg/pmapi/client.go | 2 ++ 3 files changed, 6 insertions(+) diff --git a/Changelog.md b/Changelog.md index 8735d178..83c39d92 100644 --- a/Changelog.md +++ b/Changelog.md @@ -67,6 +67,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * GODT-321 Changing address ordering would cause all messages to disappear in combined mode. * GODT-129 Fix custom message PGP by using template. * GODT-280 Don't assume contact keys are stored armored. +* GODT-427 Fix race condition in auth refresh that could cause user to be logged out. ## [v1.2.8] Donghai-fix-append (beta 2020-06-XXX) diff --git a/pkg/pmapi/auth.go b/pkg/pmapi/auth.go index 29fef42b..6232c6d9 100644 --- a/pkg/pmapi/auth.go +++ b/pkg/pmapi/auth.go @@ -357,6 +357,9 @@ func (c *client) Auth2FA(twoFactorCode string, auth *Auth) (*Auth2FA, error) { // AuthRefresh will refresh an expired access token. func (c *client) AuthRefresh(uidAndRefreshToken string) (auth *Auth, err error) { + c.refreshLocker.Lock() + defer c.refreshLocker.Unlock() + // If we don't yet have a saved access token, save this one in case the refresh fails! // That way we can try again later (see handleUnauthorizedStatus). c.cm.setTokenIfUnset(c.userID, uidAndRefreshToken) diff --git a/pkg/pmapi/client.go b/pkg/pmapi/client.go index b483deb8..18748ec1 100644 --- a/pkg/pmapi/client.go +++ b/pkg/pmapi/client.go @@ -113,6 +113,7 @@ type client struct { accessToken string userID string requestLocker sync.Locker + refreshLocker sync.Locker user *User addresses AddressList @@ -130,6 +131,7 @@ func newClient(cm *ClientManager, userID string) *client { hc: getHTTPClient(cm.config, cm.roundTripper), userID: userID, requestLocker: &sync.Mutex{}, + refreshLocker: &sync.Mutex{}, keyRingLock: &sync.Mutex{}, addrKeyRing: make(map[string]*crypto.KeyRing), log: logrus.WithField("pkg", "pmapi").WithField("userID", userID),