зеркало из https://github.com/nextcloud/desktop.git
OAuth: Fix refresh of token after expiration
Before commit d3b00532b1
,
fetchFromKeychain was called everytime we detect that the creds are
invalid (in AccountState::slotInvalidCredentials)
But since that commit, AccountState was calling askFromUser directly,
breaking the refresh of the token.
So I made sure AccountState::slotInvalidCredentials still calls
refreshAccessToken.
Another change that was made was too be sure to clear the cookies
in HttpCredentials::invalidateToken even when we are only clearing the
access_token. That's because the session with a cookie may stay valid
longer than the access_token
This commit is contained in:
Родитель
a831164d65
Коммит
c043840cb1
|
@ -16,6 +16,7 @@
|
|||
#include "accountmanager.h"
|
||||
#include "account.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
#include "creds/httpcredentials.h"
|
||||
#include "logger.h"
|
||||
#include "configfile.h"
|
||||
|
||||
|
@ -305,12 +306,17 @@ void AccountState::slotInvalidCredentials()
|
|||
qCInfo(lcAccountState) << "Invalid credentials for" << _account->url().toString()
|
||||
<< "asking user";
|
||||
|
||||
if (account()->credentials()->ready())
|
||||
account()->credentials()->invalidateToken();
|
||||
account()->credentials()->askFromUser();
|
||||
|
||||
setState(AskingCredentials);
|
||||
_waitingForNewCredentials = true;
|
||||
setState(AskingCredentials);
|
||||
|
||||
if (account()->credentials()->ready()) {
|
||||
account()->credentials()->invalidateToken();
|
||||
if (auto creds = qobject_cast<HttpCredentials *>(account()->credentials())) {
|
||||
if (creds->refreshAccessToken())
|
||||
return;
|
||||
}
|
||||
}
|
||||
account()->credentials()->askFromUser();
|
||||
}
|
||||
|
||||
void AccountState::slotCredentialsFetched(AbstractCredentials *)
|
||||
|
|
|
@ -292,8 +292,11 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *incomingJob)
|
|||
}
|
||||
}
|
||||
|
||||
void HttpCredentials::refreshAccessToken()
|
||||
bool HttpCredentials::refreshAccessToken()
|
||||
{
|
||||
if (_refreshToken.isEmpty())
|
||||
return false;
|
||||
|
||||
QUrl requestToken(_account->url().toString()
|
||||
+ QLatin1String("/index.php/apps/oauth2/api/v1/token?grant_type=refresh_token&refresh_token=")
|
||||
+ _refreshToken);
|
||||
|
@ -324,6 +327,7 @@ void HttpCredentials::refreshAccessToken()
|
|||
}
|
||||
emit fetched();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -344,6 +348,9 @@ void HttpCredentials::invalidateToken()
|
|||
return;
|
||||
}
|
||||
|
||||
// clear the session cookie.
|
||||
_account->clearCookieJar();
|
||||
|
||||
if (!_refreshToken.isEmpty()) {
|
||||
// Only invalidate the access_token (_password) but keep the _refreshToken in the keychain
|
||||
// (when coming from forgetSensitiveData, the _refreshToken is cleared)
|
||||
|
@ -364,9 +371,6 @@ void HttpCredentials::invalidateToken()
|
|||
job2->setKey(kck);
|
||||
job2->start();
|
||||
|
||||
// clear the session cookie.
|
||||
_account->clearCookieJar();
|
||||
|
||||
// let QNAM forget about the password
|
||||
// This needs to be done later in the event loop because we might be called (directly or
|
||||
// indirectly) from QNetworkAccessManagerPrivate::authenticationRequired, which itself
|
||||
|
|
|
@ -46,8 +46,8 @@ namespace OCC {
|
|||
|
||||
1) First, AccountState will attempt to load the certificate from the keychain
|
||||
|
||||
----> fetchFromKeychain ------------------------> shortcut to refreshAccessToken if the cached
|
||||
| } information is still valid
|
||||
----> fetchFromKeychain
|
||||
| }
|
||||
v }
|
||||
slotReadClientCertPEMJobDone } There are first 3 QtKeychain jobs to fetch
|
||||
| } the TLS client keys, if any, and the password
|
||||
|
@ -92,7 +92,10 @@ public:
|
|||
QString fetchUser();
|
||||
virtual bool sslIsTrusted() { return false; }
|
||||
|
||||
void refreshAccessToken();
|
||||
/* If we still have a valid refresh token, try to refresh it assynchronously and emit fetched()
|
||||
* otherwise return false
|
||||
*/
|
||||
bool refreshAccessToken();
|
||||
|
||||
// To fetch the user name as early as possible
|
||||
void setAccount(Account *account) Q_DECL_OVERRIDE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче