File indexing completed on 2024-06-23 05:14:19

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     utils/validation.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
0006     SPDX-FileCopyrightText: 2022 g10 Code GmbH
0007     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #include <config-kleopatra.h>
0013 
0014 #include "validation.h"
0015 
0016 #include <utils/multivalidator.h>
0017 
0018 #include <KEmailAddress>
0019 
0020 #include "kleopatra_debug.h"
0021 
0022 #include <QRegularExpression>
0023 
0024 using namespace Kleo;
0025 
0026 namespace
0027 {
0028 
0029 template<class Validator>
0030 class TrimmingValidator : public Validator
0031 {
0032 public:
0033     using Validator::Validator;
0034 
0035     QValidator::State validate(QString &str, int &pos) const override
0036     {
0037         auto trimmed = str.trimmed();
0038         auto posCopy = pos;
0039         return Validator::validate(trimmed, posCopy);
0040     }
0041 };
0042 
0043 template<class Validator>
0044 class EmptyIsAcceptableValidator : public Validator
0045 {
0046 public:
0047     using Validator::Validator;
0048 
0049     QValidator::State validate(QString &str, int &pos) const override
0050     {
0051         if (str.isEmpty()) {
0052             return QValidator::Acceptable;
0053         }
0054         return Validator::validate(str, pos);
0055     }
0056 };
0057 
0058 class EMailValidator : public QValidator
0059 {
0060 public:
0061     EMailValidator()
0062         : QValidator{}
0063     {
0064     }
0065 
0066     State validate(QString &str, int &pos) const override
0067     {
0068         Q_UNUSED(pos)
0069         if (KEmailAddress::isValidSimpleAddress(str)) {
0070             return Acceptable;
0071         }
0072         return Intermediate;
0073     }
0074 };
0075 
0076 std::shared_ptr<QValidator> regularExpressionValidator(Validation::Flags flags, const QString &regexp)
0077 {
0078     if (flags & Validation::Required) {
0079         return std::make_shared<TrimmingValidator<QRegularExpressionValidator>>(QRegularExpression{regexp});
0080     } else {
0081         return std::make_shared<TrimmingValidator<EmptyIsAcceptableValidator<QRegularExpressionValidator>>>(QRegularExpression{regexp});
0082     }
0083 }
0084 
0085 }
0086 
0087 std::shared_ptr<QValidator> Validation::email(Flags flags)
0088 {
0089     if (flags & Required) {
0090         return std::make_shared<TrimmingValidator<EMailValidator>>();
0091     } else {
0092         return std::make_shared<TrimmingValidator<EmptyIsAcceptableValidator<EMailValidator>>>();
0093     }
0094 }
0095 
0096 std::shared_ptr<QValidator> Validation::email(const QString &addRX, Flags flags)
0097 {
0098     return MultiValidator::create({email(flags), regularExpressionValidator(flags, addRX)});
0099 }
0100 
0101 std::shared_ptr<QValidator> Validation::pgpName(Flags flags)
0102 {
0103     // this regular expression is modeled after gnupg/g10/keygen.c:ask_user_id:
0104     static const QString name_rx{QLatin1StringView{"[^0-9<>][^<>@]{4,}"}};
0105     return regularExpressionValidator(flags, name_rx);
0106 }
0107 
0108 std::shared_ptr<QValidator> Validation::pgpName(const QString &addRX, Flags flags)
0109 {
0110     return MultiValidator::create({pgpName(flags), regularExpressionValidator(flags, addRX)});
0111 }
0112 
0113 std::shared_ptr<QValidator> Validation::simpleName(Flags flags)
0114 {
0115     static const QString name_rx{QLatin1StringView{"[^<>@]*"}};
0116     return std::shared_ptr<QValidator>{regularExpressionValidator(flags, name_rx)};
0117 }
0118 
0119 std::shared_ptr<QValidator> Validation::simpleName(const QString &additionalRegExp, Flags flags)
0120 {
0121     return MultiValidator::create({simpleName(flags), regularExpressionValidator(flags, additionalRegExp)});
0122 }