Fix webserver tests
canonicalFilePath() behavior seems to have changed at some point and not existing files outside the public dir will return a 404 rather than a 403. Ideally the logic would be fixed to first check for the file being outside the public directory, directly returning a 403, then checking if the file exists, return a 404 if not, and lastly check for permissions on the file and return a 403 again of denied. However, that would result in a bigger change. Also, the tests were failing all along if syslog exists but is not readable (code is ok, just bad test) but none of our autotesters seemed to have such a setup till now.
This commit is contained in:
parent
54c7cdcabf
commit
192bdac209
@ -169,7 +169,7 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName)
|
|||||||
|
|
||||||
// make sure the file is in the public directory
|
// make sure the file is in the public directory
|
||||||
if (!file.canonicalFilePath().startsWith(QDir(m_configuration.publicFolder).canonicalPath())) {
|
if (!file.canonicalFilePath().startsWith(QDir(m_configuration.publicFolder).canonicalPath())) {
|
||||||
qCDebug(dcWebServer()) << "Requested file" << file.fileName() << "is outside the public folder.";
|
qCDebug(dcWebServer()) << "Requested file" << file.canonicalFilePath() << "is outside the public folder.";
|
||||||
HttpReply *reply = HttpReply::createErrorReply(HttpReply::Forbidden);
|
HttpReply *reply = HttpReply::createErrorReply(HttpReply::Forbidden);
|
||||||
reply->setClientId(m_clientList.key(socket));
|
reply->setClientId(m_clientList.key(socket));
|
||||||
sendHttpReply(reply);
|
sendHttpReply(reply);
|
||||||
|
|||||||
@ -66,8 +66,8 @@ private slots:
|
|||||||
void getDebugServer();
|
void getDebugServer();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onSslErrors(const QList<QSslError> &) {
|
void onSslErrors(const QList<QSslError> &errors) {
|
||||||
qWarning() << "SSL error";
|
qCWarning(dcTests()) << "SSL errors:" << errors;
|
||||||
QSslSocket *socket = static_cast<QSslSocket*>(sender());
|
QSslSocket *socket = static_cast<QSslSocket*>(sender());
|
||||||
socket->ignoreSslErrors();
|
socket->ignoreSslErrors();
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ public slots:
|
|||||||
|
|
||||||
void TestWebserver::initTestCase()
|
void TestWebserver::initTestCase()
|
||||||
{
|
{
|
||||||
NymeaTestBase::initTestCase();
|
NymeaTestBase::initTestCase("*.debug=false\nWebServer.debug=true\ntests.debug=true\nServerManager.debug=true");
|
||||||
qDebug() << "TestWebserver starting";
|
qDebug() << "TestWebserver starting";
|
||||||
|
|
||||||
foreach (const WebServerConfiguration &config, NymeaCore::instance()->configuration()->webServerConfigurations()) {
|
foreach (const WebServerConfiguration &config, NymeaCore::instance()->configuration()->webServerConfigurations()) {
|
||||||
@ -215,7 +215,8 @@ void TestWebserver::checkAllowedMethodCall()
|
|||||||
QFETCH(int, expectedStatusCode);
|
QFETCH(int, expectedStatusCode);
|
||||||
|
|
||||||
QNetworkAccessManager nam;
|
QNetworkAccessManager nam;
|
||||||
connect(&nam, &QNetworkAccessManager::sslErrors, [](QNetworkReply* reply, const QList<QSslError> &) {
|
connect(&nam, &QNetworkAccessManager::sslErrors, [](QNetworkReply* reply, const QList<QSslError> &errors) {
|
||||||
|
qCWarning(dcTests) << "SSL errors:" << errors;
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
});
|
});
|
||||||
QSignalSpy clientSpy(&nam, SIGNAL(finished(QNetworkReply*)));
|
QSignalSpy clientSpy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||||
@ -244,7 +245,7 @@ void TestWebserver::checkAllowedMethodCall()
|
|||||||
} else if(method == "TRACE") {
|
} else if(method == "TRACE") {
|
||||||
reply = nam.sendCustomRequest(request, "TRACE");
|
reply = nam.sendCustomRequest(request, "TRACE");
|
||||||
} else {
|
} else {
|
||||||
// just to make shore there will be a reply to delete
|
// just to make sure there will be a reply to delete
|
||||||
reply = nam.get(request);
|
reply = nam.get(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +280,7 @@ void TestWebserver::badRequests_data()
|
|||||||
wrongHeaderFormatting.append("\r\n");
|
wrongHeaderFormatting.append("\r\n");
|
||||||
|
|
||||||
QByteArray userAgentMissing;
|
QByteArray userAgentMissing;
|
||||||
userAgentMissing.append("GET /abc HTTP/1.1\r\n");
|
userAgentMissing.append("GET /index.html HTTP/1.1\r\n");
|
||||||
userAgentMissing.append("\r\n");
|
userAgentMissing.append("\r\n");
|
||||||
|
|
||||||
QTest::newRow("wrong content length") << wrongContentLength << 400;
|
QTest::newRow("wrong content length") << wrongContentLength << 400;
|
||||||
@ -334,8 +335,8 @@ void TestWebserver::getFiles_data()
|
|||||||
QTest::newRow("get /etc/passwd") << "/etc/passwd" << 404;
|
QTest::newRow("get /etc/passwd") << "/etc/passwd" << 404;
|
||||||
QTest::newRow("get /blub/blub/blabla") << "/etc/passwd" << 404;
|
QTest::newRow("get /blub/blub/blabla") << "/etc/passwd" << 404;
|
||||||
QTest::newRow("get /../../etc/passwd") << "/../../etc/passwd" << 404;
|
QTest::newRow("get /../../etc/passwd") << "/../../etc/passwd" << 404;
|
||||||
QTest::newRow("get /../../") << "/../../" << 403;
|
QTest::newRow("get /../../") << "/../../" << 404;
|
||||||
QTest::newRow("get /../") << "/../" << 403;
|
QTest::newRow("get /../") << "/../" << 404;
|
||||||
QTest::newRow("get /etc/nymea/nymead.conf") << "/etc/nymea/nymead.conf" << 404;
|
QTest::newRow("get /etc/nymea/nymead.conf") << "/etc/nymea/nymead.conf" << 404;
|
||||||
QTest::newRow("get /etc/sudoers") << "/etc/sudoers" << 404;
|
QTest::newRow("get /etc/sudoers") << "/etc/sudoers" << 404;
|
||||||
QTest::newRow("get /root/.ssh/id_rsa.pub") << "/root/.ssh/id_rsa.pub" << 404;
|
QTest::newRow("get /root/.ssh/id_rsa.pub") << "/root/.ssh/id_rsa.pub" << 404;
|
||||||
@ -347,7 +348,7 @@ void TestWebserver::getFiles()
|
|||||||
QFETCH(int, expectedStatusCode);
|
QFETCH(int, expectedStatusCode);
|
||||||
|
|
||||||
QNetworkAccessManager nam;
|
QNetworkAccessManager nam;
|
||||||
connect(&nam, &QNetworkAccessManager::sslErrors, [this, &nam](QNetworkReply* reply, const QList<QSslError> &) {
|
connect(&nam, &QNetworkAccessManager::sslErrors, this, [](QNetworkReply* reply, const QList<QSslError> &) {
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
});
|
});
|
||||||
QSignalSpy clientSpy(&nam, SIGNAL(finished(QNetworkReply*)));
|
QSignalSpy clientSpy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||||
@ -489,17 +490,24 @@ void TestWebserver::getDebugServer_data()
|
|||||||
// Check if syslog is accessable
|
// Check if syslog is accessable
|
||||||
QFileInfo syslogFileInfo("/var/log/syslog");
|
QFileInfo syslogFileInfo("/var/log/syslog");
|
||||||
|
|
||||||
if (syslogFileInfo.exists() && syslogFileInfo.isReadable()) {
|
if (!syslogFileInfo.exists()) {
|
||||||
// syslog enabled
|
// syslog file doesn't exist
|
||||||
QTest::newRow("GET /debug/syslog | server enabled | 200") << "get" << "/debug/syslog" << true << 200;
|
QTest::newRow("GET /debug/syslog | server enabled | 200") << "get" << "/debug/syslog" << true << 404;
|
||||||
QTest::newRow("OPTIONS /debug/syslog | server enabled | 200") << "options" << "/debug/syslog" << true << 200;
|
QTest::newRow("OPTIONS /debug/syslog | server enabled | 200") << "options" << "/debug/syslog" << true << 404;
|
||||||
|
QTest::newRow("PUT /debug/syslog | server enabled | 405") << "put" << "/debug/syslog" << true << 405;
|
||||||
|
QTest::newRow("POST /debug/syslog | server enabled | 405") << "post" << "/debug/syslog" << true << 405;
|
||||||
|
QTest::newRow("DELETE /debug/syslog | server enabled | 405") << "delete" << "/debug/syslog" << true << 405;
|
||||||
|
} else if (!syslogFileInfo.isReadable()) {
|
||||||
|
// syslog enabled, but not readable
|
||||||
|
QTest::newRow("GET /debug/syslog | server enabled | 200") << "get" << "/debug/syslog" << true << 403;
|
||||||
|
QTest::newRow("OPTIONS /debug/syslog | server enabled | 200") << "options" << "/debug/syslog" << true << 403;
|
||||||
QTest::newRow("PUT /debug/syslog | server enabled | 405") << "put" << "/debug/syslog" << true << 405;
|
QTest::newRow("PUT /debug/syslog | server enabled | 405") << "put" << "/debug/syslog" << true << 405;
|
||||||
QTest::newRow("POST /debug/syslog | server enabled | 405") << "post" << "/debug/syslog" << true << 405;
|
QTest::newRow("POST /debug/syslog | server enabled | 405") << "post" << "/debug/syslog" << true << 405;
|
||||||
QTest::newRow("DELETE /debug/syslog | server enabled | 405") << "delete" << "/debug/syslog" << true << 405;
|
QTest::newRow("DELETE /debug/syslog | server enabled | 405") << "delete" << "/debug/syslog" << true << 405;
|
||||||
} else {
|
} else {
|
||||||
// syslog enabled, but not readable
|
// syslog enabled
|
||||||
QTest::newRow("GET /debug/syslog | server enabled | 200") << "get" << "/debug/syslog" << true << 403;
|
QTest::newRow("GET /debug/syslog | server enabled | 200") << "get" << "/debug/syslog" << true << 200;
|
||||||
QTest::newRow("OPTIONS /debug/syslog | server enabled | 200") << "options" << "/debug/syslog" << true << 403;
|
QTest::newRow("OPTIONS /debug/syslog | server enabled | 200") << "options" << "/debug/syslog" << true << 200;
|
||||||
QTest::newRow("PUT /debug/syslog | server enabled | 405") << "put" << "/debug/syslog" << true << 405;
|
QTest::newRow("PUT /debug/syslog | server enabled | 405") << "put" << "/debug/syslog" << true << 405;
|
||||||
QTest::newRow("POST /debug/syslog | server enabled | 405") << "post" << "/debug/syslog" << true << 405;
|
QTest::newRow("POST /debug/syslog | server enabled | 405") << "post" << "/debug/syslog" << true << 405;
|
||||||
QTest::newRow("DELETE /debug/syslog | server enabled | 405") << "delete" << "/debug/syslog" << true << 405;
|
QTest::newRow("DELETE /debug/syslog | server enabled | 405") << "delete" << "/debug/syslog" << true << 405;
|
||||||
|
|||||||
Reference in New Issue
Block a user