Changed AccountManager to only rely on a proper OAuth response.

This involved making another request after the initial OAuth authorization.
Because of this now-two-step process, some methods and signals were renamed
to make their purpose more clear. Additionally, a _hasProfile member variable
was added to DataServerAccountInfo in order to allow for knowledge of whether
the profile elements had been fetched when being deserialized from disk.
Error handling for the whole process is still nonexistant.
This commit is contained in:
John Grosen 2014-06-12 23:28:43 -07:00
parent e8ba3c8bb1
commit 14f56310f6
6 changed files with 172 additions and 97 deletions

View file

@ -127,7 +127,7 @@ Menu::Menu() :
toggleLoginMenuItem();
// connect to the appropriate slots of the AccountManager so that we can change the Login/Logout menu item
connect(&accountManager, &AccountManager::accessTokenChanged, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::profileChanged, this, &Menu::toggleLoginMenuItem);
connect(&accountManager, &AccountManager::logoutComplete, this, &Menu::toggleLoginMenuItem);
addDisabledActionAndSeparator(fileMenu, "Scripts");
@ -1775,4 +1775,3 @@ QString Menu::getSnapshotsLocation() const {
}
return _snapshotsLocation;
}

View file

@ -23,7 +23,7 @@ XmppClient::XmppClient() :
_xmppMUCManager()
{
AccountManager& accountManager = AccountManager::getInstance();
connect(&accountManager, SIGNAL(accessTokenChanged()), this, SLOT(connectToServer()));
connect(&accountManager, SIGNAL(profileChanged()), this, SLOT(connectToServer()));
connect(&accountManager, SIGNAL(logoutComplete()), this, SLOT(disconnectFromServer()));
}

View file

@ -123,7 +123,12 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
_accountInfo = settings.value(key).value<DataServerAccountInfo>();
qDebug() << "Found a data-server access token for" << qPrintable(keyURL.toString());
emit accessTokenChanged();
// profile info isn't guaranteed to be saved too
if (_accountInfo.hasProfile()) {
emit profileChanged();
} else {
requestProfile();
}
}
}
@ -320,12 +325,12 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply* requestReply = _networkAccessManager->post(request, postData);
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestFinished);
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError)));
connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished);
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
}
void AccountManager::requestFinished() {
void AccountManager::requestAccessTokenFinished() {
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll());
@ -345,20 +350,18 @@ void AccountManager::requestFinished() {
qDebug() << "Storing an account with access-token for" << qPrintable(rootURL.toString());
_accountInfo = DataServerAccountInfo(rootObject);
_accountInfo = DataServerAccountInfo();
_accountInfo.setAccessTokenFromJSON(rootObject);
emit loginComplete(rootURL);
// the username has changed to whatever came back
emit usernameChanged(_accountInfo.getUsername());
// we have found or requested an access token
emit accessTokenChanged();
// store this access token into the local settings
QSettings localSettings;
localSettings.beginGroup(ACCOUNTS_GROUP);
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
QVariant::fromValue(_accountInfo));
requestProfile();
}
} else {
// TODO: error handling
@ -367,7 +370,53 @@ void AccountManager::requestFinished() {
}
}
void AccountManager::requestError(QNetworkReply::NetworkError error) {
void AccountManager::requestAccessTokenError(QNetworkReply::NetworkError error) {
// TODO: error handling
qDebug() << "AccountManager requestError - " << error;
}
void AccountManager::requestProfile() {
if (!_networkAccessManager) {
_networkAccessManager = new QNetworkAccessManager(this);
}
QUrl profileURL = _authURL;
profileURL.setPath("/api/v1/users/profile");
profileURL.setQuery("access_token=" + _accountInfo.getAccessToken().token);
QNetworkReply* profileReply = _networkAccessManager->get(QNetworkRequest(profileURL));
connect(profileReply, &QNetworkReply::finished, this, &AccountManager::requestProfileFinished);
connect(profileReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestProfileError(QNetworkReply::NetworkError)));
}
void AccountManager::requestProfileFinished() {
QNetworkReply* profileReply = reinterpret_cast<QNetworkReply*>(sender());
QJsonDocument jsonResponse = QJsonDocument::fromJson(profileReply->readAll());
const QJsonObject& rootObject = jsonResponse.object();
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
_accountInfo.setProfileInfoFromJSON(rootObject);
emit profileChanged();
// the username has changed to whatever came back
emit usernameChanged(_accountInfo.getUsername());
// store the whole profile into the local settings
QUrl rootURL = profileReply->url();
rootURL.setPath("");
QSettings localSettings;
localSettings.beginGroup(ACCOUNTS_GROUP);
localSettings.setValue(rootURL.toString().replace("//", DOUBLE_SLASH_SUBSTITUTE),
QVariant::fromValue(_accountInfo));
} else {
// TODO: error handling
qDebug() << "Error in response for profile";
}
}
void AccountManager::requestProfileError(QNetworkReply::NetworkError error) {
// TODO: error handling
qDebug() << "AccountManager requestProfileError - " << error;
}

View file

@ -54,14 +54,17 @@ public:
Q_INVOKABLE bool checkAndSignalForAccessToken();
void requestAccessToken(const QString& login, const QString& password);
void requestProfile();
const DataServerAccountInfo& getAccountInfo() const { return _accountInfo; }
void destroy() { delete _networkAccessManager; }
public slots:
void requestFinished();
void requestError(QNetworkReply::NetworkError error);
void requestAccessTokenFinished();
void requestProfileFinished();
void requestAccessTokenError(QNetworkReply::NetworkError error);
void requestProfileError(QNetworkReply::NetworkError error);
void logout();
void updateBalance();
void accountInfoBalanceChanged(qint64 newBalance);
@ -69,7 +72,7 @@ signals:
void authRequired();
void authEndpointChanged();
void usernameChanged(const QString& username);
void accessTokenChanged();
void profileChanged();
void loginComplete(const QUrl& authURL);
void loginFailed();
void logoutComplete();

View file

@ -19,11 +19,13 @@ DataServerAccountInfo::DataServerAccountInfo() :
_xmppPassword(),
_discourseApiKey(),
_balance(0),
_hasBalance(false)
_hasBalance(false),
_hasProfile(false)
{
}
/*
DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) :
_accessToken(jsonObject),
_username(),
@ -36,6 +38,7 @@ DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) :
setXMPPPassword(userJSONObject["xmpp_password"].toString());
setDiscourseApiKey(userJSONObject["discourse_api_key"].toString());
}
*/
DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherInfo) {
_accessToken = otherInfo._accessToken;
@ -44,6 +47,7 @@ DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherI
_discourseApiKey = otherInfo._discourseApiKey;
_balance = otherInfo._balance;
_hasBalance = otherInfo._hasBalance;
_hasProfile = otherInfo._hasProfile;
}
DataServerAccountInfo& DataServerAccountInfo::operator=(const DataServerAccountInfo& otherInfo) {
@ -61,6 +65,11 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
swap(_discourseApiKey, otherInfo._discourseApiKey);
swap(_balance, otherInfo._balance);
swap(_hasBalance, otherInfo._hasBalance);
swap(_hasProfile, otherInfo._hasProfile);
}
void DataServerAccountInfo::setAccessTokenFromJSON(const QJsonObject& jsonObject) {
_accessToken = OAuthAccessToken(jsonObject);
}
void DataServerAccountInfo::setUsername(const QString& username) {
@ -99,12 +108,20 @@ void DataServerAccountInfo::setBalanceFromJSON(const QJsonObject& jsonObject) {
}
}
void DataServerAccountInfo::setProfileInfoFromJSON(const QJsonObject& jsonObject) {
QJsonObject user = jsonObject["data"].toObject()["user"].toObject();
setUsername(user["username"].toString());
setXMPPPassword(user["xmpp_password"].toString());
setDiscourseApiKey(user["discourse_api_key"].toString());
setHasProfile(true);
}
QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) {
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey;
out << info._accessToken << info._username << info._xmppPassword << info._discourseApiKey << info._hasProfile;
return out;
}
QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info) {
in >> info._accessToken >> info._username >> info._xmppPassword >> info._discourseApiKey;
in >> info._accessToken >> info._username >> info._xmppPassword >> info._discourseApiKey >> info._hasProfile;
return in;
}

View file

@ -22,11 +22,12 @@ class DataServerAccountInfo : public QObject {
Q_OBJECT
public:
DataServerAccountInfo();
DataServerAccountInfo(const QJsonObject& jsonObject);
// DataServerAccountInfo(const QJsonObject& jsonObject);
DataServerAccountInfo(const DataServerAccountInfo& otherInfo);
DataServerAccountInfo& operator=(const DataServerAccountInfo& otherInfo);
const OAuthAccessToken& getAccessToken() const { return _accessToken; }
void setAccessTokenFromJSON(const QJsonObject& jsonObject);
const QString& getUsername() const { return _username; }
void setUsername(const QString& username);
@ -43,6 +44,11 @@ public:
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
Q_INVOKABLE void setBalanceFromJSON(const QJsonObject& jsonObject);
bool hasProfile() const { return _hasProfile; }
void setHasProfile(bool hasProfile) { _hasProfile = hasProfile; }
void setProfileInfoFromJSON(const QJsonObject& jsonObject);
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
signals:
@ -56,6 +62,7 @@ private:
QString _discourseApiKey;
qint64 _balance;
bool _hasBalance;
bool _hasProfile;
};
#endif // hifi_DataServerAccountInfo_h