diff options
9 files changed, 367 insertions, 79 deletions
diff --git a/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po b/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po index defbbcc..bb41daf 100644 --- a/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po +++ b/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: hydrilla 2.0\n" "Report-Msgid-Bugs-To: koszko@koszko.org\n" -"POT-Creation-Date: 2022-10-19 09:36+0200\n" +"POT-Creation-Date: 2022-10-22 11:17+0200\n" "PO-Revision-Date: 2022-02-12 00:00+0000\n" "Last-Translator: Wojtek Kosior <koszko@koszko.org>\n" "Language: en_US\n" @@ -79,7 +79,7 @@ msgid "built_package_files_destination" msgstr "Destination directory to write built package files to." #: src/hydrilla/builder/build.py:499 -#: src/hydrilla/mitmproxy_launcher/launch.py:69 +#: src/hydrilla/mitmproxy_launcher/launch.py:66 #: src/hydrilla/server/serve.py:211 src/hydrilla/server/serve.py:229 #: src/hydrilla/server/serve.py:269 #, python-format @@ -164,7 +164,7 @@ msgstr "Not a valid JSON file." msgid "no_schema_number_in_instance" msgstr "JSON schema number is missing from a document." -#: src/hydrilla/mitmproxy_launcher/launch.py:58 +#: src/hydrilla/mitmproxy_launcher/launch.py:55 msgid "cli_help.haketilo" msgstr "" "Run Haketilo proxy.\n" @@ -172,52 +172,52 @@ msgstr "" "This command starts Haketilo as a local HTTP proxy which a web browser " "can then use." -#: src/hydrilla/mitmproxy_launcher/launch.py:60 +#: src/hydrilla/mitmproxy_launcher/launch.py:57 msgid "cli_opt.haketilo.listen_host" msgstr "IP address port number the proxy should listen on." -#: src/hydrilla/mitmproxy_launcher/launch.py:62 +#: src/hydrilla/mitmproxy_launcher/launch.py:59 msgid "cli_opt.haketilo.port" msgstr "TCP port number the proxy should listen on." -#: src/hydrilla/mitmproxy_launcher/launch.py:64 +#: src/hydrilla/mitmproxy_launcher/launch.py:61 msgid "cli_opt.haketilo.launch_browser" msgstr "" "Whether Haketilo should try to open its landing page in your default " "browser. Defaults to yes ('-L')." -#: src/hydrilla/mitmproxy_launcher/launch.py:67 +#: src/hydrilla/mitmproxy_launcher/launch.py:64 msgid "cli_opt.haketilo.dir_defaults_to_{}" msgstr "Data directory for Haketilo to use. Defaults to \"{}\"." -#: src/hydrilla/mitmproxy_launcher/launch.py:70 +#: src/hydrilla/mitmproxy_launcher/launch.py:67 msgid "cli_opt.haketilo.version" msgstr "Print version information and exit" -#: src/hydrilla/proxy/addon.py:167 +#: src/hydrilla/proxy/addon.py:192 msgid "warn.proxy.setting_already_configured_{}" msgstr "" "Attempt was made to configure Mitmproxy addon's option '{}' which has " "already been configured." -#: src/hydrilla/proxy/addon.py:202 +#: src/hydrilla/proxy/addon.py:227 msgid "warn.proxy.couldnt_launch_browser" msgstr "" "Failed to open a URL in a web browser. Do you have a default web browser " "configured?" -#: src/hydrilla/proxy/addon.py:246 +#: src/hydrilla/proxy/addon.py:268 msgid "err.proxy.unknown_error_{}_try_again" msgstr "" "Haketilo experienced an error. Try again.\n" "\n" "{}" -#: src/hydrilla/proxy/policies/payload_resource.py:261 +#: src/hydrilla/proxy/policies/payload_resource.py:250 msgid "api.file_not_found" msgstr "Requested file could not be found." -#: src/hydrilla/proxy/policies/payload_resource.py:384 +#: src/hydrilla/proxy/policies/payload_resource.py:368 msgid "api.resource_not_enabled_for_access" msgstr "Requested resource is not enabled for access." @@ -233,7 +233,7 @@ msgstr "" "This installation of Haketilo uses an SQLite version which does not " "support foreign key constraints." -#: src/hydrilla/proxy/state_impl/concrete_state.py:218 +#: src/hydrilla/proxy/state_impl/concrete_state.py:227 msgid "warn.proxy.failed_to_register_landing_page_at_{}" msgstr "Failed to register landing page at \"{}\"." @@ -349,21 +349,21 @@ msgstr "Add new package" msgid "web_ui.home.title" msgstr "Welcome" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:27 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:35 msgid "web_ui.home.heading.welcome_to_haketilo" msgstr "Welcome to Haketilo!" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:31 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:39 msgid "web_ui.home.this_is_haketilo_page" msgstr "" "This is a virtual site hosted locally by Haketilo. You can use it to " "configure Haketilo proxy." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:37 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:45 msgid "web_ui.home.heading.about_haketilo" msgstr "About this tool" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:41 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:49 msgid "web_ui.home.html.haketilo_is_blah_blah" msgstr "" "Haketilo is a tool that gives users more control over their web browsing." @@ -372,11 +372,11 @@ msgstr "" "extension but has since been made into an HTTP proxy. It is built on top " "of the popular <a href=\"https://mitmproxy.org/\">mitmproxy</a>." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:48 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:56 msgid "web_ui.home.heading.configuring_browser_for_haketilo" msgstr "Configuring the browser for Haketilo" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:52 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:60 msgid "web_ui.home.html.to_add_certs_do_xyz" msgstr "" "Haketilo proxy works by modifying data exchanged by your browser and web " @@ -388,110 +388,176 @@ msgstr "" "href=\"http://mitm.it\">this page</a> and add it to your operating " "system, browser or both." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:59 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:67 msgid "web_ui.home.heading.options" msgstr "Global options" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:62 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:70 msgid "web_ui.home.mapping_usage_mode_label" msgstr "Package usage mode" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:71 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:79 msgid "web_ui.home.packages_are_used_when_enabled" msgstr "" "Hektilo is currently configured to only use packages that were explicitly" " enabled." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:74 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:82 msgid "web_ui.home.user_gets_asked_whether_to_enable_package" msgstr "" "Hektilo is currently configured to ask whenever a package is found that " "could be used for the current site." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:78 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:86 msgid "web_ui.home.packages_are_used_automatically" msgstr "" "Hektilo is currently configured to automatically use packages that are " "available for the current site." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:85 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:93 msgid "web_ui.home.use_enabled_button" msgstr "Use when enabled" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:88 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:96 msgid "web_ui.home.use_question_button" msgstr "Ask whether to use" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:91 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:99 msgid "web_ui.home.use_auto_button" msgstr "Use automatically" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:98 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:106 msgid "web_ui.home.script_blocking_mode_label" msgstr "Default scripts treatment" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:106 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:114 msgid "web_ui.home.scripts_are_allowed_by_default" msgstr "" "By default Haketilo currently allows JavaScript sent by websites to the " "browser to execute." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:109 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:117 msgid "web_ui.home.scripts_are_blocked_by_default" msgstr "" "By default Haketilo currently blocks JavaScript sent by websites to the " "browser from executing." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:113 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:121 msgid "web_ui.home.allow_scripts_button" msgstr "Allow scripts" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:114 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:122 msgid "web_ui.home.block_scripts_button" msgstr "Block scripts" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:125 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:133 msgid "web_ui.home.advanced_features_label" msgstr "Advanced features" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:133 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:141 msgid "web_ui.home.user_is_advanced_user" msgstr "Interface features for advanced users are currently enabled." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:136 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:144 msgid "web_ui.home.user_is_simple_user" msgstr "Interface features for advanced users are currently disabled." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:143 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:151 msgid "web_ui.home.user_make_advanced_button" msgstr "Enable" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:146 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:154 msgid "web_ui.home.user_make_simple_button" msgstr "Disable" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:154 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:162 msgid "web_ui.home.orphans_label" msgstr "Orphans" -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:160 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:168 msgid "web_ui.home.orphans_to_delete_{mappings}" msgstr "Haketilo is holding some unused packages that can be removed ({mappings})." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:164 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:172 msgid "web_ui.home.orphans_to_delete_exist" msgstr "Haketilo is holding some unused libraries that can be removed." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:168 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:176 msgid "web_ui.home.orphans_to_delete_{mappings}_{resources}" msgstr "" "Haketilo is holding some unused items that can be removed (packages: " "{mappings}; libraries: {resources})." -#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:177 +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:185 msgid "web_ui.home.prune_orphans_button" msgstr "Prune orphans" +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:196 +msgid "web_ui.home.popup_settings_label" +msgstr "Popup settings" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:210 +msgid "web_ui.home.configure_popup_settings_on_pages_with" +msgstr "Configure popup settings on pages with" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:216 +msgid "web_ui.home.popup_settings_jsallowed_button" +msgstr "JS allowed" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:217 +msgid "web_ui.home.popup_settings_jsblocked_button" +msgstr "JS blocked" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:218 +msgid "web_ui.home.popup_settings_payloadon_button" +msgstr "Payload used" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:268 +msgid "web_ui.home.popup_no_button" +msgstr "Disable popup" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:271 +msgid "web_ui.home.popup_yes_button" +msgstr "Enable popup" + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:281 +msgid "web_ui.home.jsallowed_popup_yes" +msgstr "" +"Haketilo currently makes it possible to open its popup window on pages " +"where native JS has been allowed to execute. This is a convenience that " +"comes at a price of greater risk of user fingerprinting." + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:283 +msgid "web_ui.home.jsallowed_popup_no" +msgstr "" +"Haketilo currently does not make it possible to open its popup window on " +"pages with their native JS allowed. This setting is less convenient but " +"decreases the risk of user fingerprinting." + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:289 +msgid "web_ui.home.jsblocked_popup_yes" +msgstr "" +"Haketilo currently makes it possible to open its popup window on pages " +"where native JS has been blocked from executing." + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:291 +msgid "web_ui.home.jsblocked_popup_no" +msgstr "" +"Haketilo currently does not make it possible to open its popup window on " +"pages where native JS has been blocked from executing." + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:297 +msgid "web_ui.home.payloadon_popup_yes" +msgstr "" +"Haketilo currently makes it possible to open its popup window on pages " +"where payload is used." + +#: src/hydrilla/proxy/web_ui/templates/index.html.jinja:299 +msgid "web_ui.home.payloadon_popup_no" +msgstr "" +"Haketilo currently does not make it possible to open its popup window on " +"pages where payload is used." + #: src/hydrilla/proxy/web_ui/templates/items/item_view.html.jinja:44 #: src/hydrilla/proxy/web_ui/templates/prompts/package_suggestion.html.jinja:30 #: src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja:35 diff --git a/src/hydrilla/proxy/state.py b/src/hydrilla/proxy/state.py index f047a68..d21a392 100644 --- a/src/hydrilla/proxy/state.py +++ b/src/hydrilla/proxy/state.py @@ -617,12 +617,12 @@ class HaketiloState(ABC): def update_settings( self, *, - mapping_use_mode: t.Optional[MappingUseMode] = None, - default_allow_scripts: t.Optional[bool] = None, - advanced_user: t.Optional[bool] = None, - repo_refresh_seconds: t.Optional[int] = None + mapping_use_mode: t.Optional[MappingUseMode] = None, + default_allow_scripts: t.Optional[bool] = None, + advanced_user: t.Optional[bool] = None, + repo_refresh_seconds: t.Optional[int] = None, + default_popup_settings: t.Mapping[str, PopupSettings] = {} ) -> None: - """....""" ... @property diff --git a/src/hydrilla/proxy/state_impl/concrete_state.py b/src/hydrilla/proxy/state_impl/concrete_state.py index 2dd8810..5df7c34 100644 --- a/src/hydrilla/proxy/state_impl/concrete_state.py +++ b/src/hydrilla/proxy/state_impl/concrete_state.py @@ -55,6 +55,22 @@ from . import _operations here = Path(__file__).resolve().parent +def _add_popup_settings_columns(cursor: sqlite3.Cursor) -> None: + for page_type in ('jsallowed', 'jsblocked', 'payloadon'): + cursor.execute( + f''' + ALTER TABLE general ADD COLUMN + default_popup_{page_type}_onkeyboard BOOLEAN NOT NULL DEFAULT TRUE; + ''' + ) + cursor.execute( + f''' + ALTER TABLE general ADD COLUMN + default_popup_{page_type}_style CHAR(1) NOT NULL DEFAULT 'T' + CHECK (default_popup_{page_type}_style IN ('D', 'T')); + ''' + ) + def _prepare_database(connection: sqlite3.Connection) -> None: cursor = connection.cursor() @@ -74,19 +90,43 @@ def _prepare_database(connection: sqlite3.Connection) -> None: if not db_initialized: cursor.executescript((here / 'tables.sql').read_text()) - else: - cursor.execute( - ''' - SELECT - haketilo_version - FROM - general; - ''' - ) - (db_haketilo_version,) = cursor.fetchone() - if db_haketilo_version != '3.0b1': - raise HaketiloException(_('err.proxy.unknown_db_schema')) + cursor.execute('BEGIN TRANSACTION;') + + try: + if db_initialized: + # If db was initialized before we connected to it, we must check + # what its schema version is. + cursor.execute( + ''' + SELECT + haketilo_version + FROM + general; + ''' + ) + + (db_haketilo_version,) = cursor.fetchone() + if db_haketilo_version != '3.0b1': + raise HaketiloException(_('err.proxy.unknown_db_schema')) + + popup_settings_columns_present = False + + cursor.execute("PRAGMA TABLE_INFO('general')") + for __cid, name, __type, __notnull, __dflt_value, __pk \ + in cursor.fetchall(): + if name == 'default_popup_jsallowed_onkeyboard': + popup_settings_columns_present = True + + if not popup_settings_columns_present: + _add_popup_settings_columns(cursor) + + cursor.execute('COMMIT TRANSACTION;') + except: + cursor.execute('ROLLBACK TRANSACTION;') + raise + + cursor.execute('PRAGMA FOREIGN_KEYS;') if cursor.fetchall() == []: @@ -106,17 +146,35 @@ def load_settings(cursor: sqlite3.Cursor) -> st.HaketiloGlobalSettings: repo_refresh_seconds, mapping_use_mode FROM - general + general; ''' ) (default_allow_scripts, advanced_user, repo_refresh_seconds, mapping_use_mode), = cursor.fetchall() - default_popup_settings = st.PopupSettings( - keyboard_trigger = True, - style = st.PopupStyle.TAB - ) + popup_settings_dict = {} + + for page_type in ('jsallowed', 'jsblocked', 'payloadon'): + try: + cursor.execute( + f''' + SELECT + default_popup_{page_type}_onkeyboard, + default_popup_{page_type}_style + FROM + general; + ''' + ) + + (onkeyboard, style), = cursor.fetchall() + except: + onkeyboard, style = True, 'T' + + popup_settings_dict[f'default_popup_{page_type}'] = st.PopupSettings( + keyboard_trigger = onkeyboard, + style = st.PopupStyle(style) + ) return st.HaketiloGlobalSettings( default_allow_scripts = default_allow_scripts, @@ -124,9 +182,7 @@ def load_settings(cursor: sqlite3.Cursor) -> st.HaketiloGlobalSettings: repo_refresh_seconds = repo_refresh_seconds, mapping_use_mode = st.MappingUseMode(mapping_use_mode), - default_popup_jsallowed = default_popup_settings, - default_popup_jsblocked = default_popup_settings, - default_popup_payloadon = default_popup_settings + **popup_settings_dict ) @dc.dataclass @@ -360,10 +416,11 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields): def update_settings( self, *, - mapping_use_mode: t.Optional[st.MappingUseMode] = None, - default_allow_scripts: t.Optional[bool] = None, - advanced_user: t.Optional[bool] = None, - repo_refresh_seconds: t.Optional[int] = None + mapping_use_mode: t.Optional[st.MappingUseMode] = None, + default_allow_scripts: t.Optional[bool] = None, + advanced_user: t.Optional[bool] = None, + repo_refresh_seconds: t.Optional[int] = None, + default_popup_settings: t.Mapping[str, st.PopupSettings] = {} ) -> None: with self.cursor(transaction=True) as cursor: def set_opt(col_name: str, val: t.Union[bool, int, str]) -> None: @@ -378,6 +435,15 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields): if repo_refresh_seconds is not None: set_opt('repo_refresh_seconds', repo_refresh_seconds) + for page_type in ('jsallowed', 'jsblocked', 'payloadon'): + popup_settings = default_popup_settings.get(page_type) + if popup_settings is not None: + trigger_col_name = f'default_popup_{page_type}_onkeyboard' + set_opt(trigger_col_name, popup_settings.keyboard_trigger) + + style_col_name = f'default_popup_{page_type}_style' + set_opt(style_col_name, popup_settings.style.value) + self.settings = load_settings(cursor) @staticmethod diff --git a/src/hydrilla/proxy/web_ui/root.py b/src/hydrilla/proxy/web_ui/root.py index 3120d0e..d775730 100644 --- a/src/hydrilla/proxy/web_ui/root.py +++ b/src/hydrilla/proxy/web_ui/root.py @@ -26,9 +26,15 @@ # court. """ -..... +This module instantiated Flask apps responsible for the web UI and facilitates +conversion of Flask response objects to the ResponseInfo type used by other +Haketilo code. + +In addition, the Haketilo root/settings page and landing page also have their +handlers defined here. """ +import re import dataclasses as dc import typing as t @@ -128,6 +134,10 @@ def home(errors: t.Mapping[str, bool] = {}) -> werkzeug.Response: ) return flask.make_response(html, 200) +popup_toggle_action_re = re.compile( + r'^popup_(yes|no)_when_(jsallowed|jsblocked|payloadon)$' +) + @home_bp.route('/', methods=['POST']) def home_post() -> werkzeug.Response: action = flask.request.form['action'] @@ -151,7 +161,19 @@ def home_post() -> werkzeug.Response: elif action == 'prune_orphans': state.prune_orphan_items() else: - raise ValueError() + match = popup_toggle_action_re.match(action) + if match is None: + raise ValueError() + + popup_enable = match.group(1) == 'yes' + page_type = match.group(2) + + settings_prop = f'default_popup_{page_type}' + old_settings = getattr(state.get_settings(), settings_prop) + + new_settings = dc.replace(old_settings, keyboard_trigger=popup_enable) + + state.update_settings(default_popup_settings={page_type: new_settings}) return flask.redirect(flask.url_for('.home'), 303) diff --git a/src/hydrilla/proxy/web_ui/templates/import/checkbox_tricks.html.jinja b/src/hydrilla/proxy/web_ui/templates/import/checkbox_tricks.html.jinja index 999208b..4ad9ca1 100644 --- a/src/hydrilla/proxy/web_ui/templates/import/checkbox_tricks.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/import/checkbox_tricks.html.jinja @@ -23,7 +23,7 @@ code in a proprietary work, I am not going to enforce this in court. {{ name }}_chbx {%- endmacro %} -{% macro sibling_hider(button_text, name, initial_show=false) %} +{% macro sibling_hider_but(button_text, name, initial_show=false) %} {% set attrs = {'type': 'checkbox', 'class': 'chbx-tricks-show-hide'} %} {% do attrs.update({'id': hider_id(name)}) %} {% do attrs.update({'checked': none if initial_show else ''}) %} @@ -33,3 +33,10 @@ code in a proprietary work, I am not going to enforce this in court. {{ button_text }} </label> {% endmacro %} + +{% macro sibling_hider_radio(name, radio_id, initial_show=false) %} + {% set attrs = {'type': 'radio', 'class': 'chbx-tricks-show'} %} + {% do attrs.update({'name': name, 'id': radio_id}) %} + {% do attrs.update({'checked': '' if initial_show else none}) %} + <input {{ attrs|xmlattr }}> +{% endmacro %} diff --git a/src/hydrilla/proxy/web_ui/templates/include/checkbox_tricks_style.css.jinja b/src/hydrilla/proxy/web_ui/templates/include/checkbox_tricks_style.css.jinja index 6932228..a47a438 100644 --- a/src/hydrilla/proxy/web_ui/templates/include/checkbox_tricks_style.css.jinja +++ b/src/hydrilla/proxy/web_ui/templates/include/checkbox_tricks_style.css.jinja @@ -33,3 +33,13 @@ input.chbx-tricks-hide-show:checked+*, input.chbx-tricks-show-hide:not(:checked)+* { display: none !important; } + + +input.chbx-tricks-show, input.chbx-tricks-hide { + display: none !important; +} + +input.chbx-tricks-hide:checked+*, +input.chbx-tricks-show:not(:checked)+* { + display: none !important; +} diff --git a/src/hydrilla/proxy/web_ui/templates/index.html.jinja b/src/hydrilla/proxy/web_ui/templates/index.html.jinja index 010c2ed..2b49361 100644 --- a/src/hydrilla/proxy/web_ui/templates/index.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/index.html.jinja @@ -22,6 +22,14 @@ code in a proprietary work, I am not going to enforce this in court. {% block title %} {{ _('web_ui.home.title') }} {% endblock %} +{% block style %} + {{ super() }} + + {% include 'include/checkbox_tricks_style.css.jinja' %} +{% endblock %} + +{% import 'import/checkbox_tricks.html.jinja' as tricks %} + {% block main %} <h3> {{ _('web_ui.home.heading.welcome_to_haketilo') }} @@ -182,4 +190,113 @@ code in a proprietary work, I am not going to enforce this in court. ]) }} {% endif %} -{% endblock %} + + <div class="horizontal-separator"></div> + + {{ label(_('web_ui.home.popup_settings_label')) }} + + {% + macro render_popup_settings( + page_type, + initial_show = false, + popup_change_but_base_classes = ['red-button', 'blue-button'] + ) + %} + {% set radio_id = 'popup_settings_radio_' ~ page_type %} + {{ tricks.sibling_hider_radio('popup_settings', radio_id, initial_show) }} + + <div> + <p> + {{ _('web_ui.home.configure_popup_settings_on_pages_with') }} + </p> + + <div class="flex-row"> + {% + for but_page_type, but_text in [ + ('jsallowed', _('web_ui.home.popup_settings_jsallowed_button')), + ('jsblocked', _('web_ui.home.popup_settings_jsblocked_button')), + ('payloadon', _('web_ui.home.popup_settings_payloadon_button')) + ] + %} + {% set attrs, classes = {}, ['green-button'] %} + + {% if but_page_type == page_type %} + {% do classes.append('disabled-button') %} + {% else %} + {% set but_radio_id = 'popup_settings_radio_' ~ but_page_type %} + {% do attrs.update({'for': but_radio_id}) %} + {% endif %} + + {% if not loop.first %} + {% do classes.append('button-bordering-left') %} + {% endif %} + {% if not loop.last %} + {% do classes.append('button-bordering-right') %} + {% endif %} + + {% do attrs.update({'class': classes|join(' ')}) %} + + <label {{ attrs|xmlattr }}> + {{ but_text }} + </label> + + {% if not loop.last %} + <div class="button-row-separator"></div> + {% endif %} + {% endfor %} + </div> + + {% set popup_no_but_classes = [popup_change_but_base_classes[0]] %} + {% set popup_yes_but_classes = [popup_change_but_base_classes[1]] %} + + {% set settings_prop = 'default_popup_' ~ page_type %} + {% set is_on = (settings|attr(settings_prop)).keyboard_trigger %} + + {% if is_on %} + {% do popup_yes_but_classes.append('disabled-button') %} + {% else %} + {% do popup_no_but_classes.append('disabled-button') %} + {% endif %} + + <p> + {{ caller(is_on) }} + </p> + + {{ + button_row([ + (popup_no_but_classes, + _('web_ui.home.popup_no_button'), + {'action': 'popup_no_when_' ~ page_type}), + (popup_yes_but_classes, + _('web_ui.home.popup_yes_button'), + {'action': 'popup_yes_when_' ~ page_type}) + ]) + }} + </div> + {% endmacro %} + + {% set but_classes = ['green-button', 'green-button'] %} + {% call(popup_is_on) render_popup_settings('jsallowed', true, but_classes) %} + {% if popup_is_on %} + {{ _('web_ui.home.jsallowed_popup_yes') }} + {% else %} + {{ _('web_ui.home.jsallowed_popup_no') }} + {% endif %} + {% endcall %} + + {% call(popup_is_on) render_popup_settings('jsblocked') %} + {% if popup_is_on %} + {{ _('web_ui.home.jsblocked_popup_yes') }} + {% else %} + {{ _('web_ui.home.jsblocked_popup_no') }} + {% endif %} + {% endcall %} + + {% call(popup_is_on) render_popup_settings('payloadon') %} + {% if popup_is_on %} + {{ _('web_ui.home.payloadon_popup_yes') }} + {% else %} + {{ _('web_ui.home.payloadon_popup_no') }} + {% endif %} + {% endcall %} +{% endblock main %} diff --git a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja index c4b7a9a..8b070d9 100644 --- a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja @@ -59,7 +59,7 @@ code in a proprietary work, I am not going to enforce this in court. {% set button_text = _('web_ui.repos.single.update_name_button') %} {% set initial_show = repo_name_invalid is defined %} {% set initial_show = initial_show or repo_name_taken is defined %} - {{ tricks.sibling_hider(button_text, 'edit_name', initial_show) }} + {{ tricks.sibling_hider_but(button_text, 'edit_name', initial_show) }} <form method="POST"> <input type="hidden" name="action" value="update_repo_data"> @@ -107,7 +107,7 @@ code in a proprietary work, I am not going to enforce this in court. {% set button_text = _('web_ui.repos.single.update_url_button') %} {% set initial_show = repo_url_invalid is defined %} - {{ tricks.sibling_hider(button_text, 'edit_url', initial_show) }} + {{ tricks.sibling_hider_but(button_text, 'edit_url', initial_show) }} <form method="POST"> <input type="hidden" name="action" value="update_repo_data"> diff --git a/src/hydrilla/proxy/web_ui/templates/rules/show_single.html.jinja b/src/hydrilla/proxy/web_ui/templates/rules/show_single.html.jinja index 95e8009..7d29a0d 100644 --- a/src/hydrilla/proxy/web_ui/templates/rules/show_single.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/rules/show_single.html.jinja @@ -47,7 +47,7 @@ code in a proprietary work, I am not going to enforce this in court. {% set button_text = _('web_ui.rules.single.update_pattern_button') %} {% set initial_show = rule_pattern_invalid is defined %} - {{ tricks.sibling_hider(button_text, 'edit_pattern', initial_show) }} + {{ tricks.sibling_hider_but(button_text, 'edit_pattern', initial_show) }} <form method="POST"> <input type="hidden" name="action" value="update_rule_data"> |