diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/WebBrowser/CookieJar/CookieJar.py --- a/src/eric7/WebBrowser/CookieJar/CookieJar.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/WebBrowser/CookieJar/CookieJar.py Wed Jul 13 14:55:47 2022 +0200 @@ -23,11 +23,12 @@ """ Class implementing a QNetworkCookieJar subclass with various accept policies. - + @signal cookiesChanged() emitted after the cookies have been changed """ + cookiesChanged = pyqtSignal() - + AcceptAlways = 0 AcceptNever = 1 AcceptOnlyFromSitesNavigatedTo = 2 @@ -36,60 +37,61 @@ KeepUntilExpire = 0 KeepUntilExit = 1 KeepMax = 1 - + Allow = 0 Block = 1 AllowForSession = 2 - + def __init__(self, parent=None): """ Constructor - + @param parent reference to the parent object (QObject) """ super().__init__(parent) - + self.__loaded = False self.__acceptCookies = self.AcceptOnlyFromSitesNavigatedTo self.__saveTimer = AutoSaver(self, self.__save) - - self.__cookiesFile = os.path.join(Utilities.getConfigDir(), - "web_browser", "cookies.ini") - + + self.__cookiesFile = os.path.join( + Utilities.getConfigDir(), "web_browser", "cookies.ini" + ) + self.__store = WebBrowserWindow.webProfile().cookieStore() self.__store.setCookieFilter(self.__cookieFilter) self.__store.cookieAdded.connect(self.__cookieAdded) self.__store.cookieRemoved.connect(self.__cookieRemoved) - + self.__load() self.__store.loadAllCookies() - + def close(self): """ Public slot to close the cookie jar. """ if not self.__loaded: self.__load() - + if self.__keepCookies == self.KeepUntilExit: self.clear() self.__saveTimer.saveIfNeccessary() - + def clear(self): """ Public method to clear all cookies. """ if not self.__loaded: self.__load() - + self.setAllCookies([]) self.__store.deleteAllCookies() self.cookiesChanged.emit() - + def removeCookies(self, cookies): """ Public method to remove a list of cookies. - + @param cookies list of cookies to be removed @type list of QNetworkCookie """ @@ -97,103 +99,105 @@ for cookie in cookies: self.__store.deleteCookie(cookie) self.blockSignals(wasBlocked) - + self.cookiesChanged.emit() - + def removeCookie(self, cookie): """ Public method to remove a cookie. - + @param cookie cookie to be removed @type QNetworkCookie """ self.__store.deleteCookie(cookie) self.cookiesChanged.emit() - + def __load(self): """ Private method to load the cookies settings. """ if self.__loaded: return - - cookieSettings = QSettings(self.__cookiesFile, - QSettings.Format.IniFormat) - + + cookieSettings = QSettings(self.__cookiesFile, QSettings.Format.IniFormat) + # load exceptions self.__exceptionsBlock = Preferences.toList( - cookieSettings.value("Exceptions/block")) + cookieSettings.value("Exceptions/block") + ) self.__exceptionsAllow = Preferences.toList( - cookieSettings.value("Exceptions/allow")) + cookieSettings.value("Exceptions/allow") + ) self.__exceptionsAllowForSession = Preferences.toList( - cookieSettings.value("Exceptions/allowForSession")) + cookieSettings.value("Exceptions/allowForSession") + ) self.__exceptionsBlock.sort() self.__exceptionsAllow.sort() self.__exceptionsAllowForSession.sort() - + self.__acceptCookies = Preferences.getWebBrowser("AcceptCookies") self.__keepCookies = Preferences.getWebBrowser("KeepCookiesUntil") if self.__keepCookies == self.KeepUntilExit: self.clear() - + self.__filterTrackingCookies = Preferences.toBool( - Preferences.getWebBrowser("FilterTrackingCookies")) - + Preferences.getWebBrowser("FilterTrackingCookies") + ) + self.__loaded = True self.cookiesChanged.emit() - + def __save(self): """ Private method to save the cookies settings. """ if not self.__loaded: return - - cookieSettings = QSettings(self.__cookiesFile, - QSettings.Format.IniFormat) - + + cookieSettings = QSettings(self.__cookiesFile, QSettings.Format.IniFormat) + cookieSettings.setValue("Exceptions/block", self.__exceptionsBlock) cookieSettings.setValue("Exceptions/allow", self.__exceptionsAllow) - cookieSettings.setValue("Exceptions/allowForSession", - self.__exceptionsAllowForSession) - + cookieSettings.setValue( + "Exceptions/allowForSession", self.__exceptionsAllowForSession + ) + Preferences.setWebBrowser("AcceptCookies", self.__acceptCookies) Preferences.setWebBrowser("KeepCookiesUntil", self.__keepCookies) - Preferences.setWebBrowser("FilterTrackingCookies", - self.__filterTrackingCookies) - + Preferences.setWebBrowser("FilterTrackingCookies", self.__filterTrackingCookies) + @pyqtSlot(QNetworkCookie) def __cookieAdded(self, cookie): """ Private slot handling the addition of a cookie. - + @param cookie cookie which was added @type QNetworkCookie """ if self.__rejectCookie(cookie, cookie.domain()): self.__store.deleteCookie(cookie) return - + self.insertCookie(cookie) self.cookiesChanged.emit() - + @pyqtSlot(QNetworkCookie) def __cookieRemoved(self, cookie): """ Private slot handling the removal of a cookie. - + @param cookie cookie which was removed @type QNetworkCookie """ if self.deleteCookie(cookie): self.cookiesChanged.emit() - + def __cookieFilter(self, request): """ Private method to filter cookies. - + Note: This method is used for Qt 5.11+ only. - + @param request reference to the cookie filter request object @type QWebEngineCookieStore.FilterRequest @return flag indicating cookie access is allowed @@ -201,31 +205,29 @@ """ if not self.__loaded: self.__load() - + if self.__acceptCookies == self.AcceptNever: - res = self.__isOnDomainList(self.__exceptionsAllow, - request.origin.host()) + res = self.__isOnDomainList(self.__exceptionsAllow, request.origin.host()) if not res: return False - + if self.__acceptCookies == self.AcceptAlways: - res = self.__isOnDomainList(self.__exceptionsBlock, - request.origin.host()) + res = self.__isOnDomainList(self.__exceptionsBlock, request.origin.host()) if res: return False - + if ( - self.__acceptCookies == self.AcceptOnlyFromSitesNavigatedTo and - request.thirdParty + self.__acceptCookies == self.AcceptOnlyFromSitesNavigatedTo + and request.thirdParty ): return False - + return True - + def __rejectCookie(self, cookie, cookieDomain): """ Private method to test, if a cookie shall be rejected. - + @param cookie cookie to be tested @type QNetworkCookie @param cookieDomain domain of the cookie @@ -235,17 +237,17 @@ """ if not self.__loaded: self.__load() - + if self.__acceptCookies == self.AcceptNever: res = self.__isOnDomainList(self.__exceptionsAllow, cookieDomain) if not res: return True - + if self.__acceptCookies == self.AcceptAlways: res = self.__isOnDomainList(self.__exceptionsBlock, cookieDomain) if res: return True - + if self.__acceptCookies == self.AcceptOnlyFromSitesNavigatedTo: mainWindow = WebBrowserWindow.mainWindow() if mainWindow is not None: @@ -259,165 +261,165 @@ res = self.__matchDomain(cookieDomain, host) if not res: return True - + if self.__filterTrackingCookies and cookie.name().startsWith(b"__utm"): return True - + return False - + def acceptPolicy(self): """ Public method to get the accept policy. - + @return current accept policy """ if not self.__loaded: self.__load() - + return self.__acceptCookies - + def setAcceptPolicy(self, policy): """ Public method to set the accept policy. - + @param policy accept policy to be set """ if not self.__loaded: self.__load() - + if policy > self.AcceptMax: return if policy == self.__acceptCookies: return - + self.__acceptCookies = policy self.__saveTimer.changeOccurred() - + def keepPolicy(self): """ Public method to get the keep policy. - + @return keep policy """ if not self.__loaded: self.__load() - + return self.__keepCookies - + def setKeepPolicy(self, policy): """ Public method to set the keep policy. - + @param policy keep policy to be set """ if not self.__loaded: self.__load() - + if policy > self.KeepMax: return if policy == self.__keepCookies: return - + self.__keepCookies = policy self.__saveTimer.changeOccurred() - + def blockedCookies(self): """ Public method to return the list of blocked domains. - + @return list of blocked domains (list of strings) """ if not self.__loaded: self.__load() - + return self.__exceptionsBlock - + def allowedCookies(self): """ Public method to return the list of allowed domains. - + @return list of allowed domains (list of strings) """ if not self.__loaded: self.__load() - + return self.__exceptionsAllow - + def allowForSessionCookies(self): """ Public method to return the list of allowed session cookie domains. - + @return list of allowed session cookie domains (list of strings) """ if not self.__loaded: self.__load() - + return self.__exceptionsAllowForSession - + def setBlockedCookies(self, list_): """ Public method to set the list of blocked domains. - + @param list_ list of blocked domains (list of strings) """ if not self.__loaded: self.__load() - + self.__exceptionsBlock = list_[:] self.__exceptionsBlock.sort() self.__saveTimer.changeOccurred() - + def setAllowedCookies(self, list_): """ Public method to set the list of allowed domains. - + @param list_ list of allowed domains (list of strings) """ if not self.__loaded: self.__load() - + self.__exceptionsAllow = list_[:] self.__exceptionsAllow.sort() self.__saveTimer.changeOccurred() - + def setAllowForSessionCookies(self, list_): """ Public method to set the list of allowed session cookie domains. - + @param list_ list of allowed session cookie domains (list of strings) """ if not self.__loaded: self.__load() - + self.__exceptionsAllowForSession = list_[:] self.__exceptionsAllowForSession.sort() self.__saveTimer.changeOccurred() - + def filterTrackingCookies(self): """ Public method to get the filter tracking cookies flag. - + @return filter tracking cookies flag (boolean) """ return self.__filterTrackingCookies - + def setFilterTrackingCookies(self, filterTrackingCookies): """ Public method to set the filter tracking cookies flag. - + @param filterTrackingCookies filter tracking cookies flag (boolean) """ if filterTrackingCookies == self.__filterTrackingCookies: return - + self.__filterTrackingCookies = filterTrackingCookies self.__saveTimer.changeOccurred() - + def __isOnDomainList(self, rules, domain): """ Private method to check, if either the rule matches the domain exactly or the domain ends with ".rule". - + @param rules list of rules (list of strings) @param domain domain name to check (string) @return flag indicating a match (boolean) @@ -426,29 +428,25 @@ if rule.startswith("."): if domain.endswith(rule): return True - + withoutDot = rule[1:] if domain == withoutDot: return True else: - domainEnding = domain[-(len(rule) + 1):] - if ( - domainEnding and - domainEnding[0] == "." and - domain.endswith(rule) - ): + domainEnding = domain[-(len(rule) + 1) :] + if domainEnding and domainEnding[0] == "." and domain.endswith(rule): return True - + if rule == domain: return True - + return False - + def __matchDomain(self, cookieDomain, siteDomain): """ Private method to check, if a URLs host matches a cookie domain according to RFC 6265. - + @param cookieDomain domain of the cookie @type str @param siteDomain domain or host of an URL @@ -459,36 +457,36 @@ if not siteDomain: # empty URLs always match return True - + if cookieDomain.startswith("."): cookieDomain = cookieDomain[1:] if siteDomain.startswith("."): siteDomain = siteDomain[1:] - + if cookieDomain == siteDomain: return True - + if not siteDomain.endswith(cookieDomain): return False - + index = siteDomain.find(cookieDomain) return index > 0 and siteDomain[index - 1] == "." - + def cookies(self): """ Public method to get the cookies of the cookie jar. - + @return list of all cookies (list of QNetworkCookie) """ if not self.__loaded: self.__load() - + return self.allCookies() - + def cookieDomains(self): """ Public method to get a list of all domains used by the cookies. - + @return list of domain names @rtype list of str """ @@ -497,5 +495,5 @@ domain = cookie.domain() if domain not in domains: domains.append(domain) - + return domains