File indexing completed on 2024-04-28 05:50:08
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #include "input.h" 0006 0007 #include <QLocale> 0008 0009 static QDateTime DEFAULT_EPOCH_VALUE = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC); 0010 static QString DEFAULT_EPOCH = DEFAULT_EPOCH_VALUE.toString(Qt::ISODate); 0011 static QString DEFAULT_COUNTER = QLocale::c().toString(0ULL); 0012 0013 namespace model 0014 { 0015 0016 static accounts::Account::Hash toHash(AccountInput::TOTPAlgorithm algorithm) 0017 { 0018 switch(algorithm) { 0019 case AccountInput::TOTPAlgorithm::Sha1: 0020 return accounts::Account::Hash::Sha1; 0021 case AccountInput::TOTPAlgorithm::Sha256: 0022 return accounts::Account::Hash::Sha256; 0023 case AccountInput::TOTPAlgorithm::Sha512: 0024 return accounts::Account::Hash::Sha512; 0025 default: 0026 Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown/unsupported TOTP hashing algorithm?"); 0027 return accounts::Account::Hash::Sha1; 0028 } 0029 } 0030 0031 AccountInput::AccountInput(QObject *parent) : 0032 QObject(parent), 0033 m_type(TokenType::Totp), m_name(QString()), m_issuer(QString()), m_secret(QString()), m_tokenLength(6U), 0034 m_timeStep(30U), m_algorithm(TOTPAlgorithm::Sha1), m_epoch(DEFAULT_EPOCH), m_epochValue(DEFAULT_EPOCH_VALUE), 0035 m_checksum(false), m_counter(DEFAULT_COUNTER), m_counterValue(0ULL), m_truncation(std::nullopt) 0036 { 0037 } 0038 0039 void AccountInput::reset(void) 0040 { 0041 setType(TokenType::Totp); 0042 setName(QString()); 0043 setIssuer(QString()); 0044 setSecret(QString()); 0045 setTokenLength(6U); 0046 setTimeStep(30U); 0047 setAlgorithm(TOTPAlgorithm::Sha1); 0048 setEpoch(DEFAULT_EPOCH); 0049 setChecksum(false); 0050 setCounter(0ULL); 0051 setDynamicTruncation(); 0052 } 0053 0054 void AccountInput::createNewAccount(accounts::AccountStorage *storage) const 0055 { 0056 if (!storage) { 0057 Q_ASSERT_X(false, Q_FUNC_INFO, "Storage must be provided"); 0058 return; 0059 } 0060 0061 switch(m_type) { 0062 case Hotp: 0063 storage->addHotp(m_name, m_issuer, m_secret, m_tokenLength, m_counterValue, m_truncation, m_checksum); 0064 break; 0065 case Totp: 0066 storage->addTotp(m_name, m_issuer, m_secret, m_tokenLength, m_timeStep, m_epochValue, toHash(m_algorithm)); 0067 break; 0068 default: 0069 Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown/unsupported token type?"); 0070 } 0071 } 0072 0073 AccountInput::TokenType AccountInput::type(void) const 0074 { 0075 return m_type; 0076 } 0077 0078 void AccountInput::setType(model::AccountInput::TokenType type) 0079 { 0080 if (m_type != type) { 0081 m_type = type; 0082 Q_EMIT typeChanged(); 0083 } 0084 } 0085 0086 QString AccountInput::name(void) const 0087 { 0088 return m_name; 0089 } 0090 0091 void AccountInput::setName(const QString &name) 0092 { 0093 if (m_name != name) { 0094 m_name = name; 0095 Q_EMIT nameChanged(); 0096 } 0097 } 0098 0099 QString AccountInput::issuer(void) const 0100 { 0101 return m_issuer; 0102 } 0103 0104 void AccountInput::setIssuer(const QString &issuer) 0105 { 0106 if (m_issuer != issuer) { 0107 m_issuer = issuer; 0108 Q_EMIT issuerChanged(); 0109 } 0110 } 0111 0112 QString AccountInput::secret(void) const 0113 { 0114 return m_secret; 0115 } 0116 0117 void AccountInput::setSecret(const QString &secret) 0118 { 0119 if (m_secret != secret) { 0120 m_secret = secret; 0121 Q_EMIT secretChanged(); 0122 } 0123 } 0124 0125 uint AccountInput::tokenLength(void) const 0126 { 0127 return m_tokenLength; 0128 } 0129 0130 void AccountInput::setTokenLength(uint tokenLength) 0131 { 0132 if (m_tokenLength != tokenLength) { 0133 m_tokenLength = tokenLength; 0134 Q_EMIT tokenLengthChanged(); 0135 } 0136 } 0137 0138 uint AccountInput::timeStep(void) const 0139 { 0140 return m_timeStep; 0141 } 0142 0143 void AccountInput::setTimeStep(uint timeStep) 0144 { 0145 if (m_timeStep != timeStep) { 0146 m_timeStep = timeStep; 0147 Q_EMIT timeStepChanged(); 0148 } 0149 } 0150 0151 AccountInput::TOTPAlgorithm AccountInput::algorithm(void) const 0152 { 0153 return m_algorithm; 0154 } 0155 0156 void AccountInput::setAlgorithm(model::AccountInput::TOTPAlgorithm algorithm) 0157 { 0158 if (m_algorithm != algorithm) { 0159 m_algorithm = algorithm; 0160 Q_EMIT algorithmChanged(); 0161 } 0162 } 0163 0164 QString AccountInput::epoch(void) const 0165 { 0166 return m_epoch; 0167 } 0168 0169 void AccountInput::setEpoch(const QString &epoch) 0170 { 0171 if (m_epoch != epoch) { 0172 m_epoch = epoch; 0173 m_epochValue = validators::parseDateTime(epoch).value_or(DEFAULT_EPOCH_VALUE); 0174 Q_EMIT epochChanged(); 0175 } 0176 } 0177 0178 bool AccountInput::checksum(void) const 0179 { 0180 return m_checksum; 0181 } 0182 0183 void AccountInput::setChecksum(bool checksum) 0184 { 0185 if (m_checksum != checksum) { 0186 m_checksum = checksum; 0187 Q_EMIT checksumChanged(); 0188 } 0189 } 0190 0191 QString AccountInput::counter(void) const 0192 { 0193 return m_counter; 0194 } 0195 0196 void AccountInput::setCounter(const QString &counter, validators::UnsignedLongValidator *validator) 0197 { 0198 if (!validator) { 0199 Q_ASSERT_X(false, Q_FUNC_INFO, "Validator must be provided"); 0200 return; 0201 } 0202 0203 if (m_counter != counter) { 0204 m_counter = counter; 0205 m_counterValue = validators::parseUnsignedInteger(counter, validator->locale()).value_or(0ULL); 0206 Q_EMIT counterChanged(); 0207 } 0208 } 0209 0210 void AccountInput::setCounter(quint64 counter) 0211 { 0212 if (m_counterValue != counter) { 0213 m_counter.setNum(counter); 0214 m_counterValue = counter; 0215 Q_EMIT counterChanged(); 0216 } 0217 } 0218 0219 uint AccountInput::truncationOffset(void) const 0220 { 0221 return m_truncation.value_or(0U); 0222 } 0223 0224 void AccountInput::setTruncationOffset(uint truncationOffset) 0225 { 0226 if (!m_truncation || *m_truncation != truncationOffset) { 0227 m_truncation = std::optional<uint>(truncationOffset); 0228 Q_EMIT truncationChanged(); 0229 } 0230 } 0231 0232 bool AccountInput::fixedTruncation(void) const 0233 { 0234 return (bool) m_truncation; 0235 } 0236 0237 void AccountInput::setDynamicTruncation(void) 0238 { 0239 if (m_truncation) { 0240 m_truncation = std::nullopt; 0241 Q_EMIT truncationChanged(); 0242 } 0243 } 0244 }