Add processing of the url placeholders

This commit is contained in:
frostasm 2017-10-14 15:41:45 +03:00
parent 1374c68274
commit 5e0df62d7a
4 changed files with 128 additions and 14 deletions

View File

@ -755,23 +755,28 @@ QString Entry::resolvePlaceholder(const QString& str) const
{
QString result = str;
const QList<QString> keyList = attributes()->keys();
for (const QString& key : keyList) {
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
QString k = key;
const UrlPlaceholderType placeholderType = urlPlaceholderType(str);
if (placeholderType != UrlPlaceholderType::NotUrl) {
return resolveUrlPlaceholder(url(), placeholderType);
} else {
const QList<QString> keyList = attributes()->keys();
for (const QString& key : keyList) {
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
QString k = key;
if (!EntryAttributes::isDefaultAttribute(key)) {
cs = Qt::CaseSensitive;
k.prepend("{S:");
} else {
k.prepend("{");
}
if (!EntryAttributes::isDefaultAttribute(key)) {
cs = Qt::CaseSensitive;
k.prepend("{S:");
} else {
k.prepend("{");
}
k.append("}");
if (result.compare(k,cs)==0) {
result.replace(result,attributes()->value(key));
break;
k.append("}");
if (result.compare(k,cs)==0) {
result.replace(result,attributes()->value(key));
break;
}
}
}
@ -829,3 +834,62 @@ QString Entry::resolveUrl(const QString& url) const
// No valid http URL's found
return QString("");
}
QString Entry::resolveUrlPlaceholder(const QString &strUrl, Entry::UrlPlaceholderType placeholderType) const
{
QUrl qurl(strUrl);
if (!qurl.isValid())
return QString();
switch (placeholderType) {
case UrlPlaceholderType::FullUrl:
return strUrl;
case UrlPlaceholderType::WithoutScheme:
return qurl.toString(QUrl::RemoveScheme | QUrl::FullyDecoded);
case UrlPlaceholderType::Scheme:
return qurl.scheme();
case UrlPlaceholderType::Host:
return qurl.host();
case UrlPlaceholderType::Port:
return QString::number(qurl.port());
case UrlPlaceholderType::Path:
return qurl.path();
case UrlPlaceholderType::Query:
return qurl.query();
case UrlPlaceholderType::Fragment:
return qurl.fragment();
case UrlPlaceholderType::UserInfo:
return qurl.userInfo();
case UrlPlaceholderType::UserName:
return qurl.userName();
case UrlPlaceholderType::Password:
return qurl.password();
default:
Q_ASSERT(false);
break;
}
return QString();
}
Entry::UrlPlaceholderType Entry::urlPlaceholderType(const QString &placeholder) const
{
static const QMap<QString, UrlPlaceholderType> urlPlaceholders {
{ QStringLiteral("{URL}"), UrlPlaceholderType::FullUrl },
{ QStringLiteral("{URL:RMVSCM}"), UrlPlaceholderType::WithoutScheme },
{ QStringLiteral("{URL:WITHOUTSCHEME}"), UrlPlaceholderType::WithoutScheme },
{ QStringLiteral("{URL:SCM}"), UrlPlaceholderType::Scheme },
{ QStringLiteral("{URL:SCHEME}"), UrlPlaceholderType::Scheme },
{ QStringLiteral("{URL:HOST}"), UrlPlaceholderType::Host },
{ QStringLiteral("{URL:PORT}"), UrlPlaceholderType::Port },
{ QStringLiteral("{URL:PATH}"), UrlPlaceholderType::Path },
{ QStringLiteral("{URL:QUERY}"), UrlPlaceholderType::Query },
{ QStringLiteral("{URL:FRAGMENT}"), UrlPlaceholderType::Fragment },
{ QStringLiteral("{URL:USERINFO}"), UrlPlaceholderType::UserInfo },
{ QStringLiteral("{URL:USERNAME}"), UrlPlaceholderType::UserName },
{ QStringLiteral("{URL:PASSWORD}"), UrlPlaceholderType::Password }
};
UrlPlaceholderType result = urlPlaceholders.value(placeholder.toUpper(), UrlPlaceholderType::NotUrl);
return result;
}

View File

@ -134,6 +134,21 @@ public:
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
enum class UrlPlaceholderType {
NotUrl,
FullUrl,
WithoutScheme,
Scheme,
Host,
Port,
Path,
Query,
Fragment,
UserInfo,
UserName,
Password,
};
/**
* Creates a duplicate of this entry except that the returned entry isn't
* part of any group.
@ -145,6 +160,8 @@ public:
QString maskPasswordPlaceholders(const QString& str) const;
QString resolveMultiplePlaceholders(const QString& str) const;
QString resolvePlaceholder(const QString& str) const;
QString resolveUrlPlaceholder(const QString& url, UrlPlaceholderType placeholderType) const;
UrlPlaceholderType urlPlaceholderType(const QString& placeholder) const;
QString resolveUrl(const QString& url) const;
/**

View File

@ -158,3 +158,35 @@ void TestEntry::testResolveUrl()
delete entry;
}
void TestEntry::testResolveUrlPlaceholders()
{
Entry* entry = new Entry();
entry->setUrl("https://user:pw@keepassxc.org:80/path/example.php?q=e&s=t+2#fragment");
QString rmvscm("//user:pw@keepassxc.org:80/path/example.php?q=e&s=t+2#fragment"); // Entry URL without scheme name.
QString scm("https"); // Scheme name of the entry URL.
QString host("keepassxc.org"); // Host component of the entry URL.
QString port("80"); // Port number of the entry URL.
QString path("/path/example.php"); // Path component of the entry URL.
QString query("q=e&s=t+2"); // Query information of the entry URL.
QString userinfo("user:pw"); // User information of the entry URL.
QString username("user"); // User name of the entry URL.
QString password("pw"); // Password of the entry URL.
QString fragment("fragment"); // Password of the entry URL.
QCOMPARE(entry->resolvePlaceholder("{URL:RMVSCM}"), rmvscm);
QCOMPARE(entry->resolvePlaceholder("{URL:WITHOUTSCHEME}"), rmvscm);
QCOMPARE(entry->resolvePlaceholder("{URL:SCM}"), scm);
QCOMPARE(entry->resolvePlaceholder("{URL:SCHEME}"), scm);
QCOMPARE(entry->resolvePlaceholder("{URL:HOST}"), host);
QCOMPARE(entry->resolvePlaceholder("{URL:PORT}"), port);
QCOMPARE(entry->resolvePlaceholder("{URL:PATH}"), path);
QCOMPARE(entry->resolvePlaceholder("{URL:QUERY}"), query);
QCOMPARE(entry->resolvePlaceholder("{URL:USERINFO}"), userinfo);
QCOMPARE(entry->resolvePlaceholder("{URL:USERNAME}"), username);
QCOMPARE(entry->resolvePlaceholder("{URL:PASSWORD}"), password);
QCOMPARE(entry->resolvePlaceholder("{URL:FRAGMENT}"), fragment);
delete entry;
}

View File

@ -32,6 +32,7 @@ private slots:
void testCopyDataFrom();
void testClone();
void testResolveUrl();
void testResolveUrlPlaceholders();
};
#endif // KEEPASSX_TESTENTRY_H