keysmith/src/model/input.cpp

221 lines
5.7 KiB
C++

/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
*/
#include "input.h"
#include <QLocale>
static QDateTime DEFAULT_EPOCH_VALUE = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
static QString DEFAULT_EPOCH = DEFAULT_EPOCH_VALUE.toString(Qt::ISODate);
static QString DEFAULT_COUNTER = QLocale::c().toString(0ULL);
namespace model
{
static accounts::Account::Hash toHash(AccountInput::TOTPAlgorithm algorithm)
{
switch(algorithm) {
case AccountInput::TOTPAlgorithm::Sha1:
return accounts::Account::Hash::Sha1;
case AccountInput::TOTPAlgorithm::Sha256:
return accounts::Account::Hash::Sha256;
case AccountInput::TOTPAlgorithm::Sha512:
return accounts::Account::Hash::Sha512;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown/unsupported TOTP hashing algorithm?");
return accounts::Account::Hash::Sha1;
}
}
AccountInput::AccountInput(QObject *parent) :
QObject(parent),
m_type(TokenType::Totp), m_name(QString()), m_issuer(QString()), m_secret(QString()), m_tokenLength(6U),
m_timeStep(30U), m_algorithm(TOTPAlgorithm::Sha1), m_epoch(DEFAULT_EPOCH), m_epochValue(DEFAULT_EPOCH_VALUE),
m_checksum(false), m_counter(DEFAULT_COUNTER), m_counterValue(0ULL), m_truncation(std::nullopt)
{
}
void AccountInput::createNewAccount(accounts::AccountStorage *storage) const
{
if (!storage) {
Q_ASSERT_X(false, Q_FUNC_INFO, "Storage must be provided");
return;
}
switch(m_type) {
case Hotp:
storage->addHotp(m_name, m_issuer, m_secret, m_tokenLength, m_counterValue, m_truncation, m_checksum);
break;
case Totp:
storage->addTotp(m_name, m_issuer, m_secret, m_tokenLength, m_timeStep, m_epochValue, toHash(m_algorithm));
break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown/unsupported token type?");
}
}
AccountInput::TokenType AccountInput::type(void) const
{
return m_type;
}
void AccountInput::setType(model::AccountInput::TokenType type)
{
if (m_type != type) {
m_type = type;
Q_EMIT typeChanged();
}
}
QString AccountInput::name(void) const
{
return m_name;
}
void AccountInput::setName(const QString &name)
{
if (m_name != name) {
m_name = name;
Q_EMIT nameChanged();
}
}
QString AccountInput::issuer(void) const
{
return m_issuer;
}
void AccountInput::setIssuer(const QString &issuer)
{
if (m_issuer != issuer) {
m_issuer = issuer;
Q_EMIT issuerChanged();
}
}
QString AccountInput::secret(void) const
{
return m_secret;
}
void AccountInput::setSecret(QString &secret)
{
if (m_secret != secret) {
m_secret = secret;
Q_EMIT secretChanged();
}
}
uint AccountInput::tokenLength(void) const
{
return m_tokenLength;
}
void AccountInput::setTokenLength(uint tokenLength)
{
if (m_tokenLength != tokenLength) {
m_tokenLength = tokenLength;
Q_EMIT tokenLengthChanged();
}
}
uint AccountInput::timeStep(void) const
{
return m_timeStep;
}
void AccountInput::setTimeStep(uint timeStep)
{
if (m_timeStep != timeStep) {
m_timeStep = timeStep;
Q_EMIT timeStepChanged();
}
}
AccountInput::TOTPAlgorithm AccountInput::algorithm(void) const
{
return m_algorithm;
}
void AccountInput::setAlgorithm(model::AccountInput::TOTPAlgorithm algorithm)
{
if (m_algorithm != algorithm) {
m_algorithm = algorithm;
Q_EMIT algorithmChanged();
}
}
QString AccountInput::epoch(void) const
{
return m_epoch;
}
void AccountInput::setEpoch(const QString &epoch)
{
if (m_epoch != epoch) {
m_epoch = epoch;
m_epochValue = validators::parseDateTime(epoch).value_or(DEFAULT_EPOCH_VALUE);
Q_EMIT epochChanged();
}
}
bool AccountInput::checksum(void) const
{
return m_checksum;
}
void AccountInput::setChecksum(bool checksum)
{
if (m_checksum != checksum) {
m_checksum = checksum;
Q_EMIT checksumChanged();
}
}
QString AccountInput::counter(void) const
{
return m_counter;
}
void AccountInput::setCounter(const QString &counter, validators::UnsignedLongValidator *validator)
{
if (!validator) {
Q_ASSERT_X(false, Q_FUNC_INFO, "Validator must be provided");
return;
}
if (m_counter != counter) {
m_counter = counter;
m_counterValue = validators::parseUnsignedInteger(counter, validator->locale()).value_or(0ULL);
Q_EMIT counterChanged();
}
}
uint AccountInput::truncationOffset(void) const
{
return m_truncation.value_or(0U);
}
void AccountInput::setTruncationOffset(uint truncationOffset)
{
if (!m_truncation || *m_truncation != truncationOffset) {
m_truncation = std::optional<uint>(truncationOffset);
Q_EMIT truncationChanged();
}
}
bool AccountInput::fixedTruncation(void) const
{
return (bool) m_truncation;
}
void AccountInput::setDynamicTruncation(void)
{
if (m_truncation) {
m_truncation = std::nullopt;
Q_EMIT truncationChanged();
}
}
}