File indexing completed on 2024-04-28 05:50:05
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #ifndef ACCOUNTS_ACCOUNT_H 0006 #define ACCOUNTS_ACCOUNT_H 0007 0008 #include <QDateTime> 0009 #include <QObject> 0010 #include <QScopedPointer> 0011 #include <QSettings> 0012 #include <QString> 0013 #include <QThread> 0014 #include <QUuid> 0015 #include <QVector> 0016 0017 #include <functional> 0018 #include <optional> 0019 0020 #include "keys.h" 0021 0022 namespace accounts 0023 { 0024 using PersistenceAction = std::function<void(QSettings&)>; 0025 using SettingsProvider = std::function<void(const PersistenceAction&)>; 0026 0027 class AccountPrivate; 0028 class Account: public QObject 0029 { 0030 Q_OBJECT 0031 public: 0032 enum Algorithm { 0033 Totp, 0034 Hotp 0035 }; 0036 Q_ENUM(Algorithm) 0037 enum Hash { 0038 Sha1, Sha256, Sha512 0039 }; 0040 Q_ENUM(Hash) 0041 explicit Account(AccountPrivate *d, QObject *parent = nullptr); 0042 QString name(void) const; 0043 QString token(void) const; 0044 QString issuer(void) const; 0045 quint64 counter(void) const; 0046 QDateTime epoch(void) const; 0047 uint timeStep(void) const; 0048 std::optional<uint> offset(void) const; 0049 int tokenLength(void) const; 0050 bool checksum(void) const; 0051 Hash hash(void) const; 0052 Algorithm algorithm(void) const; 0053 public Q_SLOTS: 0054 void remove(void); 0055 void recompute(void); 0056 void setCounter(quint64 counter); 0057 void advanceCounter(quint64 by = 1ULL); 0058 Q_SIGNALS: 0059 void tokenChanged(const QString &otp); 0060 void removed(void); 0061 void updated(void); 0062 private: 0063 QScopedPointer<AccountPrivate> m_dptr; 0064 Q_DECLARE_PRIVATE_D(m_dptr, Account) 0065 }; 0066 0067 class AccountStoragePrivate; 0068 class AccountStorage: public QObject 0069 { 0070 Q_OBJECT 0071 public: 0072 static AccountStorage * open(const SettingsProvider &settings, AccountSecret *secret = nullptr, 0073 QObject *parent = nullptr); 0074 explicit AccountStorage(const SettingsProvider &settings, QThread *thread, AccountSecret *secret = nullptr, 0075 QObject *parent = nullptr); 0076 void removeAll(const QSet<Account*> &accounts) const; 0077 bool isAccountStillAvailable(const QString &fullName) const; 0078 bool isAccountStillAvailable(const QString &name, const QString &issuer) const; 0079 bool contains(const QString &fullName) const; 0080 bool contains(const QString &name, const QString &issuer) const; 0081 Account * get(const QString &fullName) const; 0082 Account * get(const QString &name, const QString &issuer) const; 0083 AccountSecret * secret(void) const; 0084 QVector<QString> accounts(void) const; 0085 void dispose(void); 0086 void addHotp(const QString &name, 0087 const QString &issuer, 0088 const QString &secret, 0089 uint tokenLength = 6U, 0090 quint64 counter = 0ULL, 0091 const std::optional<uint> offset = std::nullopt, 0092 bool addChecksum = false); 0093 void addTotp(const QString &name, 0094 const QString &issuer, 0095 const QString &secret, 0096 uint tokenLength = 6U, 0097 uint timeStep = 30U, 0098 const QDateTime &epoch = QDateTime::fromMSecsSinceEpoch(0), 0099 Account::Hash hash = Account::Hash::Sha1); 0100 void clearError(void); 0101 bool hasError(void) const; 0102 bool isLoaded(void) const; 0103 Q_SIGNALS: 0104 void added(const QString &fullName); 0105 void removed(const QString &fullName); 0106 void error(void); 0107 void loaded(void); 0108 void disposed(void); 0109 private Q_SLOTS: 0110 void unlock(void); 0111 void load(void); 0112 void accountRemoved(void); 0113 void handleDisposal(void); 0114 void handleError(void); 0115 void handleLoaded(void); 0116 void handleHotp(const QUuid id, const QString &name, const QString &issuer, 0117 const QByteArray &secret, const QByteArray &nonce, uint tokenLength, 0118 quint64 counter, bool fixedTruncation, uint offset, bool checksum); 0119 void handleTotp(const QUuid id, const QString &name, const QString &issuer, 0120 const QByteArray &secret, const QByteArray &nonce, uint tokenLength, 0121 uint timeStep, const QDateTime &epoch, Account::Hash hash); 0122 private: 0123 QScopedPointer<AccountStoragePrivate> m_dptr; 0124 Q_DECLARE_PRIVATE_D(m_dptr, AccountStorage) 0125 }; 0126 } 0127 0128 #endif