identity: allow using and updating the "password" property
So far, only the "username" property was used once identity providers were involved. The upcoming oauth2 provider uses the "password" property for the refresh token and needs the ability to store a new token if the OAuth2 server updates it. Setting the new value will not always be possible (for example, when running a command line operation where all properties were provided on the command line without a permanent config). This still needs to be handled.
This commit is contained in:
parent
f2b2ea4271
commit
b747a8c2e4
|
@ -199,7 +199,8 @@ public:
|
|||
|
||||
virtual Credentials getCredentials() const { SE_THROW("only OAuth2 is supported"); }
|
||||
|
||||
virtual std::string getOAuth2Bearer(int failedTokens) const
|
||||
virtual std::string getOAuth2Bearer(int failedTokens,
|
||||
const PasswordUpdateCallback &passwordUpdateCallback) const
|
||||
{
|
||||
m_account->m_ensureCredentials();
|
||||
std::string token = m_account->m_getAccessToken();
|
||||
|
|
|
@ -85,7 +85,8 @@ public:
|
|||
|
||||
virtual Credentials getCredentials() const { SE_THROW("only OAuth2 is supported"); }
|
||||
|
||||
virtual std::string getOAuth2Bearer(int failedTokens) const
|
||||
virtual std::string getOAuth2Bearer(int failedTokens,
|
||||
const PasswordUpdateCallback &passwordUpdateCallback) const
|
||||
{
|
||||
SE_LOG_DEBUG(NULL, "retrieving OAuth2 token, attempt %d", failedTokens);
|
||||
|
||||
|
|
|
@ -957,7 +957,8 @@ void Session::checkAuthorization()
|
|||
// Count the number of times we asked for new tokens. This helps
|
||||
// the provider determine whether the token that it returns are valid.
|
||||
try {
|
||||
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(m_oauthTokenRejections);
|
||||
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(m_oauthTokenRejections,
|
||||
boost::bind(&Settings::updatePassword, m_settings, _1));
|
||||
SE_LOG_DEBUG(NULL, "got new OAuth2 token '%s' for next request", m_oauth2Bearer.c_str());
|
||||
} catch (...) {
|
||||
std::string explanation;
|
||||
|
|
|
@ -93,6 +93,11 @@ class Settings {
|
|||
*/
|
||||
virtual boost::shared_ptr<AuthProvider> getAuthProvider() = 0;
|
||||
|
||||
/**
|
||||
* Updates password to new one returned during OAuth2 authorization.
|
||||
*/
|
||||
virtual void updatePassword(const std::string& password) = 0;
|
||||
|
||||
/**
|
||||
* Google returns a 401 error even if the credentials
|
||||
* are valid. It seems to use that to throttle request
|
||||
|
|
|
@ -157,6 +157,8 @@ public:
|
|||
|
||||
virtual boost::shared_ptr<AuthProvider> getAuthProvider();
|
||||
|
||||
void updatePassword(const string &password);
|
||||
|
||||
std::string getUsername()
|
||||
{
|
||||
lookupAuthProvider();
|
||||
|
@ -205,6 +207,12 @@ boost::shared_ptr<AuthProvider> ContextSettings::getAuthProvider()
|
|||
return m_authProvider;
|
||||
}
|
||||
|
||||
void ContextSettings::updatePassword(const std::string &password)
|
||||
{
|
||||
m_context->setSyncPassword(password, false);
|
||||
m_context->flush();
|
||||
}
|
||||
|
||||
void ContextSettings::lookupAuthProvider()
|
||||
{
|
||||
if (m_authProvider) {
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
virtual bool wasConfigured() const { return !m_creds.m_username.empty() || !m_creds.m_password.empty(); }
|
||||
virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_CREDENTIALS; }
|
||||
virtual Credentials getCredentials() const { return m_creds; }
|
||||
virtual std::string getOAuth2Bearer(int failedTokens) const { SE_THROW("OAuth2 not supported"); return ""; }
|
||||
virtual std::string getOAuth2Bearer(int failedTokens, const PasswordUpdateCallback &passwordUpdateCallback) const { SE_THROW("OAuth2 not supported"); return ""; }
|
||||
virtual std::string getUsername() const { return m_creds.m_username; }
|
||||
};
|
||||
|
||||
|
|
|
@ -104,11 +104,15 @@ class AuthProvider
|
|||
* To achieve that, the caller must count how often he got a token that
|
||||
* did not work.
|
||||
*
|
||||
* @param failedTokens zero when asking for initial token, one for refresh, two for full re-authorization
|
||||
* @param failedTokens zero when asking for initial token, one for refresh, two for full re-authorization
|
||||
* @param passwordUpdateCallback callback function to be called when stored refresh token need to be updated.
|
||||
* Only parameter of this callback function is new value of refresh token.
|
||||
*
|
||||
* @return a base64 encoded token, ready to be used in "Authorization: Bearer %s"
|
||||
*/
|
||||
virtual std::string getOAuth2Bearer(int failedTokens) const = 0;
|
||||
typedef boost::function<void (const std::string &newPassword)> PasswordUpdateCallback;
|
||||
virtual std::string getOAuth2Bearer(int failedTokens,
|
||||
const PasswordUpdateCallback &passwordUpdateCallback) const = 0;
|
||||
|
||||
/**
|
||||
* Returns username at the remote service. Works for
|
||||
|
|
|
@ -2194,14 +2194,6 @@ void PasswordConfigProperty::savePassword(UserInterface &ui,
|
|||
}
|
||||
credConfig->setSyncPassword(password, false);
|
||||
syncPropPassword.savePassword(ui, *credConfig);
|
||||
} else if (identity.m_provider != USER_IDENTITY_PLAIN_TEXT) {
|
||||
// Cannot store passwords in providers.
|
||||
if (password.wasSet() && !password.empty()) {
|
||||
SE_THROW(StringPrintf("setting property '%s' not supported for provider '%s' from property '%s'",
|
||||
getMainName().c_str(),
|
||||
identity.m_provider.c_str(),
|
||||
usernameProperty.getMainName().c_str()));
|
||||
}
|
||||
} else {
|
||||
if (password == "-" || password == "" ||
|
||||
(boost::starts_with(password, "${") && boost::ends_with(password, "}"))) {
|
||||
|
|
Loading…
Reference in New Issue