mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
Make use of QKeyChain if its there.
This commit is contained in:
parent
22128781be
commit
5d958a4c07
6 changed files with 140 additions and 24 deletions
|
@ -123,10 +123,10 @@ void CredentialStore::fetchCredentials()
|
|||
if( !_user.isEmpty() ) {
|
||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||
// job->setAutoDelete( false );
|
||||
job->setKey( _user );
|
||||
job->setKey( keyChainKey( cfgFile.ownCloudUrl() ) );
|
||||
|
||||
connect( job, SIGNAL(finished(QKeychain::Job*)), this,
|
||||
SLOT(slotKeyChainFinished(QKeychain::Job*)));
|
||||
SLOT(slotKeyChainReadFinished(QKeychain::Job*)));
|
||||
job->start();
|
||||
}
|
||||
#else
|
||||
|
@ -156,7 +156,21 @@ void CredentialStore::fetchCredentials()
|
|||
}
|
||||
}
|
||||
|
||||
void CredentialStore::slotKeyChainFinished(QKeychain::Job* job)
|
||||
void CredentialStore::reset()
|
||||
{
|
||||
_state = NotFetched;
|
||||
_user = QString::null;
|
||||
_passwd = QString::null;
|
||||
_tries = 0;
|
||||
}
|
||||
|
||||
QString CredentialStore::keyChainKey( const QString& url ) const
|
||||
{
|
||||
QString key = _user+QLatin1Char(':')+url;
|
||||
return key;
|
||||
}
|
||||
|
||||
void CredentialStore::slotKeyChainReadFinished(QKeychain::Job* job)
|
||||
{
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
ReadPasswordJob *pwdJob = static_cast<ReadPasswordJob*>(job);
|
||||
|
@ -188,11 +202,71 @@ QByteArray CredentialStore::basicAuthHeader() const
|
|||
return data;
|
||||
}
|
||||
|
||||
void CredentialStore::setCredentials( const QString& user, const QString& pwd )
|
||||
void CredentialStore::setCredentials( const QString& url, const QString& user, const QString& pwd, bool noLocalPwd )
|
||||
{
|
||||
_passwd = pwd;
|
||||
_user = user;
|
||||
_state = Ok;
|
||||
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
MirallConfigFile::CredentialType t;
|
||||
t = MirallConfigFile::KeyChain;
|
||||
if( noLocalPwd ) t = MirallConfigFile::User;
|
||||
|
||||
switch( t ) {
|
||||
case MirallConfigFile::User:
|
||||
deleteKeyChainCredential(keyChainKey( url ));
|
||||
break;
|
||||
case MirallConfigFile::KeyChain: {
|
||||
// Set password in KeyChain
|
||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||
// job->setAutoDelete( false );
|
||||
job->setKey( keyChainKey( url ) );
|
||||
job->setTextData(pwd);
|
||||
|
||||
connect( job, SIGNAL(finished(QKeychain::Job*)), this,
|
||||
SLOT(slotKeyChainWriteFinished(QKeychain::Job*)));
|
||||
job->start();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// unsupported.
|
||||
break;
|
||||
}
|
||||
#else
|
||||
(void) url;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CredentialStore::slotKeyChainWriteFinished( QKeychain::Job *job )
|
||||
{
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
WritePasswordJob *pwdJob = static_cast<WritePasswordJob*>(job);
|
||||
if( pwdJob ) {
|
||||
if( pwdJob->error() ) {
|
||||
qDebug() << "Error with keychain: " << pwdJob->errorString();
|
||||
} else {
|
||||
qDebug() << "Successfully stored password for user " << _user;
|
||||
// Try to remove password formerly stored in the config file.
|
||||
MirallConfigFile cfgFile;
|
||||
cfgFile.clearPasswordFromConfig();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Error: KeyChain Write Password Job failed!";
|
||||
}
|
||||
#else
|
||||
(void) job;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Called if a user chooses to not store the password locally.
|
||||
void CredentialStore::deleteKeyChainCredential( const QString& key )
|
||||
{
|
||||
// Start the remove job, do not care so much about the result.
|
||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||
job->setKey( key );
|
||||
job->start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -96,13 +96,14 @@ public:
|
|||
* @param user - the user name
|
||||
* @param password - the password.
|
||||
*/
|
||||
void setCredentials( const QString&, const QString& );
|
||||
void setCredentials( const QString&, const QString&, const QString&, bool );
|
||||
|
||||
/**
|
||||
* @brief canTryAgain - check if another try to get credentials makes sense.
|
||||
*/
|
||||
bool canTryAgain();
|
||||
|
||||
void reset();
|
||||
signals:
|
||||
/**
|
||||
* @brief fetchCredentialsFinished
|
||||
|
@ -115,10 +116,13 @@ signals:
|
|||
void fetchCredentialsFinished(bool);
|
||||
|
||||
protected slots:
|
||||
void slotKeyChainFinished(QKeychain::Job* job);
|
||||
void slotKeyChainReadFinished( QKeychain::Job* );
|
||||
void slotKeyChainWriteFinished( QKeychain::Job* );
|
||||
|
||||
private:
|
||||
explicit CredentialStore(QObject *parent = 0);
|
||||
void deleteKeyChainCredential( const QString& );
|
||||
QString keyChainKey( const QString& ) const;
|
||||
|
||||
static CredentialStore *_instance;
|
||||
static CredState _state;
|
||||
|
|
|
@ -147,18 +147,43 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
|
|||
pwd.clear();
|
||||
}
|
||||
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
// Password is stored to QtKeyChain now by default in CredentialStore
|
||||
// The CredentialStore calls clearPasswordFromConfig after the creds
|
||||
// were successfully wiritten to delete the passwd entry from config.
|
||||
qDebug() << "Going to delete the password from settings file.";
|
||||
#else
|
||||
// store password into settings file.
|
||||
QByteArray pwdba = pwd.toUtf8();
|
||||
settings.setValue( QLatin1String("passwd"), QVariant(pwdba.toBase64()) );
|
||||
#endif
|
||||
settings.setValue( QLatin1String("nostoredpassword"), QVariant(skipPwd) );
|
||||
settings.sync();
|
||||
// check the perms, only read-write for the owner.
|
||||
QFile::setPermissions( file, QFile::ReadOwner|QFile::WriteOwner );
|
||||
|
||||
// inform the credential store about the password change.
|
||||
CredentialStore::instance()->setCredentials( user, pwd );
|
||||
CredentialStore::instance()->setCredentials( cloudsUrl, user, pwd, skipPwd );
|
||||
|
||||
}
|
||||
|
||||
// This method is called after the password was successfully stored into the
|
||||
// QKeyChain in CredentialStore.
|
||||
void MirallConfigFile::clearPasswordFromConfig( const QString& connection )
|
||||
{
|
||||
const QString file = configFile();
|
||||
QString con( defaultConnection() );
|
||||
if( !connection.isEmpty() )
|
||||
con = connection;
|
||||
|
||||
QSettings settings( file, QSettings::IniFormat);
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
settings.beginGroup( con ); // FIXME: Connection!
|
||||
settings.remove(QLatin1String("passwd"));
|
||||
settings.remove(QLatin1String("password"));
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
// set the url, called from redirect handling.
|
||||
void MirallConfigFile::setOwnCloudUrl( const QString& connection, const QString & url )
|
||||
{
|
||||
|
@ -315,11 +340,16 @@ int MirallConfigFile::pollTimerExceedFactor( const QString& connection ) const
|
|||
return pte;
|
||||
}
|
||||
|
||||
MirallConfigFile::CredentialType MirallConfigFile::credentialType() const
|
||||
MirallConfigFile::CredentialType MirallConfigFile::credentialType( const QString& connection) const
|
||||
{
|
||||
QString con; /* ( connection ); */
|
||||
/* if( connection.isEmpty() ) */ con = defaultConnection();
|
||||
QString con( connection );
|
||||
if( connection.isEmpty() ) con = defaultConnection();
|
||||
|
||||
CredentialType ct = Settings;
|
||||
#ifdef WITH_QTKEYCHAIN
|
||||
// In case QtKeyChain is there, use it mandatory.
|
||||
ct = KeyChain;
|
||||
#endif
|
||||
|
||||
QSettings settings( configFile(), QSettings::IniFormat );
|
||||
settings.setIniCodec( "UTF-8" );
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
QByteArray caCerts();
|
||||
void setCaCerts( const QByteArray& );
|
||||
|
||||
CredentialType credentialType() const;
|
||||
CredentialType credentialType(const QString &connection = QString::null) const;
|
||||
|
||||
QString ownCloudVersion() const;
|
||||
void setOwnCloudVersion( const QString& );
|
||||
|
@ -107,7 +107,7 @@ public:
|
|||
protected:
|
||||
QString ownCloudPasswd( const QString& connection = QString() ) const;
|
||||
QString ownCloudUser( const QString& connection = QString() ) const;
|
||||
|
||||
void clearPasswordFromConfig( const QString& connect = QString() );
|
||||
private:
|
||||
QVariant getValue(const QString& param, const QString& group) const;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/owncloudinfo.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/credentialstore.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QProcess>
|
||||
|
@ -391,15 +392,20 @@ void OwncloudSetupWizard::setupLocalSyncFolder()
|
|||
|
||||
if( localFolderOk ) {
|
||||
_remoteFolder = Theme::instance()->defaultServerFolder();
|
||||
if( !_remoteFolder.isEmpty() && createRemoteFolder( _remoteFolder ) ) {
|
||||
// the creation started successfully, does not mean it will work
|
||||
qDebug() << "Creation of remote folder started successfully.";
|
||||
} else {
|
||||
// the start of the http request failed.
|
||||
_ocWizard->appendToResultWidget(tr("Creation of remote folder %1 could not be started.").arg(_remoteFolder));
|
||||
qDebug() << "Creation of remote folder failed.";
|
||||
}
|
||||
CredentialStore::instance()->reset();
|
||||
connect( CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(int)),
|
||||
this, SLOT(slotCreateRemoteFolder(int)));
|
||||
CredentialStore::instance()->fetchCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudSetupWizard::slotCreateRemoteFolder(int res)
|
||||
{
|
||||
disconnect(CredentialStore::instance(), SIGNAL(fetchCredentialsFinished(bool)));
|
||||
if( createRemoteFolder( _remoteFolder ) ) {
|
||||
qDebug() << "Started remote folder creation ok";
|
||||
} else {
|
||||
_ocWizard->appendToResultWidget(tr("Creation of remote folder %1 could not be started.").arg(_remoteFolder));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,14 +456,14 @@ void OwncloudSetupWizard::finalizeSetup( bool success )
|
|||
}
|
||||
_ocWizard->appendToResultWidget( QLatin1String(" "));
|
||||
_ocWizard->appendToResultWidget( QLatin1String("<p><font color=\"green\"><b>")
|
||||
+ tr("Succesfully connected to %1!")
|
||||
.arg(Theme::instance()->appName())
|
||||
+ QLatin1String("</b></font></p>"));
|
||||
+ tr("Succesfully connected to %1!")
|
||||
.arg(Theme::instance()->appName())
|
||||
+ QLatin1String("</b></font></p>"));
|
||||
_ocWizard->appendToResultWidget( tr("Press Finish to permanently accept this connection."));
|
||||
} else {
|
||||
_ocWizard->appendToResultWidget(QLatin1String("<p><font color=\"red\">")
|
||||
+ tr("Connection to %1 could not be established. Please check again.")
|
||||
.arg(Theme::instance()->appName())
|
||||
.arg(Theme::instance()->appName())
|
||||
+ QLatin1String("</font></p>"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ protected slots:
|
|||
void slotConnectToOCUrl( const QString& );
|
||||
void slotCreateOCLocalhost();
|
||||
|
||||
void slotCreateRemoteFolder(int);
|
||||
|
||||
private slots:
|
||||
void slotOwnCloudFound( const QString&, const QString&, const QString&, const QString& );
|
||||
void slotNoOwnCloudFound( QNetworkReply* );
|
||||
|
|
Loading…
Reference in a new issue