syncthingtray/tray/gui/webpage.cpp

164 lines
5.1 KiB
C++
Raw Normal View History

2016-09-03 19:39:43 +02:00
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
2016-08-25 00:45:32 +02:00
#include "./webpage.h"
2016-09-03 20:14:52 +02:00
#include "./webviewdialog.h"
2016-08-25 00:45:32 +02:00
#include "../application/settings.h"
#include "../../connector/syncthingconnection.h"
2016-08-25 00:45:32 +02:00
#include "resources/config.h"
#include <QDesktopServices>
#include <QAuthenticator>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#if defined(SYNCTHINGTRAY_USE_WEBENGINE)
# include <QWebEngineSettings>
# include <QWebEngineView>
2016-09-01 16:34:30 +02:00
# include <QWebEngineCertificateError>
2016-08-25 00:45:32 +02:00
#elif defined(SYNCTHINGTRAY_USE_WEBKIT)
# include <QWebSettings>
# include <QWebView>
# include <QWebFrame>
2016-09-01 16:34:30 +02:00
# include <QSslError>
# include <QNetworkRequest>
2016-08-25 00:45:32 +02:00
#endif
2016-09-01 16:34:30 +02:00
using namespace Data;
2016-08-25 00:45:32 +02:00
namespace QtGui {
2016-09-03 20:14:52 +02:00
WebPage::WebPage(WebViewDialog *dlg, WEB_VIEW_PROVIDER *view) :
2016-08-25 00:45:32 +02:00
WEB_PAGE_PROVIDER(view),
2016-09-03 20:14:52 +02:00
m_dlg(dlg),
2016-08-25 00:45:32 +02:00
m_view(view)
{
2016-09-03 19:39:43 +02:00
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
2016-08-25 00:45:32 +02:00
settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
connect(this, &WebPage::authenticationRequired, this, static_cast<void(WebPage::*)(const QUrl &, QAuthenticator *)>(&WebPage::supplyCredentials));
#else
settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
setNetworkAccessManager(&Data::networkAccessManager());
connect(&Data::networkAccessManager(), &QNetworkAccessManager::authenticationRequired, this, static_cast<void(WebPage::*)(QNetworkReply *, QAuthenticator *)>(&WebPage::supplyCredentials));
2016-09-01 16:34:30 +02:00
connect(&Data::networkAccessManager(), &QNetworkAccessManager::sslErrors, this, static_cast<void(WebPage::*)(QNetworkReply *, const QList<QSslError> &errors)>(&WebPage::handleSslErrors));
2016-08-25 00:45:32 +02:00
#endif
2016-08-25 00:45:32 +02:00
if(!m_view) {
// initialization for new window
// -> delegate to external browser if no view is assigned
2016-09-03 19:39:43 +02:00
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
connect(this, &WebPage::urlChanged, this, &WebPage::delegateNewWindowToExternalBrowser);
2016-08-25 00:45:32 +02:00
#else
connect(this->mainFrame(), &QWebFrame::urlChanged, this, &WebPage::delegateNewWindowToExternalBrowser);
2016-08-25 00:45:32 +02:00
#endif
// -> there need to be a view, though
2016-08-25 00:45:32 +02:00
m_view = new WEB_VIEW_PROVIDER;
m_view->setPage(this);
}
}
WEB_PAGE_PROVIDER *WebPage::createWindow(WEB_PAGE_PROVIDER::WebWindowType type)
{
2016-09-03 20:14:52 +02:00
Q_UNUSED(type)
2016-08-25 00:45:32 +02:00
return new WebPage;
}
2016-09-01 16:34:30 +02:00
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
bool WebPage::certificateError(const QWebEngineCertificateError &certificateError)
{
switch(certificateError.error()) {
case QWebEngineCertificateError::CertificateCommonNameInvalid:
case QWebEngineCertificateError::CertificateAuthorityInvalid:
// FIXME: only ignore the error if the used certificate matches the certificate
// known to be used by the Syncthing GUI
return true;
default:
return false;
}
}
bool WebPage::acceptNavigationRequest(const QUrl &url, WEB_PAGE_PROVIDER::NavigationType type, bool isMainFrame)
{
Q_UNUSED(isMainFrame)
Q_UNUSED(type)
return handleNavigationRequest(this->url(), url);
}
#else // SYNCTHINGTRAY_USE_WEBKIT
bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, WEB_PAGE_PROVIDER::NavigationType type)
{
Q_UNUSED(frame)
Q_UNUSED(type)
return handleNavigationRequest(mainFrame() ? mainFrame()->url() : QUrl(), request.url());
}
2016-09-01 16:34:30 +02:00
#endif
void WebPage::delegateNewWindowToExternalBrowser(const QUrl &url)
2016-08-25 00:45:32 +02:00
{
2016-09-01 16:34:30 +02:00
QDesktopServices::openUrl(url);
2016-08-25 00:45:32 +02:00
// this page and the associated view are useless
m_view->deleteLater();
deleteLater();
}
void WebPage::supplyCredentials(const QUrl &requestUrl, QAuthenticator *authenticator)
{
Q_UNUSED(requestUrl)
supplyCredentials(authenticator);
}
void WebPage::supplyCredentials(QNetworkReply *reply, QAuthenticator *authenticator)
{
Q_UNUSED(reply)
supplyCredentials(authenticator);
}
void WebPage::supplyCredentials(QAuthenticator *authenticator)
{
2016-09-03 20:14:52 +02:00
if(m_dlg && m_dlg->settings().authEnabled) {
authenticator->setUser(m_dlg->settings().userName);
authenticator->setPassword(m_dlg->settings().password);
2016-08-25 00:45:32 +02:00
}
}
bool WebPage::handleNavigationRequest(const QUrl &currentUrl, const QUrl &targetUrl)
{
if(currentUrl.isEmpty()) {
// allow initial request
return true;
}
// only allow navigation on the same page
if(currentUrl.scheme() == targetUrl.scheme()
&& currentUrl.host() == targetUrl.host()
&& currentUrl.port() == targetUrl.port()) {
QString currentPath = currentUrl.path();
while(currentPath.endsWith(QChar('/'))) {
currentPath.resize(currentPath.size() - 1);
}
QString targetPath = targetUrl.path();
while(targetPath.endsWith(QChar('/'))) {
targetPath.resize(targetPath.size() - 1);
}
if(currentPath == targetPath) {
return true;
}
}
// otherwise open URL in external browser
QDesktopServices::openUrl(targetUrl);
return false;
}
2016-09-01 16:34:30 +02:00
#ifdef SYNCTHINGTRAY_USE_WEBKIT
void WebPage::handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
2016-08-25 00:45:32 +02:00
{
2016-09-03 20:14:52 +02:00
Q_UNUSED(errors)
if(m_dlg && reply->request().url().host() == m_view->url().host()) {
reply->ignoreSslErrors(m_dlg->settings().expectedSslErrors);
2016-09-01 16:34:30 +02:00
}
2016-08-25 00:45:32 +02:00
}
2016-09-01 16:34:30 +02:00
#endif
2016-08-25 00:45:32 +02:00
}
2016-09-03 19:39:43 +02:00
#endif // SYNCTHINGTRAY_NO_WEBVIEW