1 /*
2  * Copyright (C) 2017-2018 Matthias Fehring <kontakt@buschmann23.de>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 #include "validatorurl_p.h"
20 #include <QUrl>
21 
22 using namespace Cutelyst;
23 
ValidatorUrl(const QString & field,Constraints constraints,const QStringList & schemes,const Cutelyst::ValidatorMessages & messages,const QString & defValKey)24 ValidatorUrl::ValidatorUrl(const QString &field, Constraints constraints, const QStringList &schemes, const Cutelyst::ValidatorMessages &messages, const QString &defValKey) :
25     ValidatorRule(*new ValidatorUrlPrivate(field, constraints, schemes, messages, defValKey))
26 {
27 }
28 
~ValidatorUrl()29 ValidatorUrl::~ValidatorUrl()
30 {
31 }
32 
validate(Context * c,const ParamsMultiMap & params) const33 ValidatorReturnType ValidatorUrl::validate(Context *c, const ParamsMultiMap &params) const
34 {
35     ValidatorReturnType result;
36 
37     Q_D(const ValidatorUrl);
38 
39     const QString v = value(params);
40 
41     if (!v.isEmpty()) {
42 
43         bool valid = true;
44 
45         QUrl::ParsingMode parsingMode = QUrl::TolerantMode;
46         if (d->constraints.testFlag(StrictParsing)) {
47             parsingMode = QUrl::StrictMode;
48         }
49 
50         QUrl url(v, parsingMode);
51         if (!url.isValid() || url.isEmpty()) {
52             valid = false;
53         }
54 
55         if (valid && (d->constraints.testFlag(NoRelative) || d->constraints.testFlag(WebsiteOnly)) && url.isRelative()) {
56             valid = false;
57         }
58 
59         if (valid && (d->constraints.testFlag(NoLocalFile) || d->constraints.testFlag(WebsiteOnly)) && url.isLocalFile()) {
60             valid = false;
61         }
62 
63         if (valid) {
64             const QStringList schemeList = d->constraints.testFlag(WebsiteOnly) ? QStringList({QStringLiteral("http"), QStringLiteral("https")}) : d->schemes;
65 
66 //            if (d->constraints.testFlag(WebsiteOnly)) {
67 //                if (!schemeList.contains(QStringLiteral("http"), Qt::CaseInsensitive)) {
68 //                    schemeList.append(QStringLiteral("http"));
69 //                }
70 //                if (!schemeList.contains(QStringLiteral("https"), Qt::CaseInsensitive)) {
71 //                    schemeList.append(QStringLiteral("https"));
72 //                }
73 //            }
74 
75             if (!schemeList.empty()) {
76 
77 //                const QStringList sc = schemeList;
78                 bool foundScheme = false;
79                 for (const QString &s : schemeList) {
80                     const QString sl =  s.toLower();
81                     if (url.scheme() == sl) {
82                         foundScheme = true;
83                         break;
84                     }
85                 }
86 
87                 if (!foundScheme) {
88                     valid = false;
89                 }
90             }
91         }
92 
93         if (!valid) {
94             result.errorMessage = validationError(c);
95             qCDebug(C_VALIDATOR, "ValidatorUrl: Validation failed for field %s at %s::%s: not a valid URL", qPrintable(field()), qPrintable(c->controllerName()), qPrintable(c->actionName()));
96         } else {
97             result.value.setValue(url);
98         }
99     } else {
100         defaultValue(c, &result, "ValidatorUrl");
101     }
102 
103     return result;
104 }
105 
genericValidationError(Context * c,const QVariant & errorData) const106 QString ValidatorUrl::genericValidationError(Context *c, const QVariant &errorData) const
107 {
108     QString error;
109     Q_UNUSED(errorData)
110     const QString _label = label(c);
111     if (_label.isEmpty()) {
112         error = c->translate("Cutelyst::ValidatorUrl", "Not a valid URL.");
113     } else {
114         //: %1 will be replaced by the field label
115         error = c->translate("Cutelyst::ValidatorUrl", "The value in the “%1” field is not a valid URL.").arg(_label);
116     }
117     return error;
118 }
119