Encode config params in URL (#842)

Adds support for encoding (and optionally encrypting) user config values as
a single string that can be passed to any endpoint with the "preferences" url
param.

Co-authored-by: Ben Busby <contact@benbusby.com>
This commit is contained in:
João 2022-09-22 22:14:56 +02:00 committed by GitHub
parent 11275a7796
commit 74503d542e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 249 additions and 39 deletions

View File

@ -14,7 +14,7 @@ RUN pip install --prefix /install --no-warn-script-location --no-cache-dir -r re
FROM python:3.11.0a5-alpine
RUN apk add --update --no-cache tor curl openrc
RUN apk add --update --no-cache tor curl openrc libstdc++
# libcurl4-openssl-dev
RUN apk -U upgrade

View File

@ -389,23 +389,25 @@ There are a few optional environment variables available for customizing a Whoog
### Config Environment Variables
These environment variables allow setting default config values, but can be overwritten manually by using the home page config menu. These allow a shortcut for destroying/rebuilding an instance to the same config state every time.
| Variable | Description |
| ------------------------------ | --------------------------------------------------------------- |
| WHOOGLE_CONFIG_DISABLE | Hide config from UI and disallow changes to config by client |
| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country |
| WHOOGLE_CONFIG_LANGUAGE | Set interface language |
| WHOOGLE_CONFIG_SEARCH_LANGUAGE | Set search result language |
| WHOOGLE_CONFIG_BLOCK | Block websites from search results (use comma-separated list) |
| WHOOGLE_CONFIG_THEME | Set theme mode (light, dark, or system) |
| WHOOGLE_CONFIG_SAFE | Enable safe searches |
| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) |
| WHOOGLE_CONFIG_NEAR | Restrict results to only those near a particular city |
| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) |
| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab |
| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option |
| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only |
| WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) |
| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (should be single line) |
| Variable | Description |
| ------------------------------------ | --------------------------------------------------------------- |
| WHOOGLE_CONFIG_DISABLE | Hide config from UI and disallow changes to config by client |
| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country |
| WHOOGLE_CONFIG_LANGUAGE | Set interface language |
| WHOOGLE_CONFIG_SEARCH_LANGUAGE | Set search result language |
| WHOOGLE_CONFIG_BLOCK | Block websites from search results (use comma-separated list) |
| WHOOGLE_CONFIG_THEME | Set theme mode (light, dark, or system) |
| WHOOGLE_CONFIG_SAFE | Enable safe searches |
| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) |
| WHOOGLE_CONFIG_NEAR | Restrict results to only those near a particular city |
| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) |
| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab |
| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option |
| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only |
| WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) |
| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (should be single line) |
| WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED | Encrypt preferences token, requires preferences key |
| WHOOGLE_CONFIG_PREFERENCES_KEY | Key to encrypt preferences in URL (REQUIRED to show url) |
## Usage
Same as most search engines, with the exception of filtering by time range.

View File

@ -174,6 +174,16 @@
"description": "[CONFIG] Custom CSS styling (paste in CSS or leave blank)",
"value": ":root { /* LIGHT THEME COLORS */ --whoogle-background: #d8dee9; --whoogle-accent: #2e3440; --whoogle-text: #3B4252; --whoogle-contrast-text: #eceff4; --whoogle-secondary-text: #70757a; --whoogle-result-bg: #fff; --whoogle-result-title: #4c566a; --whoogle-result-url: #81a1c1; --whoogle-result-visited: #a3be8c; /* DARK THEME COLORS */ --whoogle-dark-background: #222; --whoogle-dark-accent: #685e79; --whoogle-dark-text: #fff; --whoogle-dark-contrast-text: #000; --whoogle-dark-secondary-text: #bbb; --whoogle-dark-result-bg: #000; --whoogle-dark-result-title: #1967d2; --whoogle-dark-result-url: #4b11a8; --whoogle-dark-result-visited: #bbbbff; }",
"required": false
},
"WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED": {
"description": "[CONFIG] Encrypt preferences token, requires WHOOGLE_CONFIG_PREFERENCES_KEY to be set",
"value": "",
"required": false
},
"WHOOGLE_CONFIG_PREFERENCES_KEY": {
"description": "[CONFIG] Key to encrypt preferences",
"value": "NEEDS_TO_BE_MODIFIED",
"required": false
}
}
}

View File

@ -1,7 +1,13 @@
from inspect import Attribute
from app.utils.misc import read_config_bool
from flask import current_app
import os
import re
from base64 import urlsafe_b64encode, urlsafe_b64decode
import pickle
from cryptography.fernet import Fernet
import hashlib
import brotli
class Config:
@ -29,6 +35,9 @@ class Config:
self.view_image = read_config_bool('WHOOGLE_CONFIG_VIEW_IMAGE')
self.get_only = read_config_bool('WHOOGLE_CONFIG_GET_ONLY')
self.anon_view = read_config_bool('WHOOGLE_CONFIG_ANON_VIEW')
self.preferences_encrypted = read_config_bool('WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED')
self.preferences_key = os.getenv('WHOOGLE_CONFIG_PREFERENCES_KEY', '')
self.accept_language = False
self.safe_keys = [
@ -42,7 +51,8 @@ class Config:
'block',
'safe',
'nojs',
'anon_view'
'anon_view',
'preferences_encrypted'
]
# Skip setting custom config if there isn't one
@ -71,6 +81,24 @@ class Config:
if not name.startswith("__")
and (type(attr) is bool or type(attr) is str)}
def get_attrs(self):
return {name: attr for name, attr in self.__dict__.items()
if not name.startswith("__")
and (type(attr) is bool or type(attr) is str)}
@property
def preferences(self) -> str:
# if encryption key is not set will uncheck preferences encryption
if self.preferences_encrypted:
self.preferences_encrypted = bool(self.preferences_key)
# add a tag for visibility if preferences token startswith 'e' it means
# the token is encrypted, 'u' means the token is unencrypted and can be
# used by other whoogle instances
encrypted_flag = "e" if self.preferences_encrypted else 'u'
preferences_digest = self._encode_preferences()
return f"{encrypted_flag}{preferences_digest}"
def is_safe_key(self, key) -> bool:
"""Establishes a group of config options that are safe to set
in the url.
@ -109,6 +137,13 @@ class Config:
Returns:
Config -- a modified config object
"""
if 'preferences' in params:
params_new = self._decode_preferences(params['preferences'])
# if preferences leads to an empty dictionary it means preferences
# parameter was not decrypted successfully
if len(params_new):
params = params_new
for param_key in params.keys():
if not self.is_safe_key(param_key):
continue
@ -116,8 +151,9 @@ class Config:
if param_val == 'off':
param_val = False
elif param_val.isdigit():
param_val = int(param_val)
elif isinstance(param_val, str):
if param_val.isdigit():
param_val = int(param_val)
self[param_key] = param_val
return self
@ -135,3 +171,40 @@ class Config:
param_str = param_str + f'&{safe_key}={self[safe_key]}'
return param_str
def _get_fernet_key(self, password: str) -> bytes:
hash_object = hashlib.md5(password.encode())
key = urlsafe_b64encode(hash_object.hexdigest().encode())
return key
def _encode_preferences(self) -> str:
encoded_preferences = brotli.compress(pickle.dumps(self.get_attrs()))
if self.preferences_encrypted:
if self.preferences_key != '':
key = self._get_fernet_key(self.preferences_key)
encoded_preferences = Fernet(key).encrypt(encoded_preferences)
encoded_preferences = brotli.compress(encoded_preferences)
return urlsafe_b64encode(encoded_preferences).decode()
def _decode_preferences(self, preferences: str) -> dict:
mode = preferences[0]
preferences = preferences[1:]
if mode == 'e': # preferences are encrypted
try:
key = self._get_fernet_key(self.preferences_key)
config = Fernet(key).decrypt(
brotli.decompress(urlsafe_b64decode(preferences.encode()))
)
config = pickle.loads(brotli.decompress(config))
except Exception:
config = {}
elif mode == 'u': # preferences are not encrypted
config = pickle.loads(
brotli.decompress(urlsafe_b64decode(preferences.encode()))
)
else: # preferences are incorrectly formatted
config = {}
return config

View File

@ -193,6 +193,9 @@ def index():
session['error_message'] = ''
return render_template('error.html', error_message=error_message)
# Update user config if specified in search args
g.user_config = g.user_config.from_params(g.request_params)
return render_template('index.html',
has_update=app.config['HAS_UPDATE'],
languages=app.config['LANGUAGES'],
@ -231,7 +234,8 @@ def opensearch():
main_url=opensearch_url,
request_type='' if get_only else 'method="post"',
search_type=request.args.get('tbm'),
search_name=get_search_name(request.args.get('tbm'))
search_name=get_search_name(request.args.get('tbm')),
preferences=g.user_config.preferences
), 200, {'Content-Type': 'application/xml'}
@ -334,6 +338,7 @@ def search():
tabs = get_tabs_content(app.config['HEADER_TABS'],
search_util.full_query,
search_util.search_type,
g.user_config.preferences,
translation)
# Feature to display currency_card
@ -342,6 +347,9 @@ def search():
html_soup = bsoup(str(response), 'html.parser')
response = add_currency_card(html_soup, conversion)
preferences = g.user_config.preferences
home_url = f"home?preferences={preferences}" if preferences else "home"
return render_template(
'display.html',
has_update=app.config['HAS_UPDATE'],
@ -365,6 +373,7 @@ def search():
version_number=app.config['VERSION_NUMBER'],
search_header=render_template(
'header.html',
home_url=home_url,
config=g.user_config,
translation=translation,
languages=app.config['LANGUAGES'],

View File

@ -26,6 +26,9 @@
"config-tor": "Use Tor",
"config-get-only": "GET Requests Only",
"config-url": "Root URL",
"config-pref-url": "Preferences URL",
"config-pref-encryption": "Encrypt Preferences",
"config-pref-help": "Requires WHOOGLE_CONFIG_PREFERENCES_KEY, otherwise this will be ignored.",
"config-css": "Custom CSS",
"load": "Load",
"apply": "Apply",
@ -72,6 +75,9 @@
"config-tor": "Gebruik Tor",
"config-get-only": "Alleen GET Requests",
"config-url": "Root URL",
"config-pref-url": "Voorkeurs URL",
"config-pref-encryption": "Versleutel voorkeuren",
"config-pref-help": "Vereist WHOOGLE_CONFIG_PREFERENCES_KEY, anders wordt dit genegeerd.",
"config-css": "Eigen CSS",
"load": "Laden",
"apply": "Opslaan",
@ -118,6 +124,9 @@
"config-tor": "Tor benutzen",
"config-get-only": "Auschließlich GET-Anfragen",
"config-url": "Root URL",
"config-pref-url": "Einstellungs URL",
"config-pref-encryption": "Einstellungen verschlüsseln",
"config-pref-help": "Erfordert WHOOGLE_CONFIG_PREFERENCES_KEY, sonst wird dies ignoriert.",
"config-css": "Custom CSS",
"load": "Laden",
"apply": "Übernehmen",
@ -164,6 +173,9 @@
"config-tor": "Usa Tor",
"config-get-only": "GET solo solicitudes",
"config-url": "URL raíz",
"config-pref-url": "URL de preferencias",
"config-pref-encryption": "Cifrar preferencias",
"config-pref-help": "Requiere WHOOGLE_CONFIG_PREFERENCES_KEY; de lo contrario, se ignorará.",
"config-css": "CSS personalizado",
"load": "Cargar",
"apply": "Aplicar",
@ -210,6 +222,9 @@
"config-tor": "Usa Tor",
"config-get-only": "Utilizza solo richieste GET",
"config-url": "Root URL",
"config-pref-url": "URL delle preferenze",
"config-pref-encryption": "Crittografa le preferenze",
"config-pref-help": "Richiede WHOOGLE_CONFIG_PREFERENCES_KEY, altrimenti verrà ignorato.",
"config-css": "CSS Personalizzato",
"load": "Carica",
"apply": "Applica",
@ -256,6 +271,9 @@
"config-tor": "Usar Tor",
"config-get-only": "Apenas Pedidos GET",
"config-url": "URL Fonte",
"config-pref-url": "URL de preferências",
"config-pref-encryption": "Criptografar preferências",
"config-pref-help": "Requer WHOOGLE_CONFIG_PREFERENCES_KEY, caso contrário, será ignorado.",
"config-css": "CSS Personalizado",
"load": "Carregar",
"apply": "Aplicar",
@ -302,6 +320,9 @@
"config-tor": "Использовать Tor",
"config-get-only": "Только GET-запросы",
"config-url": "Корневой URL-адрес",
"config-pref-url": "URL-адрес настроек",
"config-pref-encryption": "Зашифровать настройки",
"config-pref-help": "Требуется WHOOGLE_CONFIG_PREFERENCES_KEY, иначе это будет проигнорировано.",
"config-css": "Пользовательский CSS",
"load": "Загрузить",
"apply": "Применить",
@ -348,6 +369,9 @@
"config-tor": "使用 Tor",
"config-get-only": "仅限 GET 请求",
"config-url": "站点根 URL",
"config-pref-url": "首选项网址",
"config-pref-encryption": "加密首选项",
"config-pref-help": "需要 WHOOGLE_CONFIG_PREFERENCES_KEY否则将被忽略。",
"config-css": "自定义 CSS",
"load": "载入",
"apply": "应用",
@ -394,6 +418,9 @@
"config-tor": "ටෝර් භාවිතා කරන්න",
"config-get-only": "ඉල්ලීම් පමණක් ලබා ගන්න",
"config-url": "ඒ.ස.නි.(URL) මූලය",
"config-pref-url": "මනාප URL",
"config-pref-encryption": "මනාප සංකේතනය කරන්න",
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY අවශ්‍ය වේ, එසේ නොමැතිනම් මෙය නොසලකා හරිනු ඇත.",
"config-css": "අභිරුචි සීඑස්එස්",
"load": "පූරනය කරන්න",
"apply": "යොදන්න",
@ -440,6 +467,9 @@
"config-tor": "Utiliser Tor",
"config-get-only": "Requêtes GET seulement",
"config-url": "URL de la racine",
"config-pref-url": "URL des préférences",
"config-pref-encryption": "Chiffrer les préférences",
"config-pref-help": "Nécessite WHOOGLE_CONFIG_PREFERENCES_KEY, sinon cela sera ignoré.",
"config-css": "CSS Personalisé",
"load": "Charger",
"apply": "Appliquer",
@ -486,6 +516,9 @@
"config-tor": "استفاده از تور",
"config-get-only": "فقط درخواست‌های GET",
"config-url": "آدرس ریشه‌ی سایت",
"config-pref-url": "URL تنظیمات برگزیده",
"config-pref-encryption": "رمزگذاری تنظیمات برگزیده",
"config-pref-help": "به WHOOGLE_CONFIG_PREFERENCES_KEY نیاز دارد، در غیر این صورت نادیده گرفته خواهد شد.",
"config-css": "CSS دلخواه",
"load": "بارگذاری",
"apply": "تایید",
@ -532,6 +565,9 @@
"config-tor": "Používat Tor",
"config-get-only": "Pouze požadavky GET",
"config-url": "Kořenová adresa URL",
"config-pref-url": "Adresa URL předvoleb",
"config-pref-encryption": "Předvolby šifrování",
"config-pref-help": "Vyžaduje WHOOGLE_CONFIG_PREFERENCES_KEY, jinak bude ignorována.",
"config-css": "Vlastní CSS",
"load": "Načíst",
"apply": "Použít",
@ -578,6 +614,9 @@
"config-tor": "使用 Tor",
"config-get-only": "僅限於 GET 要求",
"config-url": "首頁網址",
"config-pref-url": "首選項網址",
"config-pref-encryption": "加密首選項",
"config-pref-help": "需要 WHOOGLE_CONFIG_PREFERENCES_KEY否則將被忽略。",
"config-css": "自定 CSS",
"load": "載入",
"apply": "套用",
@ -624,6 +663,9 @@
"config-tor": "Използвайте Tor",
"config-get-only": "Само GET заявки",
"config-url": "Основен URL адрес",
"config-pref-url": "URL адрес на предпочитанията",
"config-pref-encryption": "Шифроване на предпочитанията",
"config-pref-help": "Изисква WHOOGLE_CONFIG_PREFERENCES_KEY, в противен случай това ще бъде игнорирано.",
"config-css": "Персонализиран CSS",
"load": "Зареди",
"apply": "Приложи",
@ -670,6 +712,9 @@
"config-tor": "TOR का प्रयोग करें",
"config-get-only": "केवल GET अनुरोध",
"config-url": "रूट यूआरएल",
"config-pref-url": "वरीयताएँ URL",
"config-pref-encryption": "एन्क्रिप्ट प्राथमिकताएं",
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY की आवश्यकता है, अन्यथा इसे अनदेखा कर दिया जाएगा।",
"config-css": "कस्टम सीएसएस",
"load": "भार",
"apply": "लागू करना",
@ -716,6 +761,9 @@
"config-tor": "Torを使用",
"config-get-only": "GETリクエストのみ",
"config-url": "ルートURL",
"config-pref-url": "設定 URL",
"config-pref-encryption": "設定を暗号化する",
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY が必要です。それ以外の場合、これは無視されます。",
"config-css": "カスタムCSS",
"load": "読み込み",
"apply": "反映",
@ -762,6 +810,9 @@
"config-tor": "Tor 사용",
"config-get-only": "GET 요청만",
"config-url": "루트 URL",
"config-pref-url": "환경설정 URL",
"config-pref-encryption": "암호화 환경 설정",
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY이 필요합니다. 그렇지 않으면 무시됩니다.",
"config-css": "커스텀 CSS",
"load": "불러오기",
"apply": "적용",
@ -808,6 +859,9 @@
"config-tor": "Tor bi kar bîne",
"config-get-only": "Daxwazan bi Dest Bixe",
"config-url": "Reha URL",
"config-pref-url": "Preferences URL",
"config-pref-encryption": "Vebijêrkên şîfre bikin",
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY hewce dike, wekî din ev ê were paşguh kirin.",
"config-css": "CSS kesane bike",
"load": "Bar bike",
"apply": "Bisepîne",

View File

@ -4,13 +4,16 @@
<form class="search-form header"
id="search-form"
method="{{ 'GET' if config.get_only else 'POST' }}">
<a class="logo-link mobile-logo" href="home">
<a class="logo-link mobile-logo" href="{{ home_url }}">
<div id="mobile-header-logo">
{{ logo|safe }}
</div>
</a>
<div class="H0PQec mobile-input-div">
<div class="autocomplete-mobile esbc autocomplete">
{% if config.preferences %}
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
{% endif %}
<input
id="search-bar"
class="mobile-search-bar"
@ -57,7 +60,7 @@
{% else %}
<header>
<div class="logo-div">
<a class="logo-link" href="home">
<a class="logo-link" href="{{ home_url }}">
<div class="desktop-header-logo">
{{ logo|safe }}
</div>
@ -70,6 +73,9 @@
method="{{ 'GET' if config.get_only else 'POST' }}">
<div class="autocomplete header-autocomplete">
<div style="width: 100%; display: flex">
{% if config.preferences %}
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
{% endif %}
<input
id="search-bar"
autocapitalize="none"

View File

@ -66,6 +66,9 @@
<form id="search-form" action="search" method="{{ 'get' if config.get_only else 'post' }}">
<div class="search-fields">
<div class="autocomplete">
{% if config.preferences %}
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
{% endif %}
<input
type="text"
name="q"
@ -233,6 +236,14 @@
{{ config.style.replace('\t', '') }}
</textarea>
</div>
<div class="config-div config-div-pref-url">
<label for="config-pref-encryption">{{ translation['config-pref-encryption'] }}: </label>
<input type="checkbox" name="preferences_encrypted"
id="config-pref-encryption" {{ 'checked' if config.preferences_encrypted and config.preferences_key else '' }}>
<div><span class="info-text"> — {{ translation['config-pref-help'] }}</span></div>
<label for="config-pref-url">{{ translation['config-pref-url'] }}: </label>
<input type="text" name="pref-url" id="config-pref-url" value="{{ config.url }}?preferences={{ config.preferences }}">
</div>
</div>
<div class="config-div config-buttons">
<input type="submit" id="config-load" value="{{ translation['load'] }}">&nbsp;

View File

@ -17,6 +17,9 @@
{% if search_type %}
<Param name="tbm" value="{{ search_type }}"/>
{% endif %}
{% if preferences %}
<Param name="preferences" value="{{ preferences }}"/>
{% endif %}
</Url>
<Url type="application/x-suggestions+json" {{ request_type|safe }} template="{{ main_url }}/autocomplete">
<Param name="q" value="{searchTerms}"/>

View File

@ -393,6 +393,7 @@ def add_currency_card(soup: BeautifulSoup,
def get_tabs_content(tabs: dict,
full_query: str,
search_type: str,
preferences: str,
translation: dict) -> dict:
"""Takes the default tabs content and updates it according to the query.
@ -416,6 +417,9 @@ def get_tabs_content(tabs: dict,
if tab_content['tbm'] is not None:
query = f"{query}&tbm={tab_content['tbm']}"
if preferences:
query = f"{query}&preferences={preferences}"
tab_content['href'] = tab_content['href'].format(query=query)

View File

@ -47,21 +47,23 @@ conf: {}
# WHOOGLE_AUTOCOMPLETE: "" # Controls visibility of autocomplete/search suggestions. Default on -- use '0' to disable
# WHOOGLE_MINIMAL: "" # Remove everything except basic result cards from all search queries.
# WHOOGLE_CONFIG_DISABLE: "" # Hide config from UI and disallow changes to config by client
# WHOOGLE_CONFIG_COUNTRY: "" # Filter results by hosting country
# WHOOGLE_CONFIG_LANGUAGE: "" # Set interface language
# WHOOGLE_CONFIG_SEARCH_LANGUAGE: "" # Set search result language
# WHOOGLE_CONFIG_BLOCK: "" # Block websites from search results (use comma-separated list)
# WHOOGLE_CONFIG_THEME: "" # Set theme mode (light, dark, or system)
# WHOOGLE_CONFIG_SAFE: "" # Enable safe searches
# WHOOGLE_CONFIG_ALTS: "" # Use social media site alternatives (nitter, invidious, etc)
# WHOOGLE_CONFIG_NEAR: "" # Restrict results to only those near a particular city
# WHOOGLE_CONFIG_TOR: "" # Use Tor routing (if available)
# WHOOGLE_CONFIG_NEW_TAB: "" # Always open results in new tab
# WHOOGLE_CONFIG_VIEW_IMAGE: "" # Enable View Image option
# WHOOGLE_CONFIG_GET_ONLY: "" # Search using GET requests only
# WHOOGLE_CONFIG_URL: "" # The root url of the instance (https://<your url>/)
# WHOOGLE_CONFIG_STYLE: "" # The custom CSS to use for styling (should be single line)
# WHOOGLE_CONFIG_DISABLE: "" # Hide config from UI and disallow changes to config by client
# WHOOGLE_CONFIG_COUNTRY: "" # Filter results by hosting country
# WHOOGLE_CONFIG_LANGUAGE: "" # Set interface language
# WHOOGLE_CONFIG_SEARCH_LANGUAGE: "" # Set search result language
# WHOOGLE_CONFIG_BLOCK: "" # Block websites from search results (use comma-separated list)
# WHOOGLE_CONFIG_THEME: "" # Set theme mode (light, dark, or system)
# WHOOGLE_CONFIG_SAFE: "" # Enable safe searches
# WHOOGLE_CONFIG_ALTS: "" # Use social media site alternatives (nitter, invidious, etc)
# WHOOGLE_CONFIG_NEAR: "" # Restrict results to only those near a particular city
# WHOOGLE_CONFIG_TOR: "" # Use Tor routing (if available)
# WHOOGLE_CONFIG_NEW_TAB: "" # Always open results in new tab
# WHOOGLE_CONFIG_VIEW_IMAGE: "" # Enable View Image option
# WHOOGLE_CONFIG_GET_ONLY: "" # Search using GET requests only
# WHOOGLE_CONFIG_URL: "" # The root url of the instance (https://<your url>/)
# WHOOGLE_CONFIG_STYLE: "" # The custom CSS to use for styling (should be single line)
# WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED: "" # Encrypt preferences token, requires key
# WHOOGLE_CONFIG_PREFERENCES_KEY: "" # Key to encrypt preferences in URL (REQUIRED to show url)
podAnnotations: {}
podSecurityContext: {}

View File

@ -72,6 +72,8 @@ services:
# - WHOOGLE_CONFIG_SEARCH_LANGUAGE=lang_en
# - WHOOGLE_CONFIG_GET_ONLY=1
# - WHOOGLE_CONFIG_COUNTRY=FR
# - WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED=1
# - WHOOGLE_CONFIG_PREFERENCES_KEY="NEEDS_TO_BE_MODIFIED"
#env_file: # Alternatively, load variables from whoogle.env
#- whoogle.env
ports:

View File

@ -1,5 +1,6 @@
attrs==19.3.0
beautifulsoup4==4.10.0
brotli==1.0.9
cachelib==0.4.1
certifi==2020.4.5.1
cffi==1.15.0

View File

@ -5,6 +5,20 @@ from app.models.endpoint import Endpoint
from app.utils.session import generate_user_key, valid_user_session
JAPAN_PREFS = 'uG-gGIJwHdqxl6DrS3mnu_511HlQcRpxYlG03Xs-' \
+ '_znXNiJWI9nLOkRLkiiFwIpeUYMTGfUF5-t9fP5DGmzDLEt04DCx703j3nPf' \
+ '29v_RWkU7gXw_44m2oAFIaKGmYlu4Z0bKyu9k5WXfL9Dy6YKKnpcR5CiaFsG' \
+ 'rccNRkAPYm-eYGAFUV8M59f8StsGd_M-gHKGS9fLok7EhwBWjHxBJ2Kv8hsT' \
+ '87zftP2gMJOevTdNnezw2Y5WOx-ZotgeheCW1BYCFcRqatlov21PHp22NGVG' \
+ '8ZuBNAFW0bE99WSdyT7dUIvzeWCLJpbdSsq-3FUUZkxbRdFYlGd8vY1UgVAp' \
+ 'OSie2uAmpgLFXygO-VfNBBZ68Q7gAap2QtzHCiKD5cFYwH3LPgVJ-DoZvJ6k' \
+ 'alt34TaYiJphgiqFKV4SCeVmLWTkr0SF3xakSR78yYJU_d41D2ng-TojA9XZ' \
+ 'uR2ZqjSvPKOWvjimu89YhFOgJxG1Po8Henj5h9OL9VXXvdvlJwBSAKw1E3FV' \
+ '7UHWiglMxPblfxqou1cYckMYkFeIMCD2SBtju68mBiQh2k328XRPTsQ_ocby' \
+ 'cgVKnleGperqbD6crRk3Z9xE5sVCjujn9JNVI-7mqOITMZ0kntq9uJ3R5n25' \
+ 'Vec0TJ0P19nEtvjY0nJIrIjtnBg=='
def test_generate_user_keys():
key = generate_user_key()
assert Fernet(key)
@ -49,3 +63,16 @@ def test_query_decryption(client):
with client.session_transaction() as session:
assert valid_user_session(session)
def test_prefs_url(client):
base_url = f'/{Endpoint.search}?q=wikipedia'
rv = client.get(base_url)
assert rv._status_code == 200
assert b'wikipedia.org' in rv.data
assert b'ja.wikipedia.org' not in rv.data
rv = client.get(f'{base_url}&preferences={JAPAN_PREFS}')
assert rv._status_code == 200
assert b'ja.wikipedia.org' in rv.data

View File

@ -85,3 +85,9 @@
# Set custom CSS styling/theming
#WHOOGLE_CONFIG_STYLE=":root { /* LIGHT THEME COLORS */ --whoogle-background: #d8dee9; --whoogle-accent: #2e3440; --whoogle-text: #3B4252; --whoogle-contrast-text: #eceff4; --whoogle-secondary-text: #70757a; --whoogle-result-bg: #fff; --whoogle-result-title: #4c566a; --whoogle-result-url: #81a1c1; --whoogle-result-visited: #a3be8c; /* DARK THEME COLORS */ --whoogle-dark-background: #222; --whoogle-dark-accent: #685e79; --whoogle-dark-text: #fff; --whoogle-dark-contrast-text: #000; --whoogle-dark-secondary-text: #bbb; --whoogle-dark-result-bg: #000; --whoogle-dark-result-title: #1967d2; --whoogle-dark-result-url: #4b11a8; --whoogle-dark-result-visited: #bbbbff; }"
# Enable preferences encryption (requires key)
#WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED=1
# Set Key to encode config in url
#WHOOGLE_CONFIG_PREFERENCES_KEY="NEEDS_TO_BE_MODIFIED"