From 46854d2676da226e0e3dd926775eed57bde6dd10 Mon Sep 17 00:00:00 2001 From: hjoaquim Date: Fri, 27 Jan 2023 10:49:35 +0000 Subject: [PATCH 1/5] filtering password --- .../core/log/generation/formatter_with_exceptions.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openbb_terminal/core/log/generation/formatter_with_exceptions.py b/openbb_terminal/core/log/generation/formatter_with_exceptions.py index 28c85a4e5a0..7202d8ee777 100644 --- a/openbb_terminal/core/log/generation/formatter_with_exceptions.py +++ b/openbb_terminal/core/log/generation/formatter_with_exceptions.py @@ -67,6 +67,13 @@ class FormatterWithExceptions(logging.Formatter): return text_mocked + @staticmethod + def mock_password(text: str) -> str: + pattern = r'("password": ")[^"]+' + replacement = r"\1 FILTERED_PASSWORD " + text_mocked = re.sub(pattern, replacement, text) + return text_mocked + @staticmethod def mock_home_directory(text: str) -> str: user_home_directory = str(HOME_DIRECTORY) @@ -85,6 +92,7 @@ class FormatterWithExceptions(logging.Formatter): def filter_piis(cls, text: str) -> str: text_filtered = cls.mock_ipv4(text=text) text_filtered = cls.mock_email(text=text_filtered) + text_filtered = cls.mock_password(text=text_filtered) text_filtered = cls.mock_home_directory(text=text_filtered) return text_filtered From f6fd627761a542b0679b4a60be01fc34306b0ea3 Mon Sep 17 00:00:00 2001 From: hjoaquim Date: Fri, 27 Jan 2023 10:51:35 +0000 Subject: [PATCH 2/5] filtering the email from user --- .../core/log/generation/formatter_with_exceptions.py | 7 ------- openbb_terminal/core/log/generation/user_logger.py | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/openbb_terminal/core/log/generation/formatter_with_exceptions.py b/openbb_terminal/core/log/generation/formatter_with_exceptions.py index 7202d8ee777..51ca71f0f63 100644 --- a/openbb_terminal/core/log/generation/formatter_with_exceptions.py +++ b/openbb_terminal/core/log/generation/formatter_with_exceptions.py @@ -5,13 +5,9 @@ import re # IMPORTATION THIRDPARTY # IMPORTATION INTERNAL -from openbb_terminal.core.log.generation.user_logger import __name__ as user_logger_name from openbb_terminal.core.config.paths import HOME_DIRECTORY from openbb_terminal.core.log.generation.settings import AppSettings -# considering starting at 0 and after the logging prefix i.e., just the text to be filtered -MODULE_POSITION = 1 - class FormatterWithExceptions(logging.Formatter): """Logging Formatter that includes formatting of Exceptions""" @@ -58,9 +54,6 @@ class FormatterWithExceptions(logging.Formatter): @staticmethod def mock_email(text: str) -> str: - if text.split("|")[MODULE_POSITION] == user_logger_name: - return text - pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b" replacement = " FILTERED_EMAIL " text_mocked = re.sub(pattern, replacement, text) diff --git a/openbb_terminal/core/log/generation/user_logger.py b/openbb_terminal/core/log/generation/user_logger.py index 2c117b2377c..59a07275afd 100644 --- a/openbb_terminal/core/log/generation/user_logger.py +++ b/openbb_terminal/core/log/generation/user_logger.py @@ -23,5 +23,5 @@ def log_user(with_rollover: bool = True): def log_user_info(): """Log user info""" - user_info = {"user_uuid": User.get_uuid(), "user_email": User.get_email()} + user_info = {"user_uuid": User.get_uuid()} logger.info("USER: %s ", json.dumps(user_info)) From 5e78254e45ca35d939ac5df8a222254c7b9c887b Mon Sep 17 00:00:00 2001 From: hjoaquim Date: Fri, 27 Jan 2023 11:01:33 +0000 Subject: [PATCH 3/5] avoid writing to multiple log files if a user logs out --- openbb_terminal/session/session_model.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openbb_terminal/session/session_model.py b/openbb_terminal/session/session_model.py index 4ff4244cd26..15fb349c925 100644 --- a/openbb_terminal/session/session_model.py +++ b/openbb_terminal/session/session_model.py @@ -1,4 +1,5 @@ import importlib +import logging import os import sys import matplotlib.pyplot as plt @@ -45,6 +46,10 @@ def logout(cls: bool = False): if v.startswith("OPENBB"): os.environ.pop(v) + # Remove the log handlers - needs to be done before reloading modules + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + # Reload all openbb modules to clear memorized variables modules = sys.modules.copy() for module in modules: From e683ca778ba7a3bf3b3c640771f1d2b7be53a9db Mon Sep 17 00:00:00 2001 From: hjoaquim Date: Fri, 27 Jan 2023 11:51:48 +0000 Subject: [PATCH 4/5] log user on the sdk --- openbb_terminal/core/library/operation.py | 18 ++++++++++++++++-- .../core/log/generation/user_logger.py | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/openbb_terminal/core/library/operation.py b/openbb_terminal/core/library/operation.py index 89e80903810..93cba207bd2 100644 --- a/openbb_terminal/core/library/operation.py +++ b/openbb_terminal/core/library/operation.py @@ -6,9 +6,9 @@ from typing import Any, Callable, Dict, List, Optional from inspect import signature import openbb_terminal.config_terminal as cfg - from openbb_terminal.core.library.metadata import Metadata from openbb_terminal.core.library.trail_map import TrailMap +from openbb_terminal.session.sdk_session import login # pylint: disable=import-outside-toplevel @@ -232,7 +232,7 @@ class OperationLogger: if func_module == "openbb_terminal.keys_model": - from openbb_terminal.core.log.generation.settings_logger import ( # pylint: disable=C0415 + from openbb_terminal.core.log.generation.settings_logger import ( # pylint: disable=import-outside-toplevel log_keys, ) @@ -252,6 +252,9 @@ class OperationLogger: method_result=method_result, method_chosen=self.__method_chosen, ) + self.__log_if_login( + method_chosen=self.__method_chosen, + ) self.__log_end( logger=logger, method_chosen=self.__method_chosen, @@ -275,6 +278,17 @@ class OperationLogger: extra={"func_name_override": method_chosen.__name__}, ) + @staticmethod + def __log_if_login( + method_chosen: Callable, + ): + if method_chosen.__name__ == login.__name__: + from openbb_terminal.core.log.generation.user_logger import ( # pylint: disable=import-outside-toplevel + log_user, + ) + + log_user(with_rollover=False) + @staticmethod def __log_end(logger: Logger, method_chosen: Callable): logger.info( diff --git a/openbb_terminal/core/log/generation/user_logger.py b/openbb_terminal/core/log/generation/user_logger.py index 59a07275afd..acda5a0e8b1 100644 --- a/openbb_terminal/core/log/generation/user_logger.py +++ b/openbb_terminal/core/log/generation/user_logger.py @@ -15,13 +15,13 @@ logger = logging.getLogger(__name__) def log_user(with_rollover: bool = True): """Log user""" if not User.is_guest(): - log_user_info() + _log_user_info() if with_rollover: do_rollover() -def log_user_info(): +def _log_user_info(): """Log user info""" user_info = {"user_uuid": User.get_uuid()} logger.info("USER: %s ", json.dumps(user_info)) From d0c7dceb21f07c2318e292b3cc9086999aff8186 Mon Sep 17 00:00:00 2001 From: montezdesousa <79287829+montezdesousa@users.noreply.github.com> Date: Fri, 27 Jan 2023 14:59:37 +0000 Subject: [PATCH 5/5] Fix login bug and decouple some logic (#4056) * fix bug, guest allowed in installer without connection * split login from lauch * improvements on the sdk login --------- Co-authored-by: hjoaquim --- openbb_terminal/session/sdk_session.py | 19 +++--- openbb_terminal/session/session_controller.py | 60 ++++++++++--------- openbb_terminal/session/session_model.py | 26 ++++++++ 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/openbb_terminal/session/sdk_session.py b/openbb_terminal/session/sdk_session.py index 662b68546aa..47b57b9c826 100644 --- a/openbb_terminal/session/sdk_session.py +++ b/openbb_terminal/session/sdk_session.py @@ -1,14 +1,10 @@ -import json - from openbb_terminal.session import local_model as Local -from openbb_terminal.session import hub_model as Hub -from openbb_terminal.session.session_model import create_session -from openbb_terminal.session.user import User +from openbb_terminal.session import session_model from openbb_terminal.rich_config import console def get_session(email: str, password: str, save: bool): - session = create_session(email, password, save) + session = session_model.create_session(email, password, save) if not (isinstance(session, dict) and session): raise Exception("Failed to create session") return session @@ -20,11 +16,10 @@ def login(email: str = "", password: str = "", save: bool = False): if not session: session = get_session(email, password, save) - User.load_user_info(session) - response = Hub.fetch_user_configs(session) + if session_model.login(session) in [ + session_model.LoginStatus.FAILED, + session_model.LoginStatus.NO_RESPONSE, + ]: + raise Exception("Login failed") - if not (response and response.status_code == 200): - raise Exception("Failed to fetch user configs") - - Local.apply_configs(configs=json.loads(response.content)) console.print("[green]Login successful[/green]") diff --git a/openbb_terminal/session/session_controller.py b/openbb_terminal/session/session_controller.py index 618600a9190..288c4b78289 100644 --- a/openbb_terminal/session/session_controller.py +++ b/openbb_terminal/session/session_controller.py @@ -1,18 +1,17 @@ from typing import Tuple -import json +from openbb_terminal import terminal_controller import openbb_terminal.session.local_model as Local -import openbb_terminal.session.hub_model as Hub -from openbb_terminal.session.session_model import create_session -from openbb_terminal.session.user import User +from openbb_terminal.session.session_model import ( + LoginStatus, + create_session, + login, +) from openbb_terminal.core.config.paths import PACKAGE_DIRECTORY from openbb_terminal.rich_config import console -from openbb_terminal import terminal_controller -from openbb_terminal.helper_funcs import system_clear def display_welcome_message(): """Display welcome message""" - system_clear() with open(PACKAGE_DIRECTORY / "session" / "banner.txt") as f: console.print(f.read(), style="menu") @@ -36,8 +35,8 @@ def get_user_input() -> Tuple[str, str, bool]: return email, password, save -def login_prompt(welcome=True, guest_allowed=True): - """Login prompt and launch terminal if login is successful. +def prompt(welcome=True, guest_allowed=False): + """Prompt and launch terminal if login is successful. Parameters ---------- @@ -51,44 +50,51 @@ def login_prompt(welcome=True, guest_allowed=True): email, password, save = get_user_input() if not email or not password: if guest_allowed: - return terminal_controller.parse_args_and_run() + return launch_terminal() continue session = create_session(email, password, save) if isinstance(session, dict) and session: - break - - login(session=session) + return login_and_launch(session=session, guest_allowed=guest_allowed) -# TODO: Move some login inside this function to the session_model.py -def login(session: dict): +def launch_terminal(): + """Launch terminal""" + terminal_controller.parse_args_and_run() + + +def login_and_launch(session: dict, guest_allowed: bool = True): """Login and launch terminal. Parameters ---------- session : dict The session info. + guest_allowed : bool, optional + Allow guest login, by default True """ - User.load_user_info(session) - response = Hub.fetch_user_configs(session) - if response: - if response.status_code == 200: - Local.apply_configs(configs=json.loads(response.content)) - terminal_controller.parse_args_and_run() - else: - login_prompt(welcome=False) + status = login(session) + if status == LoginStatus.SUCCESS: + launch_terminal() + elif status == LoginStatus.FAILED: + prompt(welcome=False, guest_allowed=guest_allowed) else: - login_prompt(welcome=True) + prompt(welcome=True, guest_allowed=guest_allowed) def main(guest_allowed: bool = True): - """Main function""" + """Main function + + Parameters + ---------- + guest_allowed : bool, optional + Allow guest login, by default True + """ local_session = Local.get_session() if not local_session: - login_prompt(guest_allowed=guest_allowed) + prompt(guest_allowed=guest_allowed) else: - login(session=local_session) + login_and_launch(session=local_session, guest_allowed=guest_allowed) if __name__ == "__main__": diff --git a/openbb_terminal/session/session_model.py b/openbb_terminal/session/session_model.py index 15fb349c925..1f0a393f661 100644 --- a/openbb_terminal/session/session_model.py +++ b/openbb_terminal/session/session_model.py @@ -2,6 +2,8 @@ import importlib import logging import os import sys +import json +from enum import Enum import matplotlib.pyplot as plt import openbb_terminal.session.local_model as Local import openbb_terminal.session.hub_model as Hub @@ -10,6 +12,12 @@ from openbb_terminal.helper_funcs import system_clear from openbb_terminal.rich_config import console +class LoginStatus(Enum): + SUCCESS = "success" + FAILED = "failed" + NO_RESPONSE = "no_response" + + def create_session(email: str, password: str, save: bool) -> dict: """Create a session. @@ -29,6 +37,24 @@ def create_session(email: str, password: str, save: bool) -> dict: return session +def login(session: dict) -> LoginStatus: + """Login and load user info. + + Parameters + ---------- + session : dict + The session info. + """ + response = Hub.fetch_user_configs(session) + if response: + if response.status_code == 200: + User.load_user_info(session) + Local.apply_configs(configs=json.loads(response.content)) + return LoginStatus.SUCCESS + return LoginStatus.FAILED + return LoginStatus.NO_RESPONSE + + def logout(cls: bool = False): """Logout and clear session.