-# Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
+# Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
#
# This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
#
uis/DurableCookiesDialog.ui
uis/EditBookmarkDialog.ui
uis/EditFolderDialog.ui
+ uis/HttpAuthenticationDialog.ui
uis/SaveDialog.ui
uis/SettingsGeneral.ui
uis/SettingsPrivacy.ui
void AddBookmarkDialog::updateUi()
{
- // Determine if both line edits are populated.
+ // Update the add button status
if (bookmarkNameLineEditPointer->text().isEmpty() || bookmarkUrlLineEditPointer->text().isEmpty()) // At least one of the line edits is empty.
{
// Disable the add button.
DurableCookiesDialog.cpp
EditBookmarkDialog.cpp
EditFolderDialog.cpp
+ HttpAuthenticationDialog.cpp
SaveDialog.cpp
SettingsDialog.cpp
)
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ *
+ * Privacy Browser PC is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser PC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Application headers.
+#include "HttpAuthenticationDialog.h"
+#include "ui_HttpAuthenticationDialog.h"
+
+// Qt toolkit headers.
+#include <QPushButton>
+#include <QUrl>
+
+// Construct the class.
+HttpAuthenticationDialog::HttpAuthenticationDialog(QWidget *parentWidgetPointer, const QUrl &requestUrl, QAuthenticator *authenticatorPointer) :
+ QDialog(parentWidgetPointer), authenticatorPointer(authenticatorPointer)
+{
+ // Set the window title.
+ setWindowTitle(i18nc("The HTTP authentication dialog window title.", "HTTP Authentication"));
+
+ // Set the window modality.
+ setWindowModality(Qt::WindowModality::ApplicationModal);
+
+ // Instantiate the HTTP authentication dialog UI.
+ Ui::HttpAuthenticationDialog httpAuthenticationDialogUi;
+
+ // Setup the UI.
+ httpAuthenticationDialogUi.setupUi(this);
+
+ // Get handles for the widgets.
+ QLabel *realmLabelPointer = httpAuthenticationDialogUi.realmLabel;
+ QLabel *hostLabelPointer = httpAuthenticationDialogUi.hostLabel;
+ usernameLineEditPointer = httpAuthenticationDialogUi.usernameLineEdit;
+ passwordLineEditPointer = httpAuthenticationDialogUi.passwordLineEdit;
+ QDialogButtonBox *dialogButtonBoxPointer = httpAuthenticationDialogUi.dialogButtonBox;
+ okButtonPointer = dialogButtonBoxPointer->button(QDialogButtonBox::Ok);
+
+ // Display the labels.
+ realmLabelPointer->setText(authenticatorPointer->realm());
+ hostLabelPointer->setText(requestUrl.host());
+
+ // Connect the buttons.
+ connect(dialogButtonBoxPointer, SIGNAL(accepted()), this, SLOT(authenticate()));
+ connect(dialogButtonBoxPointer, SIGNAL(rejected()), this, SLOT(reject()));
+
+ // Update the UI when the line edits change.
+ connect(usernameLineEditPointer, SIGNAL(textEdited(const QString&)), this, SLOT(updateUi()));
+ connect(passwordLineEditPointer, SIGNAL(passwordChanged(const QString&)), this, SLOT(updateUi()));
+
+ // Initially disable the OK button.
+ okButtonPointer->setEnabled(false);
+}
+
+void HttpAuthenticationDialog::authenticate()
+{
+ // Populate the authenticator.
+ authenticatorPointer->setUser(usernameLineEditPointer->text());
+ authenticatorPointer->setPassword(passwordLineEditPointer->password());
+
+ // Close the dialog.
+ close();
+}
+
+void HttpAuthenticationDialog::updateUi()
+{
+ // Update the OK button status
+ if (usernameLineEditPointer->text().isEmpty() || passwordLineEditPointer->password().isEmpty()) // At least one of the line edits is empty.
+ {
+ // Disable the OK button.
+ okButtonPointer->setEnabled(false);
+ }
+ else // Both of the line edits are populated.
+ {
+ // Enable the OK button.
+ okButtonPointer->setEnabled(true);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+ *
+ * Privacy Browser PC is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser PC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HTTPAUTHENTICATIONDIALOG_H
+#define HTTPAUTHENTICATIONDIALOG_H
+
+// KDE framework headers.
+#include <KLineEdit>
+#include <KPasswordLineEdit>
+
+// Qt toolkit headers.
+#include <QAuthenticator>
+#include <QDialog>
+
+class HttpAuthenticationDialog : public QDialog
+{
+ // Include the Q_OBJECT macro.
+ Q_OBJECT
+
+public:
+ // The primary constructor.
+ explicit HttpAuthenticationDialog(QWidget *parentWidgetPointer, const QUrl &requestUrl, QAuthenticator *authenticatorPointer);
+
+private Q_SLOTS:
+ // The private slots.
+ void authenticate();
+ void updateUi();
+
+private:
+ // The private variables.
+ QAuthenticator *authenticatorPointer;
+
+ // The private widgets.
+ QPushButton *okButtonPointer;
+ KPasswordLineEdit *passwordLineEditPointer;
+ KLineEdit *usernameLineEditPointer;
+};
+#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2024 Soren Stoutner <soren@stoutner.com>.
+
+ This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
+
+ Privacy Browser PC is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Privacy Browser PC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Privacy Browser PC. If not, see <http://www.gnu.org/licenses/>. -->
+
+<ui version="4.0">
+ <class>HttpAuthenticationDialog</class>
+
+ <widget class="QWidget">
+ <!-- Dialog body. -->
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="realmLabel">
+ <property name="font">
+ <font>
+ <pointsize>24</pointsize>
+ <bold>true</bold>
+ </font>
+ </property>
+
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+
+ <item>
+ <!-- Host. -->
+ <layout class="QFormLayout">
+ <property name="formAlignment">
+ <set>Qt::AlignHCenter|Qt::AlignTop</set>
+ </property>
+
+ <item row="0" column="0">
+ <widget class="QLabel">
+ <property name="text">
+ <string>Host:</string>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column ="1">
+ <widget class="QLabel" name="hostLabel" />
+ </item>
+ </layout>
+ </item>
+
+ <item>
+ <layout class="QFormLayout">
+ <!-- Username. -->
+ <item row="0" column="0">
+ <widget class="QLabel">
+ <property name="text">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+
+ <item row="0" column="1">
+ <widget class="KLineEdit" name="usernameLineEdit">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+
+ <!-- Password. -->
+ <item row="1" column="0">
+ <widget class="QLabel">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+
+ <item row="1" column="1">
+ <widget class="KPasswordLineEdit" name="passwordLineEdit" />
+ </item>
+ </layout>
+ </item>
+
+ <!-- Spacer. -->
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </spacer>
+ </item>
+
+ <!-- Buttons. -->
+ <item>
+ <widget class="QDialogButtonBox" name="dialogButtonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok | QDialogButtonBox::Cancel</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+</ui>
/*
- * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
// Application headers.
#include "PrivacyWebEngineView.h"
#include "Settings.h"
+#include "ui_HttpAuthenticationDialog.h"
#include "databases/CookiesDatabase.h"
#include "databases/DomainsDatabase.h"
+#include "dialogs/HttpAuthenticationDialog.h"
#include "interceptors/UrlRequestInterceptor.h"
#include "windows/BrowserWindow.h"
// Display HTTP Ping blocked dialogs.
connect(urlRequestInterceptorPointer, SIGNAL(displayHttpPingDialog(const QString&)), this, SLOT(displayHttpPingDialog(const QString&)));
+
+ // Handle HTTP authentication requests.
+ connect(webEnginePagePointer, SIGNAL(authenticationRequired(const QUrl&, QAuthenticator*)), this, SLOT(handleAuthenticationRequest(const QUrl&, QAuthenticator*)));
}
void PrivacyWebEngineView::addCookieToList(const QNetworkCookie &cookie) const
emit displayHttpPingBlockedDialog(httpPingUrl);
}
+void PrivacyWebEngineView::handleAuthenticationRequest(const QUrl &requestUrl, QAuthenticator *authenticatorPointer)
+{
+ // Instantiate an HTTP authentication dialog.
+ HttpAuthenticationDialog *httpAuthenticationDialogPointer = new HttpAuthenticationDialog(parentWidget(), requestUrl, authenticatorPointer);
+
+ // Display the dialog. This must be `exec()` instead of `show()` so that the website doesn't proceed before populating the authentication pointer.
+ httpAuthenticationDialogPointer->exec();
+}
+
void PrivacyWebEngineView::removeCookieFromList(const QNetworkCookie &cookie) const
{
//qDebug() << "Remove cookie: " << cookie.toRawForm();
/*
- * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022-2024 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
*
#ifndef PRIVACYWEBENGINEVIEW_H
#define PRIVACYWEBENGINEVIEW_H
+// KDE framework headers.
+#include <KLineEdit>
+
// Qt toolkit headers.
#include <QIcon>
#include <QNetworkCookie>
// The private slots.
void applyDomainSettingsWithoutReloading(const QString &hostname);
void displayHttpPingDialog(const QString &httpPingUrl) const;
+ void handleAuthenticationRequest(const QUrl &requestUrl, QAuthenticator *authenticatorPointer);
private:
// The private variables.
+ KLineEdit *passwordLineEditPointer;
+ KLineEdit *usernameLineEditPointer;
QWebEngineProfile *webEngineProfilePointer;
QWebEngineSettings *webEngineSettingsPointer;
// Wipe the currently displayed text.
KLineEdit::setText(QLatin1String(""));
- // Create an input method event attribute list.
- QList<QInputMethodEvent::Attribute> inputMethodEventAttributeList;
+ // Only highlight the URL if it starts with a known schema.
+ if (urlString.startsWith(QLatin1String("https://")) || urlString.startsWith(QLatin1String("http://")) || urlString.startsWith(QLatin1String("view-source:")))
+ {
+ // Create an input method event attribute list.
+ QList<QInputMethodEvent::Attribute> inputMethodEventAttributeList;
- // Calculate the URL string length.
- int urlStringLength = urlString.length();
+ // Calculate the URL string length.
+ int urlStringLength = urlString.length();
- // Get the index of end of the schema.
- int endOfSchemaIndex = urlString.indexOf(QLatin1String("//")) + 2;
+ // Get the index of end of the schema.
+ int endOfSchemaIndex = urlString.indexOf(QLatin1String("//")) + 2;
- // Get the index of the last `.` in the domain.
- int lastDotIndex = urlString.lastIndexOf(QLatin1Char('.'));
+ // Get the index of the `/` immediately after the domain name. If this doesn't exit it will be set to `-1`.
+ int endOfDomainNameIndex = urlString.indexOf(QLatin1Char('/'), endOfSchemaIndex);
- // Get the index of the penultimate `.` in the domain. If this doesn't exist it will be set to `-1`.
- int penultimateDotIndex = urlString.lastIndexOf(QLatin1Char('.'), lastDotIndex - urlStringLength - 1);
+ // Get the index of the last `.` in the domain.
+ int lastDotIndex = urlString.lastIndexOf(QLatin1Char('.'), endOfDomainNameIndex - urlStringLength);
- // Get the index of the `/` immediately after the domain name. If this doesn't exit it will be set to `-1`.
- int endOfDomainNameIndex = urlString.indexOf(QLatin1Char('/'), endOfSchemaIndex);
+ // Get the index of the penultimate `.` in the domain. If this doesn't exist it will be set to `-1`.
+ int penultimateDotIndex = urlString.lastIndexOf(QLatin1Char('.'), lastDotIndex - urlStringLength - 1);
- // Create the text character formats.
- QTextCharFormat grayTextCharFormat;
- QTextCharFormat schemaTextCharFormat;
+ // Create the text character formats.
+ QTextCharFormat grayTextCharFormat;
+ QTextCharFormat schemaTextCharFormat;
- // Set the text character format colors.
- grayTextCharFormat.setForeground(Qt::darkGray);
+ // Set the text character format colors.
+ grayTextCharFormat.setForeground(Qt::darkGray);
- // Set the schema text character format color.
- if (urlString.startsWith(QLatin1String("http://")) || urlString.startsWith(QLatin1String("view-source:http://")))
- schemaTextCharFormat.setForeground(Qt::red);
- else
- schemaTextCharFormat = grayTextCharFormat;
+ // Set the schema text character format color.
+ if (urlString.startsWith(QLatin1String("http://")) || urlString.startsWith(QLatin1String("view-source:http://")))
+ schemaTextCharFormat.setForeground(Qt::red);
+ else
+ schemaTextCharFormat = grayTextCharFormat;
- // Append the schema text format format.
- inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, endOfSchemaIndex, schemaTextCharFormat));
+ // Append the schema text format format.
+ inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, endOfSchemaIndex, schemaTextCharFormat));
- // Append the subdomain format if the subdomain exists. If it doesn't, the penultimate dot index will be `-1`.
- if (penultimateDotIndex > 0)
- inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, endOfSchemaIndex, penultimateDotIndex + 1 - endOfSchemaIndex, grayTextCharFormat));
+ // Append the subdomain format if the subdomain exists. If it doesn't, the penultimate dot index will be `-1`.
+ if (penultimateDotIndex > 0)
+ inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, endOfSchemaIndex, penultimateDotIndex + 1 - endOfSchemaIndex, grayTextCharFormat));
- // Append the post domain formatting if text exists after the domain name. If it doesn't, the end of domain name index will be `-1`.
- if (endOfDomainNameIndex > 0)
- inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, endOfDomainNameIndex, urlStringLength - endOfDomainNameIndex, grayTextCharFormat));
+ // Append the post domain formatting if text exists after the domain name. If it doesn't, the end of domain name index will be `-1`.
+ if (endOfDomainNameIndex > 0)
+ inputMethodEventAttributeList.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, endOfDomainNameIndex, urlStringLength - endOfDomainNameIndex, grayTextCharFormat));
- // Create an input method event with an empty pre-edit string.
- QInputMethodEvent inputMethodEvent(QString(""), inputMethodEventAttributeList);
+ // Create an input method event with an empty pre-edit string.
+ QInputMethodEvent inputMethodEvent(QString(""), inputMethodEventAttributeList);
- // Apply the URL highlighting.
- event(&inputMethodEvent);
+ // Apply the URL highlighting.
+ event(&inputMethodEvent);
+ }
// Run the default commands.
KLineEdit::setText(urlString);