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