File indexing completed on 2024-04-28 05:50:06
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_PRIVATE_H 0006 #define ACCOUNTS_ACCOUNT_PRIVATE_H 0007 0008 #include "account.h" 0009 #include "actions_p.h" 0010 #include "keys.h" 0011 0012 #include <QDateTime> 0013 #include <QHash> 0014 #include <QObject> 0015 #include <QSet> 0016 #include <QString> 0017 #include <QUuid> 0018 #include <QVector> 0019 0020 #include <functional> 0021 #include <optional> 0022 0023 namespace accounts 0024 { 0025 class AccountStoragePrivate; 0026 class AccountPrivate 0027 { 0028 public: 0029 QUuid id(void) const; 0030 std::optional<uint> offset(void) const; 0031 QString name(void) const; 0032 QString token(void) const; 0033 QString issuer(void) const; 0034 quint64 counter(void) const; 0035 QDateTime epoch(void) const; 0036 uint timeStep(void) const; 0037 Account::Hash hash(void) const; 0038 Account::Algorithm algorithm(void) const; 0039 int tokenLength(void) const; 0040 bool checksum(void) const; 0041 public: 0042 static QString toFullName(const QString &name, const QString &issuer); 0043 explicit AccountPrivate(const std::function<Account*(AccountPrivate*)> &account, 0044 AccountStoragePrivate *storage, Dispatcher *dispatcher, 0045 const QUuid id, const QString &name, const QString &issuer, 0046 const secrets::EncryptedSecret &secret, uint tokenLength, 0047 quint64 counter, const std::optional<uint> offset, bool addChecksum); 0048 explicit AccountPrivate(const std::function<Account*(AccountPrivate*)> &account, 0049 AccountStoragePrivate *storage, Dispatcher *dispatcher, 0050 const QUuid id, const QString &name, const QString &issuer, 0051 const secrets::EncryptedSecret &secret, uint tokenLength, 0052 const QDateTime &epoch, uint timeStep, Account::Hash hash); 0053 void recompute(void); 0054 void setCounter(quint64 counter); 0055 void remove(void); 0056 void acceptCounter(quint64 counter); 0057 void acceptTotpTokens(const QString &token, const QString &nextToken, const QDateTime &validFrom, 0058 const QDateTime &validUntil); 0059 void acceptHotpTokens(const QString &token, const QString &nextToken, quint64 validUntil); 0060 void markForRemoval(void); 0061 bool isStillAlive(void) const; 0062 private: 0063 void setToken(const QString &token); 0064 void shiftTokens(void); 0065 private: 0066 Q_DISABLE_COPY(AccountPrivate) 0067 Q_DECLARE_PUBLIC(Account) 0068 Account * const q_ptr; 0069 private: 0070 AccountStoragePrivate *m_storage; 0071 Dispatcher * m_actions; 0072 bool m_is_still_alive; 0073 const Account::Algorithm m_algorithm; 0074 const QUuid m_id; 0075 private: 0076 QString m_token; 0077 QString m_nextToken; 0078 QDateTime m_nextTotpValidFrom; 0079 QDateTime m_nextTotpValidUntil; 0080 quint64 m_nextCounter; 0081 private: 0082 const QString m_name; 0083 const QString m_issuer; 0084 const secrets::EncryptedSecret m_secret; 0085 const uint m_tokenLength; 0086 quint64 m_counter; 0087 const std::optional<uint> m_offset; 0088 const bool m_checksum; 0089 const QDateTime m_epoch; 0090 const qint64 m_timeStep; 0091 const Account::Hash m_hash; 0092 }; 0093 0094 class AccountStoragePrivate 0095 { 0096 public: 0097 explicit AccountStoragePrivate(const SettingsProvider &settings, 0098 AccountSecret *secret, AccountStorage *storage, Dispatcher *dispatcher); 0099 void dispose(const std::function<void(Null*)> &handler); 0100 void acceptDisposal(void); 0101 void unlock(const std::function<void(RequestAccountPassword*)> &handler); 0102 void load(const std::function<void(LoadAccounts*)> &handler); 0103 QVector<QString> activeAccounts(void) const; 0104 bool isStillOpen(void) const; 0105 bool contains(const QString &account) const; 0106 SettingsProvider settings(void) const; 0107 bool isAccountStillAvailable(const QString &account) const; 0108 Account * get(const QString &account) const; 0109 AccountSecret *secret(void) const; 0110 void removeAccounts(const QSet<QString> &accountNames); 0111 void acceptAccountRemoval(const QString &accountName); 0112 Account * acceptHotpAccount(const QUuid id, const QString &name, const QString &issuer, 0113 const secrets::EncryptedSecret &secret, uint tokenLength, 0114 quint64 counter, const std::optional<uint> offset, bool checksum); 0115 Account * acceptTotpAccount(const QUuid id, const QString &name, const QString &issuer, 0116 const secrets::EncryptedSecret &secret, uint tokenLength, 0117 uint timeStep, const QDateTime &epoch, Account::Hash hash); 0118 bool addHotp(const std::function<void(SaveHotp*)> &handler, 0119 const QString &name, const QString &issuer, 0120 const QString &secret, uint tokenLength, 0121 quint64 counter, const std::optional<uint> offset, bool checksum); 0122 bool addTotp(const std::function<void(SaveTotp*)> &handler, 0123 const QString &name, const QString &issuer, 0124 const QString &secret, uint tokenLength, 0125 uint timeStep, const QDateTime &epoch, Account::Hash hash); 0126 void notifyLoaded(void); 0127 bool isLoaded(void) const; 0128 void notifyError(void); 0129 void clearError(void); 0130 bool hasError(void) const; 0131 private: 0132 bool validateGenericNewToken(const QString &name, const QString &issuer, 0133 const QString &secret, uint tokenLength) const; 0134 std::optional<secrets::EncryptedSecret> encrypt(const QString &secret) const; 0135 QUuid generateId(const QString &name) const; 0136 private: 0137 Q_DECLARE_PUBLIC(AccountStorage) 0138 Q_DISABLE_COPY(AccountStoragePrivate) 0139 AccountStorage * const q_ptr; 0140 private: 0141 bool m_is_loaded; 0142 bool m_has_error; 0143 bool m_is_still_open; 0144 Dispatcher * const m_actions; 0145 const SettingsProvider m_settings; 0146 AccountSecret * m_secret; 0147 private: 0148 QSet<QUuid> m_ids; 0149 QHash<QString, QUuid> m_names; 0150 QHash<QUuid, Account*> m_accounts; 0151 QHash<QUuid, AccountPrivate*> m_accountsPrivate; 0152 }; 0153 0154 class HandleCounterUpdate: public QObject 0155 { 0156 Q_OBJECT 0157 public: 0158 explicit HandleCounterUpdate(AccountPrivate *account, AccountStoragePrivate *storage, 0159 quint64 counter, SaveHotp *job, QObject *parent = nullptr); 0160 private: 0161 bool m_accept_on_finish; 0162 const quint64 m_counter; 0163 AccountPrivate * const m_account; 0164 AccountStoragePrivate * const m_storage; 0165 private Q_SLOTS: 0166 void rejected(void); 0167 void finished(void); 0168 }; 0169 0170 class HandleTokenUpdate: public QObject 0171 { 0172 Q_OBJECT 0173 public: 0174 explicit HandleTokenUpdate(AccountPrivate *account, ComputeHotp *job, QObject *parent = nullptr); 0175 explicit HandleTokenUpdate(AccountPrivate *account, ComputeTotp *job, QObject *parent = nullptr); 0176 private: 0177 AccountPrivate * const m_account; 0178 private Q_SLOTS: 0179 void totp(const QString &otp, const QString &nextOtp, const QDateTime &validFrom, const QDateTime &validUntil); 0180 void hotp(const QString &otp, const QString &nextOtp, quint64 validUntil); 0181 }; 0182 } 0183 0184 #endif