Merge pull request #5959 from nextcloud/bugfix/oc-account-login

oc desktop client login migration to nc desktop client login
This commit is contained in:
Camila 2023-09-01 10:53:11 -03:00 committed by GitHub
commit c3845136af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 246599 deletions

View File

@ -72,6 +72,7 @@ cp -R /usr/lib/x86_64-linux-gnu/libssl.so* ./usr/lib/
cp -R /usr/lib/x86_64-linux-gnu/libcrypto.so* ./usr/lib/
cp -P /usr/local/lib*/libssl.so* ./usr/lib/
cp -P /usr/local/lib*/libcrypto.so* ./usr/lib/
cp -P /usr/local/lib*/libsqlite*.so* ./usr/lib/
# NSS fun
cp -P -r /usr/lib/x86_64-linux-gnu/nss ./usr/lib/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -107,8 +107,9 @@ AccountManager::AccountsRestoreResult AccountManager::restore(const bool alsoRes
if (auto accState = AccountState::loadFromSettings(acc, *settings)) {
auto jar = qobject_cast<CookieJar*>(acc->_am->cookieJar());
ASSERT(jar);
if (jar)
if (jar) {
jar->restore(acc->cookieJarPath());
}
addAccountState(accState);
}
}
@ -303,6 +304,7 @@ void AccountManager::saveAccountState(AccountState *a)
void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool saveCredentials)
{
qCDebug(lcAccountManager) << "Saving settings to" << settings.fileName();
settings.setValue(QLatin1String(versionC), maxAccountVersion);
settings.setValue(QLatin1String(urlC), acc->_url.toString());
settings.setValue(QLatin1String(davUserC), acc->_davUser);
@ -332,8 +334,9 @@ void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool s
settings.setValue(QLatin1String(authTypeC), acc->_credentials->authType());
// HACK: Save http_user also as user
if (acc->_settingsMap.contains(httpUserC))
if (acc->_settingsMap.contains(httpUserC)) {
settings.setValue(userC, acc->_settingsMap.value(httpUserC));
}
}
// Save accepted certificates.
@ -376,8 +379,8 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
auto authType = settings.value(QLatin1String(authTypeC)).toString();
// There was an account-type saving bug when 'skip folder config' was used
// See #5408. This attempts to fix up the "dummy" authType
if (authType == QLatin1String(dummyAuthTypeC)) {
// See owncloud#5408. This attempts to fix up the "dummy" or empty authType
if (authType == QLatin1String(dummyAuthTypeC) || authType.isEmpty()) {
if (settings.contains(QLatin1String(httpUserC))) {
authType = httpAuthTypeC;
} else if (settings.contains(QLatin1String(shibbolethUserC))) {
@ -401,15 +404,16 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
// Migrate to webflow
if (authType == QLatin1String(httpAuthTypeC)) {
authType = webflowAuthTypeC;
settings.setValue(QLatin1String(authTypeC), authType);
acc->_settingsMap.insert(QLatin1String(authTypeC), authType);
const auto settingsChildKeys = settings.childKeys();
for (const auto &key : settingsChildKeys) {
if (!key.startsWith(httpAuthPrefix))
if (!key.startsWith(httpAuthPrefix)) {
continue;
}
const auto newkey = QString::fromLatin1(webflowAuthPrefix).append(key.mid(5));
settings.setValue(newkey, settings.value((key)));
settings.remove(key);
acc->_settingsMap.insert(newkey, settings.value(key));
}
}
@ -419,16 +423,16 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
acc->_serverColor = settings.value(QLatin1String(serverColorC)).value<QColor>();
acc->_serverTextColor = settings.value(QLatin1String(serverTextColorC)).value<QColor>();
acc->_skipE2eeMetadataChecksumValidation = settings.value(QLatin1String(skipE2eeMetadataChecksumValidationC), {}).toBool();
acc->_davUser = settings.value(QLatin1String(davUserC), "").toString();
acc->_davUser = settings.value(QLatin1String(davUserC)).toString();
// We want to only restore settings for that auth type and the user value
acc->_settingsMap.insert(QLatin1String(userC), settings.value(userC));
acc->_displayName = settings.value(QLatin1String(displayNameC), "").toString();
QString authTypePrefix = authType + "_";
const QString authTypePrefix = authType + "_";
const auto settingsChildKeys = settings.childKeys();
for (const auto &key : settingsChildKeys) {
if (!key.startsWith(authTypePrefix))
if (!key.startsWith(authTypePrefix)) {
continue;
}
acc->_settingsMap.insert(key, settings.value(key));
}

View File

@ -180,29 +180,9 @@ void WebFlowCredentials::askFromUser() {
void WebFlowCredentials::slotAskFromUserCredentialsProvided(const QString &user, const QString &pass, const QString &host) {
Q_UNUSED(host)
// Compare the re-entered username case-insensitive and save the new value (avoid breaking the account)
// See issue: https://github.com/nextcloud/desktop/issues/1741
if (QString::compare(_user, user, Qt::CaseInsensitive) == 0) {
_user = user;
} else {
qCInfo(lcWebFlowCredentials()) << "Authed with the wrong user!";
QString msg = tr("Please login with the account: %1")
.arg(_account->prettyName());
_askDialog->setError(msg);
if (!_askDialog->isUsingFlow2()) {
QUrl url = _account->url();
QString path = url.path() + "/index.php/login/flow";
url.setPath(path);
_askDialog->setUrl(url);
}
return;
}
qCInfo(lcWebFlowCredentials()) << "Obtained a new password";
_user = user;
_password = pass;
_ready = true;
_credentialsValid = true;

View File

@ -893,6 +893,14 @@ void Folder::blacklistPath(const QString &path)
appendPathToSelectiveSyncList(path, SyncJournalDb::SelectiveSyncBlackList);
}
void Folder::migrateBlackListPath(const QString &legacyPath)
{
if (legacyPath.startsWith(QLatin1Char('/'))) {
removePathFromSelectiveSyncList(legacyPath, SyncJournalDb::SelectiveSyncBlackList);
blacklistPath(legacyPath.mid(1));
}
}
bool Folder::isFileExcludedAbsolute(const QString &fullPath) const
{
return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);

View File

@ -303,6 +303,7 @@ public:
void whitelistPath(const QString &path);
void blacklistPath(const QString &path);
void migrateBlackListPath(const QString &legacyPath);
signals:
void syncStateChange();

View File

@ -172,9 +172,6 @@ int FolderMan::setupFolders()
unloadAndDeleteAllFolders();
QStringList skipSettingsKeys;
backwardMigrationSettingsKeys(&skipSettingsKeys, &skipSettingsKeys);
auto settings = ConfigFile::settingsWithGroup(QLatin1String("Accounts"));
const auto accountsWithSettings = settings->childGroups();
if (accountsWithSettings.isEmpty()) {
@ -187,6 +184,9 @@ int FolderMan::setupFolders()
qCInfo(lcFolderMan) << "Setup folders from settings file";
// this is done in Application::configVersionMigration
QStringList skipSettingsKeys;
backwardMigrationSettingsKeys(&skipSettingsKeys, &skipSettingsKeys);
const auto accounts = AccountManager::instance()->accounts();
for (const auto &account : accounts) {
const auto id = account->account()->id();
@ -353,19 +353,17 @@ int FolderMan::setupFoldersMigration()
qCInfo(lcFolderMan) << "Setup folders from " << configPath << "(migration)";
QDir dir(configPath);
//We need to include hidden files just in case the alias starts with '.'
// We need to include hidden files just in case the alias starts with '.'
dir.setFilter(QDir::Files | QDir::Hidden);
const auto dirFiles = dir.entryList();
// Exclude previous backed up configs e.g. oc.cfg.backup_20230831_133749_4.0.0
// only need the current config in use by the legacy application
const auto dirFiles = dir.entryList({"*.cfg"});
// Normally there should be only one account when migrating. TODO: Change
// Normally there should be only one account when migrating. TODO: Should assume only one legacy config file
const auto accountState = AccountManager::instance()->accounts().value(0).data();
for (const auto &fileName : dirFiles) {
const auto fullFilePath = dir.filePath(fileName);
const auto folder = setupFolderFromOldConfigFile(fullFilePath, accountState);
if (folder) {
scheduleFolder(folder);
emit folderSyncStateChange(folder);
}
setupFolderFromOldConfigFile(fullFilePath, accountState);
}
emit folderListChanged(_folderMap);
@ -481,8 +479,7 @@ QString FolderMan::unescapeAlias(const QString &alias)
return a;
}
// WARNING: Do not remove this code, it is used for predefined/automated deployments (2016)
Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, AccountState *accountState)
void FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, AccountState *accountState)
{
qCInfo(lcFolderMan) << " ` -> setting up:" << fileNamePath;
QString escapedFileNamePath(fileNamePath);
@ -498,7 +495,7 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, Acc
}
if (!cfgFile.isReadable()) {
qCWarning(lcFolderMan) << "Cannot read folder definition for alias " << cfgFile.filePath();
return nullptr;
return;
}
QSettings settings(escapedFileNamePath, QSettings::IniFormat);
@ -509,12 +506,12 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, Acc
const auto groups = settings.childGroups();
if (groups.isEmpty()) {
qCWarning(lcFolderMan) << "empty file:" << cfgFile.filePath();
return nullptr;
return;
}
if (!accountState) {
qCCritical(lcFolderMan) << "can't create folder without an account";
return nullptr;
return;
}
settings.beginGroup(settingsAccountsC);
@ -566,10 +563,21 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, Acc
folderDefinition.ignoreHiddenFiles = ignoreHiddenFiles;
if (const auto folder = addFolderInternal(folderDefinition, accountState, std::make_unique<VfsOff>())) {
const auto blackList = settings.value(QLatin1String("blackList")).toStringList();
if (!blackList.empty()) {
//migrate settings
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
auto ok = true;
if (const auto legacyBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList,
&ok); ok && !legacyBlacklist.isEmpty()) {
qCInfo(lcFolderMan) << "Legacy selective sync list found:" << legacyBlacklist;
for (const auto &legacyFolder : legacyBlacklist) {
folder->migrateBlackListPath(legacyFolder);
}
} else {
qCInfo(lcFolderMan) << "There was a problem retriving the database selective sync for " << folder;
}
const auto settingLegacyBlacklist = settings.value(QLatin1String("blackList")).toStringList();
if (!settingLegacyBlacklist.empty()) {
// migrate settings
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, settingLegacyBlacklist);
settings.remove(QLatin1String("blackList"));
// FIXME: If you remove this codepath, you need to provide another way to do
// this via theme.h or the normal FolderMan::setupFolders
@ -577,10 +585,15 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, Acc
folder->saveToSettings();
qCInfo(lcFolderMan) << "Migrated!" << folder;
qCInfo(lcFolderMan) << "Migrated!" << folder->path();
settings.sync();
return folder;
if (!folder) {
continue;
}
scheduleFolder(folder);
emit folderSyncStateChange(folder);
}
settings.endGroup();
@ -590,7 +603,7 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &fileNamePath, Acc
settings.endGroup();
}
return nullptr;
return;
}
void FolderMan::slotFolderSyncPaused(Folder *f, bool paused)

View File

@ -119,10 +119,10 @@ public:
Folder *folder(const QString &);
/**
* Migrate accounts from owncloud < 2.0
* Migrate accounts from owncloud
* Creates a folder for a specific configuration, identified by alias.
*/
Folder *setupFolderFromOldConfigFile(const QString &, AccountState *account);
void setupFolderFromOldConfigFile(const QString &, AccountState *account);
/**
* Ensures that a given directory does not contain a sync journal file.

View File

@ -110,17 +110,23 @@ void UserInfo::slotUpdateLastInfo(const QJsonDocument &json)
AccountPtr account = _accountState->account();
// User Info
QString user = objData.value("id").toString();
if (!user.isEmpty()) {
account->setDavUser(user);
if (const auto newUserId = objData.value("id").toString(); !newUserId.isEmpty()) {
if (QString::compare(account->davUser(), newUserId, Qt::CaseInsensitive) != 0) {
// TODO: the error message should be in the UI
qInfo() << "Authenticated with the wrong user! Please login with the account:" << account->prettyName();
if (const auto cred = account->credentials()) {
account->credentials()->askFromUser();
}
return;
}
account->setDavUser(newUserId);
}
QString displayName = objData.value("display-name").toString();
if (!displayName.isEmpty()) {
account->setDavDisplayName(displayName);
}
// Quota
auto objQuota = objData.value("quota").toObject();
qint64 used = objQuota.value("used").toDouble();
qint64 total = objQuota.value("quota").toDouble();
@ -134,15 +140,15 @@ void UserInfo::slotUpdateLastInfo(const QJsonDocument &json)
_jobRestartTimer.start(defaultIntervalT);
_lastInfoReceived = QDateTime::currentDateTime();
// Avatar Image
if(_fetchAvatarImage) {
auto *job = new AvatarJob(account, account->davUser(), 128, this);
job->setTimeout(20 * 1000);
QObject::connect(job, &AvatarJob::avatarPixmap, this, &UserInfo::slotAvatarImage);
job->start();
return;
}
else
emit fetchedLastInfo(this);
emit fetchedLastInfo(this);
}
void UserInfo::slotAvatarImage(const QImage &img)

View File

@ -368,32 +368,27 @@ QString ConfigFile::configPath() const
return Utility::trailingSlashPath(_confDir);
}
static const QLatin1String exclFile("sync-exclude.lst");
static const QLatin1String syncExclFile("sync-exclude.lst");
static const QLatin1String exclFile("exclude.lst");
QString ConfigFile::excludeFile(Scope scope) const
{
// prefer sync-exclude.lst, but if it does not exist, check for
// exclude.lst for compatibility reasons in the user writeable
// directories.
QFileInfo fi;
switch (scope) {
case UserScope:
fi.setFile(configPath(), exclFile);
if (!fi.isReadable()) {
fi.setFile(configPath(), QLatin1String("exclude.lst"));
}
if (!fi.isReadable()) {
fi.setFile(configPath(), exclFile);
}
return fi.absoluteFilePath();
case SystemScope:
if (scope == SystemScope) {
return ConfigFile::excludeFileFromSystem();
}
ASSERT(false);
return QString();
const auto excludeFilePath = scope == LegacyScope ? discoveredLegacyConfigPath() : configPath();
// prefer sync-exclude.lst, but if it does not exist, check for exclude.lst
QFileInfo exclFileInfo(excludeFilePath, syncExclFile);
if (!exclFileInfo.isReadable()) {
exclFileInfo.setFile(excludeFilePath, exclFile);
}
if (!exclFileInfo.isReadable()) {
exclFileInfo.setFile(excludeFilePath, syncExclFile);
}
return exclFileInfo.absoluteFilePath();
}
QString ConfigFile::excludeFileFromSystem()
@ -1162,23 +1157,29 @@ std::unique_ptr<QSettings> ConfigFile::settingsWithGroup(const QString &group, Q
void ConfigFile::setupDefaultExcludeFilePaths(ExcludedFiles &excludedFiles)
{
ConfigFile cfg;
QString systemList = cfg.excludeFile(ConfigFile::SystemScope);
QString userList = cfg.excludeFile(ConfigFile::UserScope);
const auto systemList = cfg.excludeFile(ConfigFile::SystemScope);
const auto userList = cfg.excludeFile(ConfigFile::UserScope);
const auto legacyList = cfg.excludeFile(ConfigFile::LegacyScope);
if (!QFile::exists(userList)) {
qCInfo(lcConfigFile) << "User defined ignore list does not exist:" << userList;
if (!QFile::copy(systemList, userList)) {
qCInfo(lcConfigFile) << "Could not copy over default list to:" << userList;
if (QFile::exists(legacyList) && QFile::copy(legacyList, userList)) {
qCInfo(lcConfigFile) << "Migrating legacy list" << legacyList << "to user list" << userList;
} else if (QFile::copy(systemList, userList)) {
qCInfo(lcConfigFile) << "Migrating system list" << legacyList << "to user list" << userList;
}
}
if (!QFile::exists(userList)) {
qCInfo(lcConfigFile) << "Adding system ignore list to csync:" << systemList;
excludedFiles.addExcludeFilePath(systemList);
} else {
qCInfo(lcConfigFile) << "Adding user defined ignore list to csync:" << userList;
excludedFiles.addExcludeFilePath(userList);
return;
}
qCInfo(lcConfigFile) << "Adding user defined ignore list to csync:" << userList;
excludedFiles.addExcludeFilePath(userList);
}
QString ConfigFile::discoveredLegacyConfigPath()

View File

@ -41,7 +41,7 @@ public:
ConfigFile();
enum Scope { UserScope,
SystemScope };
SystemScope, LegacyScope };
[[nodiscard]] QString configPath() const;
[[nodiscard]] QString configFile() const;