185 lines
7.5 KiB
C++
185 lines
7.5 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
* SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
|
|
*/
|
|
#ifndef ACCOUNTS_ACCOUNT_PRIVATE_H
|
|
#define ACCOUNTS_ACCOUNT_PRIVATE_H
|
|
|
|
#include "account.h"
|
|
#include "actions_p.h"
|
|
#include "keys.h"
|
|
|
|
#include <QDateTime>
|
|
#include <QHash>
|
|
#include <QObject>
|
|
#include <QSet>
|
|
#include <QString>
|
|
#include <QUuid>
|
|
#include <QVector>
|
|
|
|
#include <functional>
|
|
#include <optional>
|
|
|
|
namespace accounts
|
|
{
|
|
class AccountStoragePrivate;
|
|
class AccountPrivate
|
|
{
|
|
public:
|
|
QUuid id(void) const;
|
|
std::optional<uint> offset(void) const;
|
|
QString name(void) const;
|
|
QString token(void) const;
|
|
QString issuer(void) const;
|
|
quint64 counter(void) const;
|
|
QDateTime epoch(void) const;
|
|
uint timeStep(void) const;
|
|
Account::Hash hash(void) const;
|
|
Account::Algorithm algorithm(void) const;
|
|
int tokenLength(void) const;
|
|
bool checksum(void) const;
|
|
public:
|
|
static QString toFullName(const QString &name, const QString &issuer);
|
|
explicit AccountPrivate(const std::function<Account*(AccountPrivate*)> &account,
|
|
AccountStoragePrivate *storage, Dispatcher *dispatcher,
|
|
const QUuid id, const QString &name, const QString &issuer,
|
|
const secrets::EncryptedSecret &secret, uint tokenLength,
|
|
quint64 counter, const std::optional<uint> offset, bool addChecksum);
|
|
explicit AccountPrivate(const std::function<Account*(AccountPrivate*)> &account,
|
|
AccountStoragePrivate *storage, Dispatcher *dispatcher,
|
|
const QUuid id, const QString &name, const QString &issuer,
|
|
const secrets::EncryptedSecret &secret, uint tokenLength,
|
|
const QDateTime &epoch, uint timeStep, Account::Hash hash);
|
|
void recompute(void);
|
|
void setCounter(quint64 counter);
|
|
void remove(void);
|
|
void acceptCounter(quint64 counter);
|
|
void acceptTotpTokens(const QString &token, const QString &nextToken, const QDateTime &validFrom,
|
|
const QDateTime &validUntil);
|
|
void acceptHotpTokens(const QString &token, const QString &nextToken, quint64 validUntil);
|
|
void markForRemoval(void);
|
|
bool isStillAlive(void) const;
|
|
private:
|
|
void setToken(const QString &token);
|
|
void shiftTokens(void);
|
|
private:
|
|
Q_DISABLE_COPY(AccountPrivate);
|
|
Q_DECLARE_PUBLIC(Account);
|
|
Account * const q_ptr;
|
|
private:
|
|
AccountStoragePrivate *m_storage;
|
|
Dispatcher * m_actions;
|
|
bool m_is_still_alive;
|
|
const Account::Algorithm m_algorithm;
|
|
const QUuid m_id;
|
|
private:
|
|
QString m_token;
|
|
QString m_nextToken;
|
|
QDateTime m_nextTotpValidFrom;
|
|
QDateTime m_nextTotpValidUntil;
|
|
quint64 m_nextCounter;
|
|
private:
|
|
const QString m_name;
|
|
const QString m_issuer;
|
|
const secrets::EncryptedSecret m_secret;
|
|
const uint m_tokenLength;
|
|
quint64 m_counter;
|
|
const std::optional<uint> m_offset;
|
|
const bool m_checksum;
|
|
const QDateTime m_epoch;
|
|
const qint64 m_timeStep;
|
|
const Account::Hash m_hash;
|
|
};
|
|
|
|
class AccountStoragePrivate
|
|
{
|
|
public:
|
|
explicit AccountStoragePrivate(const SettingsProvider &settings,
|
|
AccountSecret *secret, AccountStorage *storage, Dispatcher *dispatcher);
|
|
void dispose(const std::function<void(Null*)> &handler);
|
|
void acceptDisposal(void);
|
|
void unlock(const std::function<void(RequestAccountPassword*)> &handler);
|
|
void load(const std::function<void(LoadAccounts*)> &handler);
|
|
QVector<QString> activeAccounts(void) const;
|
|
bool isStillOpen(void) const;
|
|
bool contains(const QString &account) const;
|
|
SettingsProvider settings(void) const;
|
|
bool isAccountStillAvailable(const QString &account) const;
|
|
Account * get(const QString &account) const;
|
|
AccountSecret *secret(void) const;
|
|
void removeAccounts(const QSet<QString> &accountNames);
|
|
void acceptAccountRemoval(const QString &accountName);
|
|
Account * acceptHotpAccount(const QUuid id, const QString &name, const QString &issuer,
|
|
const secrets::EncryptedSecret &secret, uint tokenLength,
|
|
quint64 counter, const std::optional<uint> offset, bool checksum);
|
|
Account * acceptTotpAccount(const QUuid id, const QString &name, const QString &issuer,
|
|
const secrets::EncryptedSecret &secret, uint tokenLength,
|
|
uint timeStep, const QDateTime &epoch, Account::Hash hash);
|
|
bool addHotp(const std::function<void(SaveHotp*)> &handler,
|
|
const QString &name, const QString &issuer,
|
|
const QString &secret, uint tokenLength,
|
|
quint64 counter, const std::optional<uint> offset, bool checksum);
|
|
bool addTotp(const std::function<void(SaveTotp*)> &handler,
|
|
const QString &name, const QString &issuer,
|
|
const QString &secret, uint tokenLength,
|
|
uint timeStep, const QDateTime &epoch, Account::Hash hash);
|
|
void notifyLoaded(void);
|
|
bool isLoaded(void) const;
|
|
void notifyError(void);
|
|
void clearError(void);
|
|
bool hasError(void) const;
|
|
private:
|
|
bool validateGenericNewToken(const QString &name, const QString &issuer,
|
|
const QString &secret, uint tokenLength) const;
|
|
std::optional<secrets::EncryptedSecret> encrypt(const QString &secret) const;
|
|
QUuid generateId(const QString &name) const;
|
|
private:
|
|
Q_DECLARE_PUBLIC(AccountStorage);
|
|
Q_DISABLE_COPY(AccountStoragePrivate);
|
|
AccountStorage * const q_ptr;
|
|
private:
|
|
bool m_is_loaded;
|
|
bool m_has_error;
|
|
bool m_is_still_open;
|
|
Dispatcher * const m_actions;
|
|
const SettingsProvider m_settings;
|
|
AccountSecret * m_secret;
|
|
private:
|
|
QSet<QUuid> m_ids;
|
|
QHash<QString, QUuid> m_names;
|
|
QHash<QUuid, Account*> m_accounts;
|
|
QHash<QUuid, AccountPrivate*> m_accountsPrivate;
|
|
};
|
|
|
|
class HandleCounterUpdate: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit HandleCounterUpdate(AccountPrivate *account, AccountStoragePrivate *storage,
|
|
quint64 counter, SaveHotp *job, QObject *parent = nullptr);
|
|
private:
|
|
bool m_accept_on_finish;
|
|
const quint64 m_counter;
|
|
AccountPrivate * const m_account;
|
|
AccountStoragePrivate * const m_storage;
|
|
private Q_SLOTS:
|
|
void rejected(void);
|
|
void finished(void);
|
|
};
|
|
|
|
class HandleTokenUpdate: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit HandleTokenUpdate(AccountPrivate *account, ComputeHotp *job, QObject *parent = nullptr);
|
|
explicit HandleTokenUpdate(AccountPrivate *account, ComputeTotp *job, QObject *parent = nullptr);
|
|
private:
|
|
AccountPrivate * const m_account;
|
|
private Q_SLOTS:
|
|
void totp(const QString &otp, const QString &nextOtp, const QDateTime &validFrom, const QDateTime &validUntil);
|
|
void hotp(const QString &otp, const QString &nextOtp, quint64 validUntil);
|
|
};
|
|
}
|
|
|
|
#endif
|