sailfish-safe

Sailfish frontend for safe(1)
git clone git://git.z3bra.org/sailfish-safe.git
Log | Files | Refs | README | LICENSE

commit 282985f0b34b09b001e0a3c14fe8361c4d17282c
parent b68489e813410b19b4a5f766be76d92ade4d449f
Author: Daniel Vrátil <dvratil@kde.org>
Date:   Thu, 14 Feb 2019 22:19:54 +0100

Make password expiration customizable

Diffstat:
Mharbour-passilic.pro | 10+++++++---
Mqml/components/GlobalPullDownMenu.qml | 4++++
Aqml/pages/SettingsPage.qml | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.cpp | 9+++++++++
Msrc/passwordprovider.cpp | 4++--
Msrc/passwordsmodel.cpp | 3+++
Asrc/scopeguard.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/settings.cpp | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/settings.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtranslations/harbour-passilic-zh_cn.ts | 16++++++++++++++++
Mtranslations/harbour-passilic.ts | 16++++++++++++++++
11 files changed, 286 insertions(+), 5 deletions(-)

diff --git a/harbour-passilic.pro b/harbour-passilic.pro @@ -22,7 +22,8 @@ SOURCES += \ src/passwordprovider.cpp \ src/passwordsmodel.cpp \ src/passwordsortproxymodel.cpp \ - 3rdparty/kitemmodels/kdescendantsproxymodel.cpp + 3rdparty/kitemmodels/kdescendantsproxymodel.cpp \ + src/settings.cpp HEADERS += \ @@ -32,7 +33,9 @@ HEADERS += \ src/passwordprovider.h \ src/passwordsmodel.h \ src/passwordsortproxymodel.h \ - 3rdparty/kitemmodels/kdescendantsproxymodel.h + 3rdparty/kitemmodels/kdescendantsproxymodel.h \ + src/settings.h \ + src/scopeguard.h DISTFILES += \ qml/harbour-passilic.qml \ @@ -48,7 +51,8 @@ DISTFILES += \ translations/*.ts \ harbour-passilic.desktop \ qml/pages/SearchPage.qml \ - qml/components/PasswordDelegate.qml + qml/components/PasswordDelegate.qml \ + qml/pages/SettingsPage.qml OTHER_FILES += \ README.md diff --git a/qml/components/GlobalPullDownMenu.qml b/qml/components/GlobalPullDownMenu.qml @@ -25,6 +25,10 @@ PullDownMenu { onClicked: app.pageStack.push(Qt.resolvedUrl("../pages/AboutPage.qml")) } MenuItem { + text: qsTr("Settings") + onClicked: app.pageStack.push(Qt.resolvedUrl("../pages/SettingsPage.qml")) + } + MenuItem { text: qsTr("Search") onClicked: app.pageStack.push(searchPage) } diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 Daniel Vrátil <dvratil@kde.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import QtQuick 2.0 +import harbour.passilic 1.0 + +Dialog { + id: settingsDialog + + onAccepted: { + Settings.expirationTimeout = expirationSlider.sliderValue + Settings.save() + } + + DialogHeader { + id: dialogHeader + width: parent.width + } + + SilicaFlickable { + anchors { + left: parent.left + right: parent.right + top: dialogHeader.bottom + bottom: parent.bottom + leftMargin: Theme.horizontalPageMargin + rightMargin: Theme.horizontalPageMargin + } + + Column { + spacing: Theme.paddingMedium + width: parent.width + + Label { + text: qsTr("Password expiration") + } + Slider { + id: expirationSlider + width: parent.width + + minimumValue: 10 + maximumValue: 120 + stepSize: 1 + //: number of seconds + valueText: qsTr("%1 s").arg(sliderValue) + + Component.onCompleted: value = Settings.expirationTimeout + } + } + + VerticalScrollDecorator { + flickable: parent + } + } +} diff --git a/src/main.cpp b/src/main.cpp @@ -19,6 +19,8 @@ #include "passwordfiltermodel.h" #include "passwordsortproxymodel.h" #include "imageprovider.h" +#include "scopeguard.h" +#include "settings.h" #include <QQuickView> #include <QQmlEngine> @@ -41,10 +43,17 @@ int main(int argc, char *argv[]) app->setOrganizationName(QObject::tr("Daniel Vrátil")); QScopedPointer<QQuickView> view(SailfishApp::createView()); + const auto settingsGuard = scopeGuard([]() { + Settings::destroy(); + }); qmlRegisterType<PasswordsModel>("harbour.passilic", 1, 0, "PasswordsModel"); qmlRegisterType<PasswordFilterModel>("harbour.passilic", 1, 0, "PasswordFilterModel"); qmlRegisterType<PasswordSortProxyModel>("harbour.passilic", 1, 0, "PasswordSortProxyModel"); + qmlRegisterSingletonType<Settings>("harbour.passilic", 1, 0, "Settings", + [](QQmlEngine *, QJSEngine *) -> QObject* { + return Settings::self(); + }); addImageProvider(view->engine(), QStringLiteral("passIcon")); addImageProvider(view->engine(), QStringLiteral("passImage")); diff --git a/src/passwordprovider.cpp b/src/passwordprovider.cpp @@ -18,6 +18,7 @@ */ #include "passwordprovider.h" +#include "settings.h" #include <QProcess> #include <QStandardPaths> @@ -26,7 +27,6 @@ namespace { -static const auto PasswordTimeout = 45 * 1000; static const auto PasswordTimeoutUpdateInterval = 100; } @@ -168,7 +168,7 @@ int PasswordProvider::timeout() const int PasswordProvider::defaultTimeout() const { - return PasswordTimeout; + return Settings::self()->expirationTimeout() * 1000; } QString PasswordProvider::error() const diff --git a/src/passwordsmodel.cpp b/src/passwordsmodel.cpp @@ -41,6 +41,9 @@ public: ~Node() { + if (provider) { + provider->expirePassword(); + } qDeleteAll(children); } diff --git a/src/scopeguard.h b/src/scopeguard.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 Daniel Vrátil <dvratil@kde.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef SCOPEGUARD_H +#define SCOPEGUARD_H + +template<typename Func> +class ScopeGuard +{ +public: + ScopeGuard(Func &&func) + : mFunc(std::move(func)) + {} + + ScopeGuard(ScopeGuard<Func> &&) = default; + ScopeGuard<Func> &operator=(ScopeGuard<Func> &&) = default; + ScopeGuard(const ScopeGuard<Func> &) = delete; + ScopeGuard<Func> &operator=(const ScopeGuard<Func> &) = delete; + + ~ScopeGuard() + { + mFunc(); + } + +private: + Func mFunc; +}; + +template<typename Func> +ScopeGuard<Func> scopeGuard(Func &&func) +{ + return ScopeGuard<Func>(std::move(func)); +} + +#endif // SCOPEGUARD_H diff --git a/src/settings.cpp b/src/settings.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019 Daniel Vrátil <dvratil@kde.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "settings.h" + +std::unique_ptr<Settings> Settings::kInstance = {}; + +Settings::Settings(): QObject() {} + +Settings *Settings::self() +{ + if (!kInstance) { + kInstance.reset(new Settings); + } + return kInstance.get(); +} + +void Settings::destroy() +{ + kInstance.reset(); +} + +void Settings::save() +{ + mSettings.sync(); +} + +#define IMPLEMENT_OPTION(type, lc, uc, name, defValue) \ + void Settings::set##uc(type val) { \ + if (lc() != val) { \ + mSettings.setValue(QStringLiteral(name), val); \ + Q_EMIT lc##Changed(); \ + } \ + } \ + type Settings::lc() const { \ + return mSettings.value(QStringLiteral(name), defValue).value<type>(); \ + } + +IMPLEMENT_OPTION(int, expirationTimeout, ExpirationTimeout, "expirationTimeout", 45) + + +#undef IMPLEMENT_OPTION diff --git a/src/settings.h b/src/settings.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 Daniel Vrátil <dvratil@kde.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifndef SETTINGS_H +#define SETTINGS_H + +#include <QObject> +#include <QSettings> + +#include <memory> + +#define DECLARE_OPTION(type, lc, uc) \ + private: Q_PROPERTY(type lc READ lc WRITE set##uc NOTIFY lc##Changed) \ + public: type lc() const; \ + public: void set##uc(type val); \ + Q_SIGNALS: void lc##Changed(); + + +class Settings : public QObject +{ + Q_OBJECT +public: + static Settings *self(); + static void destroy(); + + Q_INVOKABLE void save(); + + DECLARE_OPTION(int, expirationTimeout, ExpirationTimeout) + +private: + explicit Settings(); + QSettings mSettings; + + static std::unique_ptr<Settings> kInstance; +}; + +#undef DECLARE_OPTION + +#endif // SETTINGS_H diff --git a/translations/harbour-passilic-zh_cn.ts b/translations/harbour-passilic-zh_cn.ts @@ -38,6 +38,10 @@ <source>Search</source> <translation type="unfinished"></translation> </message> + <message> + <source>Settings</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PasswordDelegate</name> @@ -95,4 +99,16 @@ <translation>Daniel Vrátil</translation> </message> </context> +<context> + <name>SettingsPage</name> + <message> + <source>Password expiration</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 s</source> + <extracomment>number of seconds</extracomment> + <translation type="unfinished"></translation> + </message> +</context> </TS> diff --git a/translations/harbour-passilic.ts b/translations/harbour-passilic.ts @@ -38,6 +38,10 @@ <source>Search</source> <translation type="unfinished"></translation> </message> + <message> + <source>Settings</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>PasswordDelegate</name> @@ -95,4 +99,16 @@ <translation type="unfinished"></translation> </message> </context> +<context> + <name>SettingsPage</name> + <message> + <source>Password expiration</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 s</source> + <extracomment>number of seconds</extracomment> + <translation type="unfinished"></translation> + </message> +</context> </TS>