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 }