From b64a617615eb2e869e86742c1785483ec1ada2dd Mon Sep 17 00:00:00 2001 From: Alexandr Date: Mon, 25 Jan 2021 11:31:25 +0300 Subject: [PATCH] init --- .gitignore | 78 ++++++ README.md | 3 + _locales/en/messages.json | 8 + _locales/ru/messages.json | 8 + app128.png | Bin 0 -> 9862 bytes app32.png | Bin 0 -> 2092 bytes app64.png | Bin 0 -> 5005 bytes data/content.js | 103 ++++++++ data/options.html | 17 ++ data/options.js | 58 +++++ example/example.py | 40 +++ example/selenium_helper.py | 350 ++++++++++++++++++++++++++ manifest.json | 40 +++ releases/selenium_helper-0.0.4-fx.xpi | Bin 0 -> 28799 bytes 14 files changed, 705 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 _locales/en/messages.json create mode 100644 _locales/ru/messages.json create mode 100644 app128.png create mode 100644 app32.png create mode 100644 app64.png create mode 100644 data/content.js create mode 100644 data/options.html create mode 100644 data/options.js create mode 100644 example/example.py create mode 100644 example/selenium_helper.py create mode 100644 manifest.json create mode 100644 releases/selenium_helper-0.0.4-fx.xpi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f242497 --- /dev/null +++ b/.gitignore @@ -0,0 +1,78 @@ +.idea/ +bin/ +# Created by .ignore support plugin (hsz.mobi) +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ +*.mo +*.pot +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache +.scrapy +docs/_build/ +.pybuilder/ +target/ +.ipynb_checkpoints +profile_default/ +ipython_config.py +__pypackages__/ +celerybeat-schedule +celerybeat.pid +*.sage.py +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.spyderproject +.spyproject +.ropeproject +/site +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ +cython_debug/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..d5aa330 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Дополнение, которое дает возможность установить в браузер прокси с авторизацией по логину и паролю, а также дает возможность установить куки без предварительного открытия страницы для которой эти куки предназначены. + +Пример есть в директории example diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..de5421b --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,8 @@ +{ + "name": { + "message": "Selenium helper for setup proxy and cookies" + }, + "description": { + "message": "Setup proxy with authentication and cookies" + } +} diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json new file mode 100644 index 0000000..c5b85ef --- /dev/null +++ b/_locales/ru/messages.json @@ -0,0 +1,8 @@ +{ + "name": { + "message": "Selenium helper" + }, + "description": { + "message": "Это расширение дает возможность установить в браузер прокси с авторизацией и куки без предварительного открытия страницы для которой эти куки предназначены." + } +} diff --git a/app128.png b/app128.png new file mode 100644 index 0000000000000000000000000000000000000000..cb199c309361f4c58a06a192d35a43ca955ff334 GIT binary patch literal 9862 zcmV;1CVAP3P)SW6Ou`@|#&Y8(1q@nqqCqFX#lzq-#XP5PT zYi+1N1u9U13RIv1B?MhrSHK&y|0hAtez&v1NSy!Y2rHgL>o73N$Wm=;Olq!@Azy^FwMGyS1fGY#A zA%+BP*;TE=0?Qf?0BZo>vZ_FZ0hBW0TQ+q5sUz?s5LEiLsX%GKVF)<9^;_GB2YM(C z2M2*lrCqs-9-x$=R;&1E+H;I~<^kuTFv?&k__rHCY|dY)W8%xhd1vzTNRouNmlt2p zdOrct3sj&K;0;U$(sTYM0bV6^FNY!E*!Fq0j8i|^GEV(u%et`L_RZ`MY^#=jYs*eK zW6QpI_5+*EX8$PtN~k^#kV@kw

gD=KUrR<5YGI7!52yG*&?f0_q{g?ZBM>gK#t? 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 literal 0 HcmV?d00001 diff --git a/app32.png b/app32.png new file mode 100644 index 0000000000000000000000000000000000000000..509604ff2f60dcfbb86ed2f63bf179da84ded28a GIT binary patch literal 2092 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 -1) { + pendingRequests.splice(index, 1); + } + } + + function provideCredentialsSync(requestDetails) { + // If we have seen this request before, then + // assume our credentials were bad, and give up. + if (pendingRequests.indexOf(requestDetails.requestId) != -1) { + console.log(`bad credentials for: ${requestDetails.requestId}`); + return {cancel: true}; + } + pendingRequests.push(requestDetails.requestId); + console.log(`providing credentials for: ${requestDetails.requestId}`); + return {authCredentials: CREDENTIALS}; + } + + browser.proxy.onRequest.addListener( + handleProxyRequest, + {urls: [TARGET]} + ); + + browser.webRequest.onAuthRequired.addListener( + provideCredentialsSync, + {urls: [TARGET]}, + ["blocking"] + ); + + browser.webRequest.onCompleted.addListener( + completed, + {urls: [TARGET]} + ); + + browser.webRequest.onErrorOccurred.addListener( + completed, + {urls: [TARGET]} + ); +} + + +function main() { + + function setProxy(result) { + if (result.proxy) { + console.log("Setup proxy..."); + set_proxy(result.proxy); + } + } + + function setCookies(result) { + if (result.cookies) { + console.log("Setup cookies..."); + set_cookies(result.cookies); + } + } + + function onError(error) { + console.log(`Error: ${error}`); + } + + let proxy = browser.storage.sync.get("proxy"); + proxy.then(setProxy, onError); + + let cookies = browser.storage.sync.get("cookies"); + cookies.then(setCookies, onError); +} + + +browser.runtime.onMessage.addListener(function(message, sender, reply) { + if (message.update) { + main(); + } +}); diff --git a/data/options.html b/data/options.html new file mode 100644 index 0000000..4114894 --- /dev/null +++ b/data/options.html @@ -0,0 +1,17 @@ + + + + + +

+ + + + + + + +
+ + + diff --git a/data/options.js b/data/options.js new file mode 100644 index 0000000..bfbf4a5 --- /dev/null +++ b/data/options.js @@ -0,0 +1,58 @@ +function saveOptions(e) { + e.preventDefault(); + let cookies = []; + try { + cookies = JSON.parse(document.getElementById("cookies").value); + } catch {}; + console.log(cookies) + browser.storage.sync.set({ + proxy: { + "type": document.getElementById("type").value, + "host": document.getElementById("host").value, + "port": document.getElementById("port").value, + "username": document.getElementById("username").value, + "password": document.getElementById("password").value + }, + cookies: cookies + }); +} + + +function restoreOptions() { + + function setCurrentProxy(result) { + if (result.proxy) { + document.getElementById("type").value = result.proxy.type; + document.getElementById("host").value = result.proxy.host; + document.getElementById("port").value = result.proxy.port; + document.getElementById("username").value = result.proxy.username; + document.getElementById("password").value = result.proxy.password; + } + } + + function setCurrentCookies(result) { + if (result.cookies) { + document.getElementById("cookies").value = JSON.stringify(result.cookies); + } + } + + function onError(error) { + console.log(`Error: ${error}`); + } + + let proxy = browser.storage.sync.get("proxy"); + proxy.then(setCurrentProxy, onError); + + let cookies = browser.storage.sync.get("cookies"); + cookies.then(setCurrentCookies, onError); +} + + +function notifyExtension(e) { + browser.runtime.sendMessage({"update": true}); +} + + +document.addEventListener("DOMContentLoaded", restoreOptions); +document.getElementById("options_form").addEventListener("submit", saveOptions); +window.addEventListener("submit", notifyExtension); diff --git a/example/example.py b/example/example.py new file mode 100644 index 0000000..4fba584 --- /dev/null +++ b/example/example.py @@ -0,0 +1,40 @@ +import logging +import os.path + +import selenium.webdriver + +import selenium_helper + + +def main(): + logger = logging.getLogger(__name__) + profile = selenium.webdriver.FirefoxProfile() + # отключаем предупреждение при открытии about:config + profile.set_preference("browser.aboutConfig.showWarning", False) + # отключаем трекинг navigator.webdriver + profile.set_preference("dom.webdriver.enabled", False) + # отключаем уведомления от сайтов + profile.set_preference("dom.webnotifications.enabled", False) + + driver = selenium.webdriver.Firefox( + firefox_binary="bin/firefox-84.0.2/firefox-bin", executable_path="bin/geckodriver", firefox_profile=profile) + + try: + selenium_helper_extention = selenium_helper.SeleniumHelperExtension(driver) + selenium_helper_extention.install(os.path.abspath("releases/selenium_helper-0.0.4-fx.xpi")) + proxy = "http://username:password@host:port" + cookies = [ + selenium_helper.Cookie(name="cookie", value="test", url="https://whoer.net") + ] + selenium_helper_extention.begin_options().set_proxy(proxy).set_cookies(cookies).apply_options() + + driver.get("https://whoer.net/") + input("Enter to exit...") + except Exception as e: + logger.exception(f"{type(e).__name__}{getattr(e, 'args', None)}") + finally: + driver.quit() + + +if __name__ == '__main__': + main() diff --git a/example/selenium_helper.py b/example/selenium_helper.py new file mode 100644 index 0000000..8c0f0f4 --- /dev/null +++ b/example/selenium_helper.py @@ -0,0 +1,350 @@ +#!/usr/bin/env python3 +# -*- encoding: utf-8 -*- +# +# Created at 19.01.2021. +# Python 3.7.3 x64 +# Contacts: alexandrsokolov@cock.li +# +import copy +import json +import urllib.parse +from functools import lru_cache +from typing import List + +from selenium.common.exceptions import NoSuchElementException +from selenium.webdriver import Firefox +from selenium.webdriver.common.keys import Keys + +OPTION_PROXY_TYPE = "proxy_type" +OPTION_PROXY_HOST = "proxy_host" +OPTION_PROXY_PORT = "proxy_port" +OPTION_PROXY_USERNAME = "proxy_username" +OPTION_PROXY_PASSWORD = "proxy_password" +OPTION_PROXY_COOKIES = "proxy_cookies" + + +class NoAddonException(Exception): + pass + + +class CookieException(Exception): + pass + + +class Cookie(dict): + """https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/set""" + + def __init__(self, *, domain=None, expiration_date=None, first_party_domain=None, http_only=None, name=None, + path=None, same_site=None, secure=None, store_id=None, url=None, value=None): + super().__init__() + if domain: + self.domain = domain + if expiration_date: + self.expiration_date = expiration_date + if first_party_domain: + self.first_party_domain = first_party_domain + if http_only: + self.http_only = http_only + if name: + self.name = name + if path: + self.path = path + if same_site: + self.same_site = same_site + if secure: + self.secure = secure + if store_id: + self.store_id = store_id + if url: + self.url = url + if value: + self.value = value + + @property + def domain(self): + """A string representing the domain of the cookie. If omitted, the cookie becomes a host-only cookie.""" + return self.get("domain") + + @domain.setter + def domain(self, value): + self["domain"] = value + + @domain.deleter + def domain(self): + del self["domain"] + + @property + def expiration_date(self): + """A number that represents the expiration date of the cookie as the number of seconds since the UNIX epoch. + If omitted, the cookie becomes a session cookie.""" + return self.get("expirationDate") + + @expiration_date.setter + def expiration_date(self, value): + self["expirationDate"] = value + + @expiration_date.deleter + def expiration_date(self): + del self["expirationDate"] + + @property + def first_party_domain(self): + """A string representing the first-party domain with which the cookie to will be associated. + This property must be supplied if the browser has first-party isolation enabled. See First-party isolation + https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies#First-party_isolation""" + return self.get("firstPartyDomain") + + @first_party_domain.setter + def first_party_domain(self, value): + self["firstPartyDomain"] = value + + @first_party_domain.deleter + def first_party_domain(self): + del self["firstPartyDomain"] + + @property + def http_only(self): + """A boolean that specifies whether the cookie should be marked as HttpOnly (true), or not (false). + If omitted, it defaults to false.""" + return self.get("httpOnly") + + @http_only.setter + def http_only(self, value): + self["httpOnly"] = value + + @http_only.deleter + def http_only(self): + del self["httpOnly"] + + @property + def name(self): + """A string representing the name of the cookie. If omitted, this is empty by default.""" + return self.get("name") + + @name.setter + def name(self, value): + self["name"] = value + + @name.deleter + def name(self): + del self["name"] + + @property + def path(self): + """A string representing the path of the cookie. + If omitted, this defaults to the path portion of the URL parameter.""" + return self.get("path") + + @path.setter + def path(self, value): + self["path"] = value + + @path.deleter + def path(self): + del self["path"] + + @property + def same_site(self): + """A cookies.SameSiteStatus value that indicates the SameSite state of the cookie. + If omitted, it defaults to 0, 'no_restriction'. + https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/SameSiteStatus""" + return self.get("sameSite") + + @same_site.setter + def same_site(self, value): + self["sameSite"] = value + + @same_site.deleter + def same_site(self): + del self["sameSite"] + + @property + def secure(self): + """A boolean that specifies whether the cookie should be marked as secure (true), or not (false). + If omitted, it defaults to false.""" + return self.get("secure") + + @secure.setter + def secure(self, value): + self["secure"] = value + + @secure.deleter + def secure(self): + del self["secure"] + + @property + def store_id(self): + """A string representing the ID of the cookie store in which to set the cookie. + If omitted, the cookie is set in the current execution context's cookie store by default.""" + return self.get("storeId") + + @store_id.setter + def store_id(self, value): + self["storeId"] = value + + @store_id.deleter + def store_id(self): + del self["storeId"] + + @property + def url(self): + """A string representing the request-URI to associate with the cookie. + This value can affect the default domain and path values of the created cookie.""" + return self.get("url") + + @url.setter + def url(self, value): + self["url"] = value + + @url.deleter + def url(self): + del self["url"] + + @property + def value(self): + """A string representing the value of the cookie. + If omitted, this is empty by default.""" + return self.get("value") + + @value.setter + def value(self, value): + self["value"] = value + + @value.deleter + def value(self): + del self["value"] + + +class SeleniumHelperExtension: + """Обертка для установки и настройки дополнения""" + + _uuid = None + + _options = { + OPTION_PROXY_TYPE: "type", + OPTION_PROXY_HOST: "host", + OPTION_PROXY_PORT: "port", + OPTION_PROXY_USERNAME: "username", + OPTION_PROXY_PASSWORD: "password", + OPTION_PROXY_COOKIES: "cookies" + } + + def __init__(self, driver: Firefox, raise_for_about_config=True): + self.raise_for_about_config = raise_for_about_config + self._driver = driver + + @property + def uuid(self): + return self._uuid + + @property + def internal_uuid(self): + installed_addons = json.loads(self._get_preference("extensions.webextensions.uuids")) + try: + return installed_addons[self.uuid] + except KeyError: + raise NoAddonException("Addon `selenium_helper` not found. Is it installed?") + + @property + def setup_url(self): + return f"moz-extension://{self.internal_uuid}/data/options.html" + + def set_uuid(self, uuid: str): + """если дополнение уже установлено, требуется его UUID для того чтобы найти дополнение в списке + установленных и получить его внутренний UUID""" + self._uuid = uuid + + def install_debug(self): + """открываем страницу отладки дополнений и предоставляем возможность установить дополнение из файла""" + self._driver.get("about:debugging#/runtime/this-firefox") + if self._uuid: + input("Install extension from file and press Enter to continue...") + else: + self._uuid = input("Install extension from file and enter UUID:") + + def install(self, xpi_path: str): + """установка дополнения в браузер""" + self._uuid = self._driver.install_addon(xpi_path) + + def begin_options(self): + """открываем настройки дополнения""" + self._driver.get(self.setup_url) + return self + + def set_proxy(self, proxy_string: str): + """заполняем поля для прокси""" + proxy = urllib.parse.urlparse(proxy_string) + self._fill_option(OPTION_PROXY_TYPE, proxy.scheme) + self._fill_option(OPTION_PROXY_HOST, proxy.hostname) + self._fill_option(OPTION_PROXY_PORT, proxy.port) + self._fill_option(OPTION_PROXY_USERNAME, proxy.username) + self._fill_option(OPTION_PROXY_PASSWORD, proxy.password) + return self + + def set_cookies(self, cookies: List[Cookie], default_url=None, ignore_errors=False): + """устанавливаем куки. у кук должен быть url, если его нет, то попытаемся создать его из полей domain и path, + если это не получится сделать, то будем использовать переменную default_url, если она не установлена, + то выбрасываем исключение, а если ignore_errors установлен в True, то пропускаем проблемную куку.""" + clear_value = self._clear_cookies(cookies, default_url, ignore_errors) + + value = json.dumps(clear_value) + + self._fill_option(OPTION_PROXY_COOKIES, value) + return self + + def apply_options(self): + """сохраняем изменения сделанные на странице настроек""" + self._driver.find_element_by_id("submit").click() + + def _clear_cookies(self, cookies: List[Cookie], default_url=None, ignore_errors=False): + clear_value = [] + + for cookie in copy.deepcopy(cookies): + if not cookie.get("url"): + try: + domain = cookie["domain"][1:] if cookie["domain"].startswith(".") else cookie["domain"] + url = f"http://{domain}{cookie.get('path', '/')}" + except KeyError: + url = default_url + + if url is None: + if ignore_errors: + continue + else: + raise CookieException(f"No url specified for cookie {cookie}") + + cookie["url"] = url + clear_value.append(cookie) + return clear_value + + def _fill_option(self, name, value): + self._fill_element(self._driver.find_element_by_id(self._options[name]), value) + + @lru_cache() + def _get_preference(self, name): + + def get_search_box_with_wait_about_config_approved(): + try: + search_box = self._driver.find_element_by_id("about-config-search") # noqa + except NoSuchElementException: + if self.raise_for_about_config: + raise + else: + input("Approve warning message and press Enter to continue...") + return get_search_box_with_wait_about_config_approved() + else: + return search_box + + self._driver.get("about:config") + + search_box = get_search_box_with_wait_about_config_approved() + search_box.clear() + search_box.send_keys(name) + search_box.send_keys(Keys.ENTER) + + search_result = self._driver.find_elements_by_xpath("//table[@id='prefs']/tr/td/span") + return search_result[0].text + + def _fill_element(self, element, value: str): # noqa + element.clear() + element.send_keys(value) diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..769646d --- /dev/null +++ b/manifest.json @@ -0,0 +1,40 @@ +{ + "manifest_version": 2, + "version": "0.0.4", + "minimum_chrome_version": "76.0", + "applications": { + "gecko": { + "id": "eet1ra8cauDu@AlexandrSokolov" + } + }, + "default_locale": "en", + "name": "__MSG_name__", + "short_name": "__MSG_name__", + "description": "__MSG_description__", + "author": "Alexandr Sokolov", + "homepage_url": "https://github.com/alexsok-bit/selenium_helper", + "icons": { + "32": "app32.png", + "64": "app64.png", + "128": "app128.png" + }, + "permissions": [ + "proxy", + "storage", + "cookies", + "webRequest", + "webRequestBlocking", + "" + ], + "options_ui": { + "page": "data/options.html" + }, + "browser_specific_settings": { + "gecko": { + "id": "eet1ra8cauDu@AlexandrSokolov" + } + }, + "background": { + "scripts": ["data/content.js"] + } +} diff --git a/releases/selenium_helper-0.0.4-fx.xpi b/releases/selenium_helper-0.0.4-fx.xpi new file mode 100644 index 0000000000000000000000000000000000000000..5da9238c5760c669d6eebb8ab88d5531f48bd3b7 GIT binary patch literal 28799 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ʗ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 literal 0 HcmV?d00001