Skip to content

Commit

Permalink
Implement mechanism to remember password across sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Jan 4, 2025
1 parent 955bac7 commit 865d73e
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 36 deletions.
113 changes: 99 additions & 14 deletions src/core/webdavconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,26 +83,104 @@ void WebdavConnection::setPassword( const QString &password )
mWebdavConnection.clearAccessCache();
}

void WebdavConnection::setStorePassword( bool storePassword )
{
if ( mStorePassword == storePassword )
return;

mStorePassword = storePassword;
emit storePasswordChanged();
}

void WebdavConnection::checkStoredPassword()
{
mStoredPassword.clear();

if ( !mUrl.isEmpty() && !mUsername.isEmpty() )
{
QgsAuthManager *authManager = QgsApplication::instance()->authManager();
const QgsAuthMethodConfigsMap configs = authManager->availableAuthMethodConfigs();
for ( const QgsAuthMethodConfig &config : configs )
QgsAuthMethodConfigsMap configs = authManager->availableAuthMethodConfigs();
for ( QgsAuthMethodConfig &config : configs )
{
if ( config.uri() == mUrl && config.config( QStringLiteral( "username" ) ) == mUsername )
qDebug() << config.name();
qDebug() << config.uri();
if ( config.uri() == mUrl )
{
mStoredPassword = config.config( QStringLiteral( "password" ) );
authManager->loadAuthenticationConfig( config.id(), config, true );
if ( config.config( QStringLiteral( "username" ) ) == mUsername )
{
mStoredPassword = config.config( QStringLiteral( "password" ) );
}
}
}
}

emit isPasswordStoredChanged();
}

void WebdavConnection::applyStoredPassword()
{
QgsAuthManager *authManager = QgsApplication::instance()->authManager();
QgsAuthMethodConfigsMap configs = authManager->availableAuthMethodConfigs();
if ( mStorePassword )
{
if ( !mPassword.isEmpty() )
{
bool found = false;
for ( QgsAuthMethodConfig &config : configs )
{
if ( config.uri() == mUrl )
{
authManager->loadAuthenticationConfig( config.id(), config, true );
if ( config.config( QStringLiteral( "username" ) ) == mUsername )
{
if ( config.config( QStringLiteral( "password" ) ) != mPassword )
{
config.setConfig( "password", mPassword );
authManager->updateAuthenticationConfig( config );

mStoredPassword = mPassword;
emit isPasswordStoredChanged();
}

found = true;
break;
}
}
}

if ( !found )
{
QgsAuthMethodConfig config( QStringLiteral( "Basic" ) );
config.setName( QStringLiteral( "WebDAV created on %1" ).arg( QDateTime::currentDateTime().toString() ) );
config.setUri( mUrl );
config.setConfig( "username", mUsername );
config.setConfig( "password", mPassword );
authManager->storeAuthenticationConfig( config );

mStoredPassword = mPassword;
emit isPasswordStoredChanged();
}
}
}
else
{
for ( const QgsAuthMethodConfig &config : configs )
{
if ( config.uri() == mUrl && config.config( QStringLiteral( "username" ) ) == mUsername )
{
authManager->removeAuthenticationConfig( config.id() );
}
}

if ( !mStoredPassword.isEmpty() )
{
mStoredPassword = mPassword;
emit isPasswordStoredChanged();
}
}
}

void WebdavConnection::setupConnection()
{
QUrl connectionUrl( mUrl );
Expand Down Expand Up @@ -133,6 +211,8 @@ void WebdavConnection::processDirParserFinished()
{
if ( !list.isEmpty() )
{
applyStoredPassword();

mAvailablePaths << QStringLiteral( "/" );
for ( const QWebdavItem &item : list )
{
Expand All @@ -151,20 +231,25 @@ void WebdavConnection::processDirParserFinished()
}
else if ( mIsImportingPath )
{
QDir importLocalDir( mImportLocalPath );
for ( const QWebdavItem &item : list )
if ( !list.isEmpty() )
{
if ( item.isDir() )
{
importLocalDir.mkpath( item.path().mid( mImportRemotePath.size() ) );
}
else
applyStoredPassword();

QDir importLocalDir( mImportLocalPath );
for ( const QWebdavItem &item : list )
{
mImportItems << item.path();
mImportingBytesTotal += item.size();
if ( item.isDir() )
{
importLocalDir.mkpath( item.path().mid( mImportRemotePath.size() ) );
}
else
{
mImportItems << item.path();
mImportingBytesTotal += item.size();
}
}
emit progressChanged();
}
emit progressChanged();

processImportItems();
}
Expand Down
16 changes: 12 additions & 4 deletions src/core/webdavconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ class WebdavConnection : public QObject
Q_PROPERTY( QString url READ url WRITE setUrl NOTIFY urlChanged );
Q_PROPERTY( QString username READ username WRITE setUsername NOTIFY usernameChanged )
Q_PROPERTY( QString password READ password WRITE setPassword NOTIFY passwordChanged )
Q_PROPERTY( bool isPasswordStored READ isPasswordStored NOTIFY isPasswordStoredChanged )

Q_PROPERTY( QStringList availablePaths READ availablePaths NOTIFY availablePathsChanged )
Q_PROPERTY( bool storePassword READ storePassword WRITE setStorePassword NOTIFY storePasswordChanged )

Q_PROPERTY( bool isPasswordStored READ isPasswordStored NOTIFY isPasswordStoredChanged )
Q_PROPERTY( bool isFetchingAvailablePaths READ isFetchingAvailablePaths NOTIFY isFetchingAvailablePathsChanged )
Q_PROPERTY( bool isImportingPath READ isImportingPath NOTIFY isImportingPathChanged )

Q_PROPERTY( QStringList availablePaths READ availablePaths NOTIFY availablePathsChanged )
Q_PROPERTY( double progress READ progress NOTIFY progressChanged )

Q_PROPERTY( QString lastError READ lastError NOTIFY lastErrorChanged )

public:
Expand All @@ -61,6 +61,10 @@ class WebdavConnection : public QObject

void setPassword( const QString &password );

bool storePassword() const { return mStorePassword; }

void setStorePassword( bool storePassword );

bool isPasswordStored() const { return !mStoredPassword.isEmpty(); }

QStringList availablePaths() const { return mIsFetchingAvailablePaths ? QStringList() : mAvailablePaths; }
Expand All @@ -81,10 +85,11 @@ class WebdavConnection : public QObject
void urlChanged();
void usernameChanged();
void passwordChanged();
void storePasswordChanged();
void isPasswordStoredChanged();
void availablePathsChanged();
void isFetchingAvailablePathsChanged();
void isImportingPathChanged();
void availablePathsChanged();
void progressChanged();
void lastErrorChanged();

Expand All @@ -95,12 +100,15 @@ class WebdavConnection : public QObject

private:
void checkStoredPassword();
void applyStoredPassword();
void setupConnection();
void processImportItems();

QString mUrl;
QString mUsername;
QString mPassword;

bool mStorePassword = false;
QString mStoredPassword;

bool mIsFetchingAvailablePaths = false;
Expand Down
33 changes: 15 additions & 18 deletions src/qml/QFieldLocalDataPickerScreen.qml
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,9 @@ Page {
id: webdavConnection

url: importWebdavUrlInput.text
username: importWebdavUserInput.text
password: importWebdavPasswordInput.text
storePassword: importWebdavStorePasswordCheck.checked

onIsImportingPathChanged: {
if (isImportingPath) {
Expand All @@ -727,6 +729,10 @@ Page {
onLastErrorChanged: {
displayToast(qsTr("WebDAV error: ") + lastError);
}

onIsPasswordStoredChanged: {
console.log(isPasswordStored ? "stored" : "not stored");
}
}
}

Expand Down Expand Up @@ -772,39 +778,30 @@ Page {
enabled: !webdavConnectionLoader.item || !webdavConnectionLoader.item.isFetchingAvailablePaths
width: importWebdavUrlLabel.width
placeholderText: qsTr("WebDAV server URL")

onDisplayTextChanged: {
if (webdavConnectionLoader.item) {
webdavConnectionLoader.item.url = displayText;
}
}
}

QfTextField {
id: importWebdavUserInput
enabled: !webdavConnectionLoader.item || !webdavConnectionLoader.item.isFetchingAvailablePaths
width: importWebdavUrlLabel.width
placeholderText: qsTr("User")

onDisplayTextChanged: {
if (webdavConnectionLoader.item) {
webdavConnectionLoader.item.username = displayText;
}
}
}

QfTextField {
id: importWebdavPasswordInput
enabled: !webdavConnectionLoader.item || !webdavConnectionLoader.item.isFetchingAvailablePaths
width: importWebdavUrlLabel.width
placeholderText: qsTr("Password")
placeholderText: text === "" && webdavConnectionLoader.item && webdavConnectionLoader.item.isPasswordStored ? qsTr("Password (leave empty to use remembered)") : qsTr("Password")
echoMode: TextInput.Password
}

onDisplayTextChanged: {
if (webdavConnectionLoader.item) {
webdavConnectionLoader.item.password = text;
}
}
CheckBox {
id: importWebdavStorePasswordCheck
width: importWebdavUrlLabel.width
enabled: !webdavConnectionLoader.item || !webdavConnectionLoader.item.isFetchingAvailablePaths
text: qsTr('Remember password')
font: Theme.defaultFont
checked: true
}

Row {
Expand Down

0 comments on commit 865d73e

Please sign in to comment.