tpasswordprovider.cpp - sailfish-safe - Sailfish frontend for safe(1)
 (HTM) git clone git://git.z3bra.org/sailfish-safe.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tpasswordprovider.cpp (4002B)
       ---
            1 /*
            2  *   Copyright (C) 2018  Daniel Vrátil <dvratil@kde.org>
            3  *                 2021  Willy Goiffon <contact@z3bra.org>
            4  *
            5  *   This program is free software; you can redistribute it and/or modify
            6  *   it under the terms of the GNU Library General Public License as
            7  *   published by the Free Software Foundation; either version 2, or
            8  *   (at your option) any later version.
            9  *
           10  *   This program is distributed in the hope that it will be useful,
           11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
           12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           13  *   GNU General Public License for more details
           14  *
           15  *   You should have received a copy of the GNU Library General Public
           16  *   License along with this program; if not, write to the
           17  *   Free Software Foundation, Inc.,
           18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
           19  */
           20 
           21 #include "passwordprovider.h"
           22 #include "settings.h"
           23 #include "safe.h"
           24 
           25 #include <QClipboard>
           26 #include <QGuiApplication>
           27 #include <QDir>
           28 #include <QDebug>
           29 
           30 namespace {
           31 
           32 static const auto PasswordTimeoutUpdateInterval = 100;
           33 
           34 
           35 #define SAFE_DIR "SAFE_DIR"
           36 #define SAFE_SOCK "SAFE_SOCK"
           37 
           38 }
           39 
           40 PasswordProvider::PasswordProvider(const QString &path, QObject *parent)
           41     : QObject(parent)
           42     , mPath(path)
           43 {}
           44 
           45 
           46 PasswordProvider::~PasswordProvider()
           47 {}
           48 
           49 bool PasswordProvider::isValid() const
           50 {
           51     return !mPassword.isNull();
           52 }
           53 
           54 QString PasswordProvider::password() const
           55 {
           56     return mPassword;
           57 }
           58 
           59 void PasswordProvider::setPassword(const QString &password)
           60 {
           61     qGuiApp->clipboard()->setText(password, QClipboard::Clipboard);
           62 
           63     if (qGuiApp->clipboard()->supportsSelection()) {
           64         qGuiApp->clipboard()->setText(password, QClipboard::Selection);
           65     }
           66 
           67     mPassword = password;
           68     Q_EMIT validChanged();
           69     Q_EMIT passwordChanged();
           70 
           71     mTimeout = defaultTimeout();
           72     Q_EMIT timeoutChanged();
           73     mTimer.start();
           74 }
           75 
           76 void PasswordProvider::expirePassword()
           77 {
           78     removePasswordFromClipboard(mPassword);
           79 
           80     mPassword.clear();
           81     mTimer.stop();
           82     Q_EMIT validChanged();
           83     Q_EMIT passwordChanged();
           84 
           85     // Delete the provider, it's no longer needed
           86     deleteLater();
           87 }
           88 
           89 void PasswordProvider::requestPassword()
           90 {
           91     setError({});
           92     mPassword.clear();
           93     mTimer.stop();
           94     Q_EMIT validChanged();
           95     Q_EMIT passwordChanged();
           96 
           97     auto *job = Safe::decrypt(mPath);
           98     connect(job, &Safe::DecryptTask::finished,
           99         this, [this, job]() {
          100             if (job->error()) {
          101                 qWarning() << "Failed to unlock safe: " << job->errorString();
          102                 setError(job->errorString());
          103                 return;
          104             }
          105         // .split() always return one argument, so it's used here to remove
          106         // trailing \n if any, or keep the whole content otherwise
          107         const QStringList lines = job->content().split(QLatin1Char('\n'));
          108         setPassword(lines[0]);
          109         qDebug() << "requestPassword() got: " << lines[0];
          110     });
          111 
          112     mTimer.setInterval(PasswordTimeoutUpdateInterval);
          113     connect(&mTimer, &QTimer::timeout,
          114             this, [this]() {
          115                 mTimeout -= mTimer.interval();
          116                 Q_EMIT timeoutChanged();
          117                 if (mTimeout == 0) {
          118                     expirePassword();
          119                 }
          120             });
          121 }
          122 
          123 int PasswordProvider::timeout() const
          124 {
          125     return mTimeout;
          126 }
          127 
          128 int PasswordProvider::defaultTimeout() const
          129 {
          130     return Settings::self()->expirationTimeout() * 1000;
          131 }
          132 
          133 QString PasswordProvider::error() const
          134 {
          135     return mError;
          136 }
          137 
          138 bool PasswordProvider::hasError() const
          139 {
          140     return !mError.isNull();
          141 }
          142 
          143 void PasswordProvider::setError(const QString &error)
          144 {
          145     mError = error;
          146     Q_EMIT errorChanged();
          147 }
          148 
          149 void PasswordProvider::cancel()
          150 {
          151     setError(tr("Cancelled by user."));
          152 }
          153 
          154 void PasswordProvider::removePasswordFromClipboard(const QString &password)
          155 {
          156     // Clear the WS clipboard itself
          157     const auto clipboard = qGuiApp->clipboard();
          158     if (clipboard->text() == password) {
          159         clipboard->clear();
          160     }
          161 }