Skip to content

Commit

Permalink
feat: allow to set headers on HTTP GET/POST login
Browse files Browse the repository at this point in the history
  • Loading branch information
Bionus committed Apr 25, 2024
1 parent 5a61da9 commit d8ddcfb
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 11 deletions.
9 changes: 7 additions & 2 deletions src/lib/src/auth/http-auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include <utility>


HttpAuth::HttpAuth(QString type, QString url, QList<AuthField*> fields, QString cookie, QString redirectUrl, QString csrfUrl, QStringList csrfFields)
: FieldAuth(std::move(type), std::move(fields)), m_url(std::move(url)), m_cookie(std::move(cookie)), m_redirectUrl(std::move(redirectUrl)), m_csrfUrl(std::move(csrfUrl)), m_csrfFields(std::move(csrfFields))
HttpAuth::HttpAuth(QString type, QString url, QList<AuthField*> fields, QString cookie, QString redirectUrl, QString csrfUrl, QStringList csrfFields, QMap<QString, QString> headers)
: FieldAuth(std::move(type), std::move(fields)), m_url(std::move(url)), m_cookie(std::move(cookie)), m_redirectUrl(std::move(redirectUrl)), m_csrfUrl(std::move(csrfUrl)), m_csrfFields(std::move(csrfFields)), m_headers(std::move(headers))
{}


Expand Down Expand Up @@ -31,3 +31,8 @@ QStringList HttpAuth::csrfFields() const
{
return m_csrfFields;
}

const QMap<QString, QString> &HttpAuth::headers() const
{
return m_headers;
}
5 changes: 4 additions & 1 deletion src/lib/src/auth/http-auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define HTTP_AUTH_H

#include <QList>
#include <QMap>
#include <QString>
#include "auth/field-auth.h"

Expand All @@ -11,19 +12,21 @@ class AuthField;
class HttpAuth : public FieldAuth
{
public:
HttpAuth(QString type, QString url, QList<AuthField*> fields, QString cookie, QString redirectUrl, QString csrfUrl, QStringList csrfFields);
HttpAuth(QString type, QString url, QList<AuthField*> fields, QString cookie, QString redirectUrl, QString csrfUrl, QStringList csrfFields, QMap<QString, QString> headers);
QString url() const;
QString cookie() const;
QString redirectUrl() const;
QString csrfUrl() const;
QStringList csrfFields() const;
const QMap<QString, QString> &headers() const;

private:
QString m_url;
QString m_cookie;
QString m_redirectUrl;
QString m_csrfUrl;
QStringList m_csrfFields;
QMap<QString, QString> m_headers;
};

#endif // HTTP_AUTH_H
17 changes: 15 additions & 2 deletions src/lib/src/js-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ QStringList jsToStringList(const QJSValue &val)
return ret;
}

QVariantMap jsToMap(const QJSValue &val)
QMap<QString, QVariant> jsToMap(const QJSValue &val)
{
QVariantMap ret;
QMap<QString, QVariant> ret;

QJSValueIterator dit(val);
while (dit.hasNext()) {
Expand All @@ -140,3 +140,16 @@ QVariantMap jsToMap(const QJSValue &val)

return ret;
}

QMap<QString, QString> jsToStringMap(const QJSValue &val)
{
QMap<QString, QString> ret;

QJSValueIterator dit(val);
while (dit.hasNext()) {
dit.next();
ret[dit.name()] = dit.value().toString();
}

return ret;
}
3 changes: 2 additions & 1 deletion src/lib/src/js-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ T getPropertyOr(const QJSValue &val, const QString &key, T def)
}

QStringList jsToStringList(const QJSValue &val);
QVariantMap jsToMap(const QJSValue &val);
QMap<QString, QVariant> jsToMap(const QJSValue &val);
QMap<QString, QString> jsToStringMap(const QJSValue &val);

#endif // JS_HELPERS_H
7 changes: 6 additions & 1 deletion src/lib/src/login/http-get-login.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "login/http-get-login.h"
#include <QNetworkRequest>
#include <QUrlQuery>
#include "auth/http-auth.h"
#include "models/site.h"
#include "network/network-manager.h"

Expand All @@ -13,7 +14,11 @@ NetworkReply *HttpGetLogin::getReply(const QUrl &url, const QUrlQuery &query) co
{
QUrl fixedUrl = url;
fixedUrl.setQuery(query);
const QNetworkRequest request(fixedUrl);
QNetworkRequest request(fixedUrl);

for (auto it = m_auth->headers().constBegin(); it != m_auth->headers().constEnd(); ++it) {
request.setRawHeader(it.key().toLatin1(), it.value().toLatin1());
}

return m_manager->get(request);
}
5 changes: 5 additions & 0 deletions src/lib/src/login/http-post-login.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "login/http-post-login.h"
#include <QNetworkRequest>
#include <QUrlQuery>
#include "auth/http-auth.h"
#include "models/site.h"
#include "network/network-manager.h"

Expand All @@ -14,6 +15,10 @@ NetworkReply *HttpPostLogin::getReply(const QUrl &url, const QUrlQuery &query) c
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

for (auto it = m_auth->headers().constBegin(); it != m_auth->headers().constEnd(); ++it) {
request.setRawHeader(it.key().toLatin1(), it.value().toLatin1());
}

QString data = query.query(QUrl::FullyEncoded)
.replace('+', "%2B")
.replace("%20", "+");
Expand Down
3 changes: 2 additions & 1 deletion src/lib/src/models/javascript-source-engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,13 @@ void JavaScriptSourceEngine::load()
const QString url = auth.property("url").toString();
const QString cookie = checkType == "cookie" ? check.property("key").toString() : QString();
const QString redirectUrl = checkType == "redirect" ? check.property("url").toString() : QString();
const QMap<QString, QString> &headers = jsToStringMap(check.property("headers"));

const QJSValue &csrf = auth.property("csrf");
const QString csrfUrl = csrf.isObject() ? csrf.property("url").toString() : QString();
const QStringList csrfFields = csrf.isObject() ? jsToStringList(csrf.property("fields")) : QStringList();

ret = new HttpAuth(type, url, fields, cookie, redirectUrl, csrfUrl, csrfFields);
ret = new HttpAuth(type, url, fields, cookie, redirectUrl, csrfUrl, csrfFields, headers);
} else {
const int maxPage = checkType == "max_page" ? check.property("value").toInt() : 0;
ret = new UrlAuth(type, fields, maxPage);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/tests/src/auth/auth-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ TEST_CASE("Auth")
QScopedPointer<AuthConstField> constField(new AuthConstField("key", "val"));
QList<AuthField*> fields { textField.data(), constField.data() };

HttpAuth auth("post", "https://www.google.com", fields, "cookie", "/index.php", "/login", QStringList { "csrf" });
HttpAuth auth("post", "https://www.google.com", fields, "cookie", "/index.php", "/login", {"csrf"}, {{"User-Agent", "Test"}});

REQUIRE(auth.type() == QString("post"));
REQUIRE(auth.name() == QString("post"));
Expand All @@ -38,6 +38,7 @@ TEST_CASE("Auth")
REQUIRE(auth.redirectUrl() == QString("/index.php"));
REQUIRE(auth.csrfUrl() == QString("/login"));
REQUIRE(auth.csrfFields() == QStringList("csrf"));
REQUIRE(auth.headers() == QMap<QString, QString>{{"User-Agent", "Test"}});

REQUIRE(auth.settingFields().count() == 1);
REQUIRE(auth.settingFields().first().id == textField->id());
Expand Down
4 changes: 2 additions & 2 deletions src/lib/tests/src/login/http-login-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void testLogin(const QString &type, const QString &url, Login::Result expected,
manager->setCookieJar(new QNetworkCookieJar(manager));

QList<AuthField*> fields;
HttpAuth auth(type, "/login", fields, "test_cookie", "", "", QStringList());
HttpAuth auth(type, "/login", fields, "test_cookie", "", "", {}, {});
T login(&auth, site, manager, site->settings());

REQUIRE(login.isTestable());
Expand Down Expand Up @@ -55,7 +55,7 @@ TEST_CASE("HttpLogin")
SECTION("NonTestable")
{
QList<AuthField*> fields;
HttpAuth auth("url", "", fields, "", "", "", QStringList());
HttpAuth auth("url", "", fields, "", "", "", {}, {});
HttpGetLogin login(&auth, site, &accessManager, site->settings());

REQUIRE(!login.isTestable());
Expand Down
5 changes: 5 additions & 0 deletions src/sites/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ interface IHttpAuth {
*/
fields: IAuthField[];

/**
* Additional HTTP headers to pass to the login request.
*/
headers?: Record<string, string>;

/**
* Optional URL to load to get any CSRF token from the form.
*/
Expand Down

0 comments on commit d8ddcfb

Please sign in to comment.