From 771bf34ce9dc95ec1764eba01a7df52a76fea311 Mon Sep 17 00:00:00 2001 From: Vansh Comar <69755265+vacom13@users.noreply.github.com> Date: Thu, 21 Oct 2021 22:12:31 +0530 Subject: [PATCH] Show client IP for "my ip" searches (#469) This introduces a new UI element for displaying the client IP address when a search for "my ip" is used. Note that this does not show the IP address seen by Google if Whoogle is deployed remotely. It uses `request.remote_addr` to display the client IP address in the UI, not the actual address of the server (which is what Google sees in requests sent from remote Whoogle instances). --- app/routes.py | 19 ++++++++++----- app/static/css/dark-theme.css | 4 ++++ app/static/css/light-theme.css | 4 ++++ app/static/css/search.css | 8 +++++++ app/utils/results.py | 42 ++++++++++++++++++++++++++++++++++ app/utils/search.py | 20 ++++++++++++---- 6 files changed, 87 insertions(+), 10 deletions(-) diff --git a/app/routes.py b/app/routes.py index 35cff9b..2139683 100644 --- a/app/routes.py +++ b/app/routes.py @@ -8,17 +8,18 @@ import uuid from functools import wraps import waitress -from flask import jsonify, make_response, request, redirect, render_template, \ - send_file, session, url_for -from requests import exceptions - from app import app from app.models.config import Config from app.request import Request, TorError from app.utils.bangs import resolve_bang from app.utils.misc import read_config_bool -from app.utils.session import generate_user_key, valid_user_session +from app.utils.results import add_ip_card from app.utils.search import * +from app.utils.session import generate_user_key, valid_user_session +from bs4 import BeautifulSoup as bsoup +from flask import jsonify, make_response, request, redirect, render_template, \ + send_file, session, url_for +from requests import exceptions # Load DDG bang json files only on init bang_json = json.load(open(app.config['BANG_FILE'])) @@ -250,6 +251,11 @@ def search(): # Return 503 if temporarily blocked by captcha resp_code = 503 if has_captcha(str(response)) else 200 + # Feature to display IP address + if search_util.check_kw_ip(): + html_soup = bsoup(response, "html.parser") + response = add_ip_card(html_soup, request.remote_addr) + return render_template( 'display.html', query=urlparse.unquote(query), @@ -275,7 +281,8 @@ def search(): query=urlparse.unquote(query), search_type=search_util.search_type, mobile=g.user_request.mobile) - if 'isch' not in search_util.search_type else '')), resp_code + if 'isch' not in + search_util.search_type else '')), resp_code @app.route('/config', methods=['GET', 'POST', 'PUT']) diff --git a/app/static/css/dark-theme.css b/app/static/css/dark-theme.css index d0a42c8..2d17c00 100644 --- a/app/static/css/dark-theme.css +++ b/app/static/css/dark-theme.css @@ -186,3 +186,7 @@ path { .search-bar-desktop { color: var(--whoogle-dark-text) !important; } + +.ip-text-div{ + color: var(--whoogle-dark-secondary-text) !important; +} diff --git a/app/static/css/light-theme.css b/app/static/css/light-theme.css index a083f73..fbe3ad6 100644 --- a/app/static/css/light-theme.css +++ b/app/static/css/light-theme.css @@ -174,3 +174,7 @@ path { color: var(--whoogle-text); border-bottom: 0px; } + +.ip-text-div{ + color: var(--whoogle-secondary-text) !important; +} diff --git a/app/static/css/search.css b/app/static/css/search.css index 699d6c7..19fb385 100644 --- a/app/static/css/search.css +++ b/app/static/css/search.css @@ -31,3 +31,11 @@ details summary { height: 650px; border: 0; } + +.ip-address-div { + padding-bottom: 0 !important; +} + +.ip-text-div { + padding-top: 0 !important; +} diff --git a/app/utils/results.py b/app/utils/results.py index 60a4f6b..a199427 100644 --- a/app/utils/results.py +++ b/app/utils/results.py @@ -138,3 +138,45 @@ def append_nojs(result: BeautifulSoup) -> None: nojs_link.string = 'NoJS Link: ' + nojs_link['href'] result.append(BeautifulSoup('


', 'html.parser')) result.append(nojs_link) + + +def add_ip_card(html_soup: BeautifulSoup, ip: str) -> BeautifulSoup: + """Adds the client's IP address to the search results + if query contains keywords + + Args: + html_soup: The parsed search result containing the keywords + ip: ip address of the client + + Returns: + BeautifulSoup + + """ + if (not html_soup.select_one(".EY24We") + and html_soup.select_one(".OXXup").get_text().lower() == "all"): + # HTML IP card tag + ip_tag = html_soup.new_tag("div") + ip_tag["class"] = "ZINbbc xpd O9g5cc uUPGi" + + # For IP Address html tag + ip_address = html_soup.new_tag("div") + ip_address["class"] = "kCrYT ip-address-div" + ip_address.string = ip + + # Text below the IP address + ip_text = html_soup.new_tag("div") + ip_text.string = "Your public IP address" + ip_text["class"] = "kCrYT ip-text-div" + + # Adding all the above html tags to the IP card + ip_tag.append(ip_address) + ip_tag.append(ip_text) + + # Finding the element before which the IP card would be placed + f_link = html_soup.select_one(".BNeawe.vvjwJb.AP7Wnd") + ref_element = f_link.find_parent(class_="ZINbbc xpd O9g5cc" + + " uUPGi") + + # Inserting the element + ref_element.insert_before(ip_tag) + return html_soup diff --git a/app/utils/search.py b/app/utils/search.py index 561ec2f..ee092fe 100644 --- a/app/utils/search.py +++ b/app/utils/search.py @@ -1,12 +1,12 @@ import os +import re from typing import Any -from bs4 import BeautifulSoup as bsoup -from cryptography.fernet import Fernet, InvalidToken -from flask import g - from app.filter import Filter, get_first_link from app.request import gen_query +from bs4 import BeautifulSoup as bsoup +from cryptography.fernet import Fernet, InvalidToken +from flask import g TOR_BANNER = '

You are using Tor


' CAPTCHA = 'div class="g-recaptcha"' @@ -54,6 +54,7 @@ class Search: config: the current user config settings session: the flask user session """ + def __init__(self, request, config, session, cookies_disabled=False): method = request.method self.request_params = request.args if method == 'GET' else request.form @@ -161,3 +162,14 @@ class Search: link['href'] += param_str return str(formatted_results) + + def check_kw_ip(self) -> re.Match: + """Checks for keywords related to 'my ip' in the query + + Returns: + bool + + """ + return re.search("([^a-z0-9]|^)my *[^a-z0-9] *(ip|internet protocol)" + + "($|( *[^a-z0-9] *(((addres|address|adres|" + + "adress)|a)? *$)))", self.query.lower())