151 lines
5.3 KiB
C++
151 lines
5.3 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
|
|
*/
|
|
#ifndef MODEL_ACCOUNTS_H
|
|
#define MODEL_ACCOUNTS_H
|
|
|
|
#include "input.h"
|
|
#include "../account/account.h"
|
|
#include "../validators/namevalidator.h"
|
|
|
|
#include <QAbstractListModel>
|
|
#include <QByteArray>
|
|
#include <QHash>
|
|
#include <QModelIndex>
|
|
#include <QObject>
|
|
#include <QSortFilterProxyModel>
|
|
#include <QString>
|
|
#include <QValidator>
|
|
#include <QVector>
|
|
|
|
#include <optional>
|
|
|
|
namespace model
|
|
{
|
|
qint64 millisecondsLeftForToken(const QDateTime &epoch, uint timeStep,
|
|
const std::function<qint64(void)> &clock = &QDateTime::currentMSecsSinceEpoch);
|
|
|
|
class AccountView : public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(QString name READ name CONSTANT)
|
|
Q_PROPERTY(QString issuer READ issuer CONSTANT)
|
|
Q_PROPERTY(QString token READ token NOTIFY tokenChanged)
|
|
Q_PROPERTY(quint64 counter READ counter NOTIFY tokenChanged);
|
|
Q_PROPERTY(uint timeStep READ timeStep CONSTANT);
|
|
Q_PROPERTY(bool isHotp READ isHotp CONSTANT);
|
|
Q_PROPERTY(bool isTotp READ isTotp CONSTANT);
|
|
public:
|
|
explicit AccountView(accounts::Account *model, QObject *parent = nullptr);
|
|
QString name(void) const;
|
|
QString issuer(void) const;
|
|
QString token(void) const;
|
|
uint timeStep(void) const;
|
|
quint64 counter(void) const;
|
|
bool isHotp(void) const;
|
|
bool isTotp(void) const;
|
|
Q_INVOKABLE qint64 millisecondsLeftForToken(void) const;
|
|
Q_SIGNALS:
|
|
void tokenChanged(void);
|
|
void remove(void);
|
|
void recompute(void);
|
|
void advanceCounter(quint64 by = 1ULL);
|
|
void setCounter(quint64 value);
|
|
private:
|
|
accounts::Account * const m_model;
|
|
};
|
|
|
|
class SimpleAccountListModel: public QAbstractListModel
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged);
|
|
Q_PROPERTY(bool error READ error WRITE setError NOTIFY errorChanged);
|
|
public:
|
|
enum NonStandardRoles {
|
|
AccountRole = Qt::ItemDataRole::UserRole
|
|
};
|
|
Q_ENUM(NonStandardRoles)
|
|
enum TOTPAlgorithms {
|
|
Sha1, Sha256, Sha512
|
|
};
|
|
Q_ENUM(TOTPAlgorithms)
|
|
private:
|
|
static accounts::Account::Hash toHash(const TOTPAlgorithms value);
|
|
public:
|
|
explicit SimpleAccountListModel(accounts::AccountStorage *storage, QObject *parent = nullptr);
|
|
Q_INVOKABLE void addAccount(model::AccountInput *input);
|
|
Q_INVOKABLE bool isAccountStillAvailable(const QString &name, const QString &issuer) const;
|
|
Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
QHash<int, QByteArray> roleNames(void) const override;
|
|
public:
|
|
bool loaded(void) const;
|
|
bool error(void) const;
|
|
void setError(bool markAsError);
|
|
Q_SIGNALS:
|
|
void loadedChanged(void);
|
|
void errorChanged(void);
|
|
private Q_SLOTS:
|
|
void added(const QString &account);
|
|
void removed(const QString &removed);
|
|
void handleError(void);
|
|
private:
|
|
AccountView * createView(const QString &name);
|
|
void populate(const QString &name, AccountView *account);
|
|
private:
|
|
accounts::AccountStorage * const m_storage;
|
|
private:
|
|
bool m_has_error;
|
|
QVector<QString> m_index;
|
|
QHash<QString, AccountView*> m_accounts;
|
|
};
|
|
|
|
class SortedAccountsListModel: public QSortFilterProxyModel
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit SortedAccountsListModel(QObject *parent = nullptr);
|
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
|
protected:
|
|
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
|
};
|
|
|
|
class AccountNameValidator: public QValidator
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(QString issuer READ issuer WRITE setIssuer NOTIFY issuerChanged)
|
|
Q_PROPERTY(model::SimpleAccountListModel * accounts READ accounts WRITE setAccounts NOTIFY accountsChanged);
|
|
Q_PROPERTY(
|
|
bool validateAvailability
|
|
READ validateAvailability
|
|
WRITE setValidateAvailability
|
|
NOTIFY validateAvailabilityChanged
|
|
);
|
|
public:
|
|
explicit AccountNameValidator(QObject *parent = nullptr);
|
|
QValidator::State validate(QString &input, int &pos) const override;
|
|
void fixup(QString &input) const override;
|
|
bool validateAvailability(void) const;
|
|
void setValidateAvailability(bool enabled);
|
|
QString issuer(void) const;
|
|
void setIssuer(const QString &issuer);
|
|
SimpleAccountListModel * accounts(void) const;
|
|
void setAccounts(SimpleAccountListModel *accounts);
|
|
Q_SIGNALS:
|
|
void issuerChanged(void);
|
|
void accountsChanged(void);
|
|
void validateAvailabilityChanged(void);
|
|
private:
|
|
bool m_validateAvailability;
|
|
std::optional<QString> m_issuer;
|
|
SimpleAccountListModel * m_accounts;
|
|
const validators::NameValidator m_delegate;
|
|
};
|
|
}
|
|
|
|
Q_DECLARE_METATYPE(model::AccountView *);
|
|
Q_DECLARE_METATYPE(model::SimpleAccountListModel *);
|
|
|
|
#endif
|