File indexing completed on 2024-05-12 04:57:59
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "cookiemanager.h" 0019 #include "ui_cookiemanager.h" 0020 #include "browserwindow.h" 0021 #include "cookiejar.h" 0022 #include "mainapplication.h" 0023 #include "qztools.h" 0024 #include "settings.h" 0025 #include "iconprovider.h" 0026 0027 #include <QNetworkCookie> 0028 #include <QMessageBox> 0029 #include <QDateTime> 0030 #include <QShortcut> 0031 #include <QTimer> 0032 #include <QInputDialog> 0033 #include <QCloseEvent> 0034 0035 CookieManager::CookieManager(QWidget *parent) 0036 : QDialog(parent) 0037 , ui(new Ui::CookieManager) 0038 { 0039 setAttribute(Qt::WA_DeleteOnClose); 0040 0041 ui->setupUi(this); 0042 QzTools::centerWidgetOnScreen(this); 0043 0044 if (isRightToLeft()) { 0045 ui->cookieTree->headerItem()->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter); 0046 ui->cookieTree->headerItem()->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter); 0047 ui->cookieTree->setLayoutDirection(Qt::LeftToRight); 0048 ui->whiteList->setLayoutDirection(Qt::LeftToRight); 0049 ui->blackList->setLayoutDirection(Qt::LeftToRight); 0050 } 0051 0052 // Stored Cookies 0053 connect(ui->cookieTree, &QTreeWidget::currentItemChanged, this, &CookieManager::currentItemChanged); 0054 connect(ui->removeAll, &QAbstractButton::clicked, this, &CookieManager::removeAll); 0055 connect(ui->removeOne, &QAbstractButton::clicked, this, &CookieManager::remove); 0056 connect(ui->close, &QDialogButtonBox::clicked, this, &QWidget::close); 0057 connect(ui->close2, &QDialogButtonBox::clicked, this, &QWidget::close); 0058 connect(ui->close3, &QDialogButtonBox::clicked, this, &QWidget::close); 0059 connect(ui->search, &QLineEdit::textChanged, this, &CookieManager::filterString); 0060 0061 // Cookie Filtering 0062 connect(ui->whiteAdd, &QAbstractButton::clicked, this, &CookieManager::addWhitelist); 0063 connect(ui->whiteRemove, &QAbstractButton::clicked, this, &CookieManager::removeWhitelist); 0064 connect(ui->blackAdd, SIGNAL(clicked()), this, SLOT(addBlacklist())); 0065 connect(ui->blackRemove, &QAbstractButton::clicked, this, &CookieManager::removeBlacklist); 0066 0067 // Cookie Settings 0068 Settings settings; 0069 settings.beginGroup(QSL("Cookie-Settings")); 0070 ui->saveCookies->setChecked(settings.value(QSL("allowCookies"), true).toBool()); 0071 ui->filter3rdParty->setChecked(settings.value(QSL("filterThirdPartyCookies"), false).toBool()); 0072 ui->filterTracking->setChecked(settings.value(QSL("filterTrackingCookie"), false).toBool()); 0073 ui->deleteCookiesOnClose->setChecked(settings.value(QSL("deleteCookiesOnClose"), false).toBool()); 0074 ui->whiteList->addItems(settings.value(QSL("whitelist"), QStringList()).toStringList()); 0075 ui->blackList->addItems(settings.value(QSL("blacklist"), QStringList()).toStringList()); 0076 settings.endGroup(); 0077 0078 ui->search->setPlaceholderText(tr("Search")); 0079 ui->cookieTree->setDefaultItemShowMode(TreeWidget::ItemsCollapsed); 0080 ui->cookieTree->sortItems(0, Qt::AscendingOrder); 0081 ui->cookieTree->header()->setDefaultSectionSize(220); 0082 ui->cookieTree->setFocus(); 0083 0084 ui->whiteList->sortItems(Qt::AscendingOrder); 0085 ui->blackList->sortItems(Qt::AscendingOrder); 0086 0087 auto* removeShortcut = new QShortcut(QKeySequence(QSL("Del")), this); 0088 connect(removeShortcut, &QShortcut::activated, this, &CookieManager::deletePressed); 0089 0090 connect(ui->search, &QLineEdit::textChanged, this, &CookieManager::filterString); 0091 connect(mApp->cookieJar(), &CookieJar::cookieAdded, this, &CookieManager::addCookie); 0092 connect(mApp->cookieJar(), &CookieJar::cookieRemoved, this, &CookieManager::removeCookie); 0093 0094 // Load cookies 0095 const auto allCookies = mApp->cookieJar()->getAllCookies(); 0096 for (const QNetworkCookie &cookie : allCookies) { 0097 addCookie(cookie); 0098 } 0099 0100 QzTools::setWmClass(QSL("Cookies"), this); 0101 } 0102 0103 void CookieManager::removeAll() 0104 { 0105 QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Confirmation"), 0106 tr("Are you sure you want to delete all cookies on your computer?"), QMessageBox::Yes | QMessageBox::No); 0107 if (button != QMessageBox::Yes) { 0108 return; 0109 } 0110 0111 mApp->cookieJar()->deleteAllCookies(); 0112 0113 m_itemHash.clear(); 0114 m_domainHash.clear(); 0115 ui->cookieTree->clear(); 0116 } 0117 0118 void CookieManager::remove() 0119 { 0120 QList<QNetworkCookie> cookies; 0121 auto selection = ui->cookieTree->selectedItems(); 0122 0123 for (int i = 0; i < selection.count(); i++) { 0124 QTreeWidgetItem* current = selection[i]; 0125 0126 if (current->childCount()) { 0127 for (int i = 0; i < current->childCount(); ++i) { 0128 QTreeWidgetItem *item = current->child(i); 0129 if (item && m_itemHash.contains(item)) { 0130 cookies.append(m_itemHash.value(item)); 0131 } 0132 } 0133 } else if (m_itemHash.contains(current)) { 0134 cookies.append(m_itemHash.value(current)); 0135 } 0136 } 0137 0138 for (const QNetworkCookie &cookie : std::as_const(cookies)) { 0139 mApp->cookieJar()->deleteCookie(cookie); 0140 } 0141 } 0142 0143 void CookieManager::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* parent) 0144 { 0145 Q_UNUSED(parent); 0146 if (!current) { 0147 return; 0148 } 0149 0150 if (current->text(1).isEmpty()) { 0151 ui->name->setText(tr("<cookie not selected>")); 0152 ui->value->setText(tr("<cookie not selected>")); 0153 ui->server->setText(tr("<cookie not selected>")); 0154 ui->path->setText(tr("<cookie not selected>")); 0155 ui->secure->setText(tr("<cookie not selected>")); 0156 ui->expiration->setText(tr("<cookie not selected>")); 0157 0158 ui->removeOne->setText(tr("Remove cookies")); 0159 return; 0160 } else if (ui->cookieTree->selectedItems().count() > 1) { 0161 ui->name->setText(tr("<multiple cookies selected>")); 0162 ui->value->setText(tr("<multiple cookies selected>")); 0163 ui->server->setText(tr("<multiple cookies selected>")); 0164 ui->path->setText(tr("<multiple cookies selected>")); 0165 ui->secure->setText(tr("<multiple cookies selected>")); 0166 ui->expiration->setText(tr("<multiple cookies selected>")); 0167 0168 ui->removeOne->setText(tr("Remove cookies")); 0169 return; 0170 } 0171 0172 const QNetworkCookie cookie = qvariant_cast<QNetworkCookie>(current->data(0, Qt::UserRole + 10)); 0173 0174 ui->name->setText(QString::fromUtf8(cookie.name())); 0175 ui->value->setText(QString::fromUtf8(cookie.value())); 0176 ui->server->setText(cookie.domain()); 0177 ui->path->setText(cookie.path()); 0178 cookie.isSecure() ? ui->secure->setText(tr("Secure only")) : ui->secure->setText(tr("All connections")); 0179 cookie.isSessionCookie() ? ui->expiration->setText(tr("Session cookie")) : ui->expiration->setText(QDateTime(cookie.expirationDate()).toString(QSL("hh:mm:ss dddd d. MMMM yyyy"))); 0180 0181 ui->removeOne->setText(tr("Remove cookie")); 0182 } 0183 0184 void CookieManager::addWhitelist() 0185 { 0186 const QString server = QInputDialog::getText(this, tr("Add to whitelist"), tr("Server:")); 0187 0188 if (server.isEmpty()) { 0189 return; 0190 } 0191 0192 if (!ui->blackList->findItems(server, Qt::MatchFixedString).isEmpty()) { 0193 QMessageBox::information(this, tr("Already blacklisted!"), tr("The server \"%1\" is already in blacklist, please remove it first.").arg(server)); 0194 return; 0195 } 0196 0197 if (ui->whiteList->findItems(server, Qt::MatchFixedString).isEmpty()) { 0198 ui->whiteList->addItem(server); 0199 } 0200 } 0201 0202 void CookieManager::removeWhitelist() 0203 { 0204 delete ui->whiteList->currentItem(); 0205 } 0206 0207 void CookieManager::addBlacklist() 0208 { 0209 const QString server = QInputDialog::getText(this, tr("Add to blacklist"), tr("Server:")); 0210 addBlacklist(server); 0211 } 0212 0213 void CookieManager::addBlacklist(const QString &server) 0214 { 0215 if (server.isEmpty()) { 0216 return; 0217 } 0218 0219 if (!ui->whiteList->findItems(server, Qt::MatchFixedString).isEmpty()) { 0220 QMessageBox::information(this, tr("Already whitelisted!"), tr("The server \"%1\" is already in whitelist, please remove it first.").arg(server)); 0221 return; 0222 } 0223 0224 if (ui->blackList->findItems(server, Qt::MatchFixedString).isEmpty()) { 0225 ui->blackList->addItem(server); 0226 } 0227 } 0228 0229 QString CookieManager::cookieDomain(const QNetworkCookie &cookie) const 0230 { 0231 QString domain = cookie.domain(); 0232 if (domain.startsWith(QLatin1Char('.'))) { 0233 domain.remove(0, 1); 0234 } 0235 return domain; 0236 } 0237 0238 QTreeWidgetItem *CookieManager::cookieItem(const QNetworkCookie &cookie) const 0239 { 0240 QHashIterator<QTreeWidgetItem*, QNetworkCookie> it(m_itemHash); 0241 while (it.hasNext()) { 0242 it.next(); 0243 if (it.value() == cookie) 0244 return it.key(); 0245 } 0246 return nullptr; 0247 } 0248 0249 void CookieManager::removeBlacklist() 0250 { 0251 delete ui->blackList->currentItem(); 0252 } 0253 0254 void CookieManager::deletePressed() 0255 { 0256 if (ui->cookieTree->hasFocus()) { 0257 remove(); 0258 } 0259 else if (ui->whiteList->hasFocus()) { 0260 removeWhitelist(); 0261 } 0262 else if (ui->blackList->hasFocus()) { 0263 removeBlacklist(); 0264 } 0265 } 0266 0267 void CookieManager::filterString(const QString &string) 0268 { 0269 if (string.isEmpty()) { 0270 for (int i = 0; i < ui->cookieTree->topLevelItemCount(); ++i) { 0271 ui->cookieTree->topLevelItem(i)->setHidden(false); 0272 ui->cookieTree->topLevelItem(i)->setExpanded(ui->cookieTree->defaultItemShowMode() == TreeWidget::ItemsExpanded); 0273 } 0274 } 0275 else { 0276 for (int i = 0; i < ui->cookieTree->topLevelItemCount(); ++i) { 0277 QString text = QSL(".") + ui->cookieTree->topLevelItem(i)->text(0); 0278 ui->cookieTree->topLevelItem(i)->setHidden(!text.contains(string, Qt::CaseInsensitive)); 0279 ui->cookieTree->topLevelItem(i)->setExpanded(true); 0280 } 0281 } 0282 } 0283 0284 void CookieManager::addCookie(const QNetworkCookie &cookie) 0285 { 0286 QTreeWidgetItem* item; 0287 const QString domain = cookieDomain(cookie); 0288 0289 QTreeWidgetItem* findParent = m_domainHash.value(domain); 0290 if (findParent) { 0291 item = new QTreeWidgetItem(findParent); 0292 } 0293 else { 0294 auto* newParent = new QTreeWidgetItem(ui->cookieTree); 0295 newParent->setText(0, domain); 0296 newParent->setIcon(0, IconProvider::standardIcon(QStyle::SP_DirIcon)); 0297 newParent->setData(0, Qt::UserRole + 10, cookie.domain()); 0298 ui->cookieTree->addTopLevelItem(newParent); 0299 m_domainHash[domain] = newParent; 0300 0301 item = new QTreeWidgetItem(newParent); 0302 } 0303 0304 item->setText(0, QSL(".") + domain); 0305 item->setText(1, QString::fromUtf8(cookie.name())); 0306 item->setData(0, Qt::UserRole + 10, QVariant::fromValue(cookie)); 0307 ui->cookieTree->addTopLevelItem(item); 0308 0309 m_itemHash[item] = cookie; 0310 } 0311 0312 void CookieManager::removeCookie(const QNetworkCookie &cookie) 0313 { 0314 QTreeWidgetItem *item = cookieItem(cookie); 0315 if (!item) 0316 return; 0317 0318 m_itemHash.remove(item); 0319 0320 if (item->parent() && item->parent()->childCount() == 1) { 0321 m_domainHash.remove(cookieDomain(cookie)); 0322 delete item->parent(); 0323 item = nullptr; 0324 } 0325 0326 delete item; 0327 } 0328 0329 void CookieManager::closeEvent(QCloseEvent* e) 0330 { 0331 QStringList whitelist; 0332 QStringList blacklist; 0333 0334 for (int i = 0; i < ui->whiteList->count(); ++i) { 0335 whitelist.append(ui->whiteList->item(i)->text()); 0336 } 0337 0338 for (int i = 0; i < ui->blackList->count(); ++i) { 0339 blacklist.append(ui->blackList->item(i)->text()); 0340 } 0341 0342 Settings settings; 0343 settings.beginGroup(QSL("Cookie-Settings")); 0344 settings.setValue(QSL("allowCookies"), ui->saveCookies->isChecked()); 0345 settings.setValue(QSL("filterThirdPartyCookies"), ui->filter3rdParty->isChecked()); 0346 settings.setValue(QSL("filterTrackingCookie"), ui->filterTracking->isChecked()); 0347 settings.setValue(QSL("deleteCookiesOnClose"), ui->deleteCookiesOnClose->isChecked()); 0348 settings.setValue(QSL("whitelist"), whitelist); 0349 settings.setValue(QSL("blacklist"), blacklist); 0350 settings.endGroup(); 0351 0352 mApp->cookieJar()->loadSettings(); 0353 0354 e->accept(); 0355 } 0356 0357 void CookieManager::keyPressEvent(QKeyEvent* e) 0358 { 0359 if (e->key() == Qt::Key_Escape) { 0360 close(); 0361 } 0362 0363 QWidget::keyPressEvent(e); 0364 } 0365 0366 CookieManager::~CookieManager() 0367 { 0368 delete ui; 0369 }