kutils: allow storing and retreiving of temporary passwords via KPasswdStore

the implementation supports it and KIO now uses that feature

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-05 07:22:39 +03:00
parent 972b231e4a
commit 3716b1ffe5
7 changed files with 63 additions and 26 deletions

View file

@ -303,7 +303,7 @@ void SlaveBase::dispatchLoop()
int ret = -1;
if (d->appConnection.hasTaskAvailable() || d->appConnection.waitForIncomingTask(ms)) {
// dispatch application messages
int cmd;
int cmd = 0;
QByteArray data;
ret = d->appConnection.read(&cmd, data);
@ -578,6 +578,14 @@ void SlaveBase::reparseConfiguration()
bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
{
KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore);
passwdstore->openStore();
if (checkCachedAuthentication(info)) {
return true;
}
if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) {
return false;
}
@ -587,9 +595,6 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
AuthInfo dlgInfo(info);
KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore);
// assemble dialog-flags
KPasswordDialog::KPasswordDialogFlags dialogFlags;
@ -605,9 +610,8 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
dialogFlags |= KPasswordDialog::ShowUsernameLine;
}
// If store is not enabled and the caller explicitly requested for it,
// do not show the keep password checkbox.
if (dlgInfo.keepPassword && !passwdstore->cacheOnly()) {
// If the caller explicitly requested for it do not show the keep password checkbox.
if (dlgInfo.keepPassword) {
dialogFlags |= KPasswordDialog::ShowKeepPassword;
}
@ -636,9 +640,8 @@ bool SlaveBase::openPasswordDialog(AuthInfo& info, const QString &errorMsg)
dlg->setUsernameReadOnly(true);
}
if (!passwdstore->cacheOnly()) {
dlg->setKeepPassword(true);
}
// even if the store is not open passwords can be temporary stored
dlg->setKeepPassword(true);
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) {
dlg->setDomain(dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).toString());
@ -948,16 +951,21 @@ bool SlaveBase::checkCachedAuthentication(AuthInfo &info)
{
KPasswdStore* passwdstore = d->passwdStore();
Q_ASSERT(passwdstore);
if (!passwdstore->isOpen() && !passwdstore->cacheOnly()) {
// let it fail the first time, if authorization is really required openPasswordDialog()
// will open the store and call this method
return false;
}
const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong();
QByteArray authkey = authInfoKey(info);
if (passwdstore->hasPasswd(authkey, windowId)) {
const QString passwd = passwdstore->getPasswd(authkey, windowId);
QString passwd = passwdstore->getPasswd(authkey, windowId);
if (!passwd.isEmpty()) {
info = authInfoFromData(passwd.toLatin1());
return true;
}
authkey = authInfoKey2(info);
if (passwdstore->hasPasswd(authkey, windowId)) {
const QString passwd = passwdstore->getPasswd(authkey, windowId);
passwd = passwdstore->getPasswd(authkey, windowId);
if (!passwd.isEmpty()) {
info = authInfoFromData(passwd.toLatin1());
return true;
}

View file

@ -32,6 +32,23 @@ KPasswdStoreModule::~KPasswdStoreModule()
qDeleteAll(m_stores);
}
bool KPasswdStoreModule::isOpen(const QByteArray &cookie, const QString &storeid)
{
KPasswdStoreMap::const_iterator it = m_stores.begin();
while (it != m_stores.end()) {
if (it.key() != cookie) {
it++;
continue;
}
KPasswdStoreImpl *store = it.value();
if (store->storeID() == storeid) {
return store->isOpen();
}
it++;
}
return false;
}
bool KPasswdStoreModule::openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid)
{
KPasswdStoreMap::iterator it = m_stores.begin();

View file

@ -34,6 +34,7 @@ public:
~KPasswdStoreModule();
public Q_SLOTS:
Q_SCRIPTABLE bool isOpen(const QByteArray &cookie, const QString &storeid);
Q_SCRIPTABLE bool openStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0);
Q_SCRIPTABLE bool closeStore(const QByteArray &cookie, const QString &storeid, const qlonglong windowid = 0);

View file

@ -91,6 +91,11 @@ QString KPasswdStoreImpl::storeID() const
return m_storeid;
}
bool KPasswdStoreImpl::isOpen() const
{
return (m_passwdtimer.elapsed() < m_timeout);
}
bool KPasswdStoreImpl::openStore(const qlonglong windowid)
{
if (m_cacheonly) {

View file

@ -35,6 +35,7 @@ public:
QString storeID() const;
bool isOpen() const;
bool openStore(const qlonglong windowid);
bool closeStore();

View file

@ -97,6 +97,16 @@ void KPasswdStore::setStoreID(const QString &id)
d->storeid = id;
}
bool KPasswdStore::isOpen() const
{
d->ensureInterface();
KLockFile klockfile(getLockName(d->cookie, d->storeid));
klockfile.lock();
QDBusReply<bool> result = d->interface->call("isOpen", d->cookie, d->storeid);
klockfile.unlock();
return result.value();
}
bool KPasswdStore::openStore(const qlonglong windowid)
{
d->ensureInterface();
@ -120,14 +130,9 @@ bool KPasswdStore::cacheOnly() const
return result.value();
}
bool KPasswdStore::hasPasswd(const QByteArray &key, const qlonglong windowid)
{
return !getPasswd(key, windowid).isEmpty();
}
QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid)
{
if (!openStore(windowid)) {
if (!openStore(windowid) && !cacheOnly()) {
return QString();
}
QDBusReply<QString> result = d->interface->call("getPasswd", d->cookie, d->storeid, key, windowid);
@ -136,7 +141,7 @@ QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid)
bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd, const qlonglong windowid)
{
if (!openStore(windowid)) {
if (!openStore(windowid) && !cacheOnly()) {
return false;
}
QDBusReply<bool> result = d->interface->call("storePasswd", d->cookie, d->storeid, key, passwd, windowid);

View file

@ -70,6 +70,11 @@ public:
*/
void setStoreID(const QString &id);
/*!
@brief Returns true if the store is open, false otherwise
*/
bool isOpen() const;
/*!
@brief Opens the store by asking for the password for it and returns
@p true if the store is open, @p false otherwise
@ -88,11 +93,6 @@ public:
*/
bool cacheOnly() const;
/*!
@brief Returns @p true if there is password for the given @p key in the
password store, @p false otherwise
*/
bool hasPasswd(const QByteArray &key, const qlonglong windowid = 0);
/*!
@brief Retrieves password for the given @p key from the password store
*/