Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e70bbabd63 | ||
![]() |
4fad68adf2 | ||
![]() |
89d07abb6c | ||
![]() |
a8205c3043 | ||
![]() |
1b9f7990b6 | ||
![]() |
c54f4a79a6 | ||
![]() |
223f00c3c0 |
9 changed files with 49 additions and 48 deletions
|
@ -241,6 +241,8 @@ Description=Whoogle
|
|||
#Environment=WHOOGLE_ALT_SO=farside.link/anonymousoverflow
|
||||
# Load values from dotenv only
|
||||
#Environment=WHOOGLE_DOTENV=1
|
||||
# specify dotenv location if not in default location
|
||||
#Environment=WHOOGLE_DOTENV_PATH=<path/to>/whoogle.env
|
||||
Type=simple
|
||||
User=<username>
|
||||
# If installed as a package, add:
|
||||
|
@ -411,6 +413,7 @@ There are a few optional environment variables available for customizing a Whoog
|
|||
| -------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| WHOOGLE_URL_PREFIX | The URL prefix to use for the whoogle instance (i.e. "/whoogle") |
|
||||
| WHOOGLE_DOTENV | Load environment variables in `whoogle.env` |
|
||||
| WHOOGLE_DOTENV_PATH | The path to `whoogle.env` if not in default location |
|
||||
| WHOOGLE_USER | The username for basic auth. WHOOGLE_PASS must also be set if used. |
|
||||
| WHOOGLE_PASS | The password for basic auth. WHOOGLE_USER must also be set if used. |
|
||||
| WHOOGLE_PROXY_USER | The username of the proxy server. |
|
||||
|
@ -442,6 +445,7 @@ There are a few optional environment variables available for customizing a Whoog
|
|||
| WHOOGLE_TOR_CONF | The absolute path to the config file containing the password for the tor control port. Default: ./misc/tor/control.conf WHOOGLE_TOR_PASS must be 1 for this to work.|
|
||||
| WHOOGLE_SHOW_FAVICONS | Show/hide favicons next to search result URLs. Default on. |
|
||||
| WHOOGLE_UPDATE_CHECK | Enable/disable the automatic daily check for new versions of Whoogle. Default on. |
|
||||
| WHOOGLE_FALLBACK_ENGINE_URL | Set a fallback Search Engine URL when there is internal server error or instance is rate-limited. Search query is appended to the end of the URL (eg. https://duckduckgo.com/?k1=-1&q=). |
|
||||
|
||||
### 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.
|
||||
|
|
|
@ -25,9 +25,10 @@ app = Flask(__name__, static_folder=os.path.dirname(
|
|||
|
||||
app.wsgi_app = ProxyFix(app.wsgi_app)
|
||||
|
||||
dot_env_path = (
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'../whoogle.env'))
|
||||
# look for WHOOGLE_ENV, else look in parent directory
|
||||
dot_env_path = os.getenv(
|
||||
"WHOOGLE_DOTENV_PATH",
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), "../whoogle.env"))
|
||||
|
||||
# Load .env file if enabled
|
||||
if os.path.exists(dot_env_path):
|
||||
|
|
|
@ -3,13 +3,12 @@ from typing import Optional
|
|||
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
|
||||
import logging
|
||||
import json
|
||||
|
||||
import cssutils
|
||||
from cssutils.css.cssstylesheet import CSSStyleSheet
|
||||
|
@ -62,7 +61,7 @@ class Config:
|
|||
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 = [
|
||||
|
@ -144,7 +143,7 @@ class Config:
|
|||
# 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
|
||||
|
@ -237,35 +236,32 @@ class Config:
|
|||
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)
|
||||
preferences_json = json.dumps(self.get_attrs()).encode()
|
||||
compressed_preferences = brotli.compress(preferences_json)
|
||||
|
||||
return urlsafe_b64encode(encoded_preferences).decode()
|
||||
if self.preferences_encrypted and self.preferences_key:
|
||||
key = self._get_fernet_key(self.preferences_key)
|
||||
encrypted_preferences = Fernet(key).encrypt(compressed_preferences)
|
||||
compressed_preferences = brotli.compress(encrypted_preferences)
|
||||
|
||||
return urlsafe_b64encode(compressed_preferences).decode()
|
||||
|
||||
def _decode_preferences(self, preferences: str) -> dict:
|
||||
mode = preferences[0]
|
||||
preferences = preferences[1:]
|
||||
if mode == 'e': # preferences are encrypted
|
||||
try:
|
||||
|
||||
try:
|
||||
decoded_data = brotli.decompress(urlsafe_b64decode(preferences.encode() + b'=='))
|
||||
|
||||
if mode == 'e' and self.preferences_key:
|
||||
# preferences are encrypted
|
||||
key = self._get_fernet_key(self.preferences_key)
|
||||
decrypted_data = Fernet(key).decrypt(decoded_data)
|
||||
decoded_data = brotli.decompress(decrypted_data)
|
||||
|
||||
config = Fernet(key).decrypt(
|
||||
brotli.decompress(urlsafe_b64decode(
|
||||
preferences.encode() + b'=='))
|
||||
)
|
||||
|
||||
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() + b'=='))
|
||||
)
|
||||
else: # preferences are incorrectly formatted
|
||||
config = json.loads(decoded_data)
|
||||
except Exception:
|
||||
config = {}
|
||||
|
||||
return config
|
||||
|
||||
|
|
|
@ -339,6 +339,10 @@ def search():
|
|||
# Return 503 if temporarily blocked by captcha
|
||||
if has_captcha(str(response)):
|
||||
app.logger.error('503 (CAPTCHA)')
|
||||
fallback_engine = os.environ.get('WHOOGLE_FALLBACK_ENGINE_URL', '')
|
||||
if (fallback_engine):
|
||||
return redirect(fallback_engine + query)
|
||||
|
||||
return render_template(
|
||||
'error.html',
|
||||
blocked=True,
|
||||
|
@ -619,6 +623,10 @@ def internal_error(e):
|
|||
|
||||
print(traceback.format_exc(), file=sys.stderr)
|
||||
|
||||
fallback_engine = os.environ.get('WHOOGLE_FALLBACK_ENGINE_URL', '')
|
||||
if (fallback_engine):
|
||||
return redirect(fallback_engine + query)
|
||||
|
||||
localization_lang = g.user_config.get_localization_lang()
|
||||
translation = app.config['TRANSLATIONS'][localization_lang]
|
||||
return render_template(
|
||||
|
|
|
@ -16,7 +16,7 @@ const checkForTracking = () => {
|
|||
]
|
||||
},
|
||||
"usps": {
|
||||
"link": `https://tools.usps.com/go/TrackConfirmAction?tLabels=${query}`,
|
||||
"link": `https://tools.usps.com/go/TrackConfirmAction_input?origTrackNum=${query}`,
|
||||
"expr": [
|
||||
/(\b\d{30}\b)|(\b91\d+\b)|(\b\d{20}\b)/,
|
||||
/^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/,
|
||||
|
|
|
@ -4,4 +4,4 @@ optional_dev_tag = ''
|
|||
if os.getenv('DEV_BUILD'):
|
||||
optional_dev_tag = '.dev' + os.getenv('DEV_BUILD')
|
||||
|
||||
__version__ = '0.9.0' + optional_dev_tag
|
||||
__version__ = '0.9.1' + optional_dev_tag
|
||||
|
|
|
@ -3,7 +3,7 @@ name: whoogle
|
|||
description: A self hosted search engine on Kubernetes
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: 0.9.0
|
||||
appVersion: 0.9.1
|
||||
|
||||
icon: https://github.com/benbusby/whoogle-search/raw/main/app/static/img/favicon/favicon-96x96.png
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ soupsieve==2.4
|
|||
stem==1.8.1
|
||||
urllib3==1.26.19
|
||||
validators==0.22.0
|
||||
waitress==2.1.2
|
||||
waitress==3.0.1
|
||||
wcwidth==0.2.6
|
||||
Werkzeug==3.0.3
|
||||
Werkzeug==3.0.6
|
||||
python-dotenv==0.21.1
|
||||
|
|
|
@ -4,19 +4,11 @@ from app import app
|
|||
from app.models.endpoint import Endpoint
|
||||
from app.utils.session import generate_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=='
|
||||
JAPAN_PREFS = 'uG7IBICwK7FgMJNpUawp2tKDb1Omuv_euy-cJHVZ' \
|
||||
+ 'BSydthgwxRFIHxiVA8qUGavKaDXyiM5uNuPIjKbEAW-zB_vzNXWVaafFhW7k2' \
|
||||
+ 'fO2_mS5e5eK41XXWwiViTz2VVmGWje0UgQwwVPe1A7aH0s10FgARsd2xl5nlg' \
|
||||
+ 'RLHT2krPUw-iLQ5uHZSnYXFuF4caYemWcj4vqB2ocHkt-aqn04jgnnlWWME_K' \
|
||||
+ '9ySWdWmPyS66HtLt1tCwc_-xGZklvbHw=='
|
||||
|
||||
|
||||
def test_generate_user_keys():
|
||||
|
|
Loading…
Add table
Reference in a new issue