diff --git a/interface/src/main.cpp b/interface/src/main.cpp
index 9d8b733ba7..303d7f210b 100644
--- a/interface/src/main.cpp
+++ b/interface/src/main.cpp
@@ -83,6 +83,7 @@ int main(int argc, const char* argv[]) {
QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run");
QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache
", "dir");
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts ", "path");
+ QCommandLineOption responseTokensOption("tokens", "set response tokens ", "json");
parser.addOption(urlOption);
parser.addOption(noLauncherOption);
@@ -93,6 +94,7 @@ int main(int argc, const char* argv[]) {
parser.addOption(overrideAppLocalDataPathOption);
parser.addOption(overrideScriptsPathOption);
parser.addOption(allowMultipleInstancesOption);
+ parser.addOption(responseTokensOption);
if (!parser.parse(arguments)) {
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
@@ -121,7 +123,7 @@ int main(int argc, const char* argv[]) {
static const QString APPLICATION_CONFIG_FILENAME = "config.json";
QDir applicationDir(applicationPath);
QFile configFile(applicationDir.filePath(APPLICATION_CONFIG_FILENAME));
-
+ bool isConfigFileValid = false;
if (configFile.exists()) {
if (!configFile.open(QIODevice::ReadOnly)) {
qWarning() << "Found application config, but could not open it";
@@ -136,6 +138,7 @@ int main(int argc, const char* argv[]) {
static const QString LAUNCHER_PATH_KEY = "launcherPath";
QString launcherPath = doc.object()[LAUNCHER_PATH_KEY].toString();
if (!launcherPath.isEmpty()) {
+ isConfigFileValid = true;
if (!parser.isSet(noLauncherOption)) {
qDebug() << "Found a launcherPath in application config. Starting launcher.";
QProcess launcher;
@@ -146,6 +149,7 @@ int main(int argc, const char* argv[]) {
qDebug() << "Found a launcherPath in application config, but the launcher"
" has been suppressed. Continuing normal execution.";
}
+ configFile.close();
}
}
}
@@ -398,6 +402,18 @@ int main(int argc, const char* argv[]) {
printSystemInformation();
+ if (isConfigFileValid || parser.isSet(responseTokensOption)) {
+ auto accountManager = DependencyManager::get();
+ if (!accountManager.isNull()) {
+ if (parser.isSet(responseTokensOption)) {
+ QString tokens = QString(parser.value(responseTokensOption));
+ accountManager->setAccessTokens(tokens);
+ } else if (isConfigFileValid) {
+ accountManager->setConfigFileURL(configFile.fileName());
+ }
+ }
+ }
+
QTranslator translator;
translator.load("i18n/interface_en");
app.installTranslator(&translator);
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 226433e388..014ae62aff 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -97,6 +97,7 @@ void AccountManager::logout() {
// remove this account from the account settings file
removeAccountFromFile();
+ saveLoginStatus(false);
emit logoutComplete();
// the username has changed to blank
@@ -650,6 +651,39 @@ void AccountManager::refreshAccessToken() {
}
}
+void AccountManager::setAccessTokens(const QString& response) {
+ QJsonDocument jsonResponse = QJsonDocument::fromJson(response.toUtf8());
+ const QJsonObject& rootObject = jsonResponse.object();
+
+ if (!rootObject.contains("error")) {
+ // construct an OAuthAccessToken from the json object
+
+ if (!rootObject.contains("access_token") || !rootObject.contains("expires_in")
+ || !rootObject.contains("token_type")) {
+ // TODO: error handling - malformed token response
+ qCDebug(networking) << "Received a response for password grant that is missing one or more expected values.";
+ } else {
+ // clear the path from the response URL so we have the right root URL for this access token
+ QUrl rootURL = rootObject.contains("url") ? rootObject["url"].toString() : _authURL;
+ rootURL.setPath("");
+
+ qCDebug(networking) << "Storing an account with access-token for" << qPrintable(rootURL.toString());
+
+ _accountInfo = DataServerAccountInfo();
+ _accountInfo.setAccessTokenFromJSON(rootObject);
+ emit loginComplete(rootURL);
+
+ persistAccountToFile();
+
+ requestProfile();
+ }
+ } else {
+ // TODO: error handling
+ qCDebug(networking) << "Error in response for password grant -" << rootObject["error_description"].toString();
+ emit loginFailed();
+ }
+}
+
void AccountManager::requestAccessTokenFinished() {
QNetworkReply* requestReply = reinterpret_cast(sender());
@@ -895,3 +929,32 @@ void AccountManager::handleKeypairGenerationError() {
void AccountManager::setLimitedCommerce(bool isLimited) {
_limitedCommerce = isLimited;
}
+
+void AccountManager::saveLoginStatus(bool isLoggedIn) {
+ if (_configFileURL.isValid()) {
+ QFile configFile(_configFileURL.toString());
+ configFile.open(QIODevice::ReadOnly | QIODevice::Text);
+ QJsonParseError error;
+ QJsonDocument jsonDocument = QJsonDocument::fromJson(configFile.readAll(), &error);
+ configFile.close();
+ QString launcherPath;
+ if (error.error == QJsonParseError::NoError) {
+ QJsonObject rootObject = jsonDocument.object();
+ if (rootObject.contains("loggedIn")) {
+ rootObject["loggedIn"] = isLoggedIn;
+ }
+ if (rootObject.contains("laucherPath")) {
+ launcherPath = rootObject["launcherPath"].isString();
+ }
+ }
+ configFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
+ configFile.write(jsonDocument.toJson());
+ configFile.close();
+ if (!isLoggedIn && !launcherPath.isEmpty()) {
+ QProcess launcher;
+ launcher.setProgram(launcherPath);
+ launcher.startDetached();
+ qApp->quit();
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h
index 8732042e93..3fcbff4f99 100644
--- a/libraries/networking/src/AccountManager.h
+++ b/libraries/networking/src/AccountManager.h
@@ -102,6 +102,10 @@ public:
bool getLimitedCommerce() { return _limitedCommerce; }
void setLimitedCommerce(bool isLimited);
+ void setAccessTokens(const QString& response);
+ void setConfigFileURL(const QUrl& fileURL) { _configFileURL = fileURL; }
+ void saveLoginStatus(bool isLoggedIn);
+
public slots:
void requestAccessToken(const QString& login, const QString& password);
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
@@ -162,6 +166,7 @@ private:
QUuid _sessionID { QUuid::createUuid() };
bool _limitedCommerce { false };
+ QUrl _configFileURL;
};
#endif // hifi_AccountManager_h