Refactor of Ticket flow. Stable to get confirmed Result via CLI. Not yet GUI
This commit is contained in:
parent
8dca35d5c9
commit
bf9063b1f8
12 changed files with 723 additions and 457 deletions
|
|
@ -18,11 +18,14 @@ class Constants:
|
||||||
|
|
||||||
# ticketing group:
|
# ticketing group:
|
||||||
TICKET_API_BASE_URL: Final[str] = os.environ.get(
|
TICKET_API_BASE_URL: Final[str] = os.environ.get(
|
||||||
"TICKET_API_BASE_URL", "https://api.hydraveil.net"
|
# "TICKET_API_BASE_URL", "https://api.hydraveil.net"
|
||||||
|
"TICKET_API_BASE_URL", "http://localhost:8000"
|
||||||
)
|
)
|
||||||
|
|
||||||
SP_API_BASE_URL: Final[str] = os.environ.get('SP_API_BASE_URL', 'https://api.hydraveil.net/api/v1')
|
SP_API_BASE_URL: Final[str] = os.environ.get('SP_API_BASE_URL', 'http://localhost:8000/api/v1')
|
||||||
SP_BASE_URL: Final[str] = os.environ.get('SP_BASE_URL', 'https://api.hydraveil.net/api')
|
SP_BASE_URL: Final[str] = os.environ.get('SP_BASE_URL', 'http://localhost:8000/api')
|
||||||
|
# SP_API_BASE_URL: Final[str] = os.environ.get('SP_API_BASE_URL', 'https://api.hydraveil.net/api/v1')
|
||||||
|
# SP_BASE_URL: Final[str] = os.environ.get('SP_BASE_URL', 'https://api.hydraveil.net/api')
|
||||||
|
|
||||||
PING_URL: Final[str] = os.environ.get('PING_URL', 'https://api.hydraveil.net/api/v1/health')
|
PING_URL: Final[str] = os.environ.get('PING_URL', 'https://api.hydraveil.net/api/v1/health')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ if TYPE_CHECKING:
|
||||||
from core.essentials.observers.ConnectionObserver import ConnectionObserver
|
from core.essentials.observers.ConnectionObserver import ConnectionObserver
|
||||||
from core.observers.TicketObserver import TicketObserver
|
from core.observers.TicketObserver import TicketObserver
|
||||||
#
|
#
|
||||||
from core.services.prepare_tickets.get_public_key_by_config import (
|
# from core.services.prepare_tickets.get_public_key_by_config import (
|
||||||
get_public_key_from_LOCAL_files_only,
|
# get_public_key_from_LOCAL_files_only,
|
||||||
)
|
# )
|
||||||
from core.services.failed_verification.is_the_key_to_blame import is_the_key_to_blame
|
from core.services.failed_verification.is_the_key_to_blame import is_the_key_to_blame
|
||||||
from core.services.failed_verification.prep_with_previously_saved_blind_sigs import (
|
from core.services.failed_verification.prep_with_previously_saved_blind_sigs import (
|
||||||
prep_with_previously_saved_blind_sigs,
|
prep_with_previously_saved_blind_sigs,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
from __future__ import annotations
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from core.essentials.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
from core.observers.TicketObserver import TicketObserver
|
from core.observers.TicketObserver import TicketObserver
|
||||||
|
|
||||||
from core.services.payment_phase.payment_state import TicketPaymentData
|
from core.services.payment_phase.payment_state import TicketPaymentData
|
||||||
# from core.services.prepare_tickets.get_pub_key import get_and_save_pub_key
|
from core.services.prepare_tickets.get_pub_key import get_and_save_pub_key
|
||||||
from core.utils.type_checker import type_checker
|
from core.utils.type_checker import type_checker
|
||||||
from core.services.prepare_tickets.ticket_prep_orchestrator import ticket_prep_orchestrator
|
from core.services.prepare_tickets.ticket_prep_orchestrator import ticket_prep_orchestrator
|
||||||
from core.services.prepare_tickets.make_sure_pub_key_exists import make_sure_pub_key_exists
|
from core.services.prepare_tickets.make_sure_pub_key_exists import make_sure_pub_key_exists
|
||||||
|
|
@ -14,7 +10,6 @@ from core.services.prepare_tickets import ticket_tracker
|
||||||
from core.services.helpers.get_how_many_profiles_were_ordered import (
|
from core.services.helpers.get_how_many_profiles_were_ordered import (
|
||||||
get_how_many_profiles_were_ordered,
|
get_how_many_profiles_were_ordered,
|
||||||
)
|
)
|
||||||
# from core.observers.BaseObserver import BaseObserver
|
|
||||||
from core.models.Result import Result, ResultError
|
from core.models.Result import Result, ResultError
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
||||||
|
|
@ -82,11 +77,12 @@ def prepare_tickets(
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
# got_key = get_and_save_pub_key(which_key)
|
got_key = get_and_save_pub_key(which_key, connection_observer)
|
||||||
# if not got_key.valid:
|
if not got_key.valid:
|
||||||
# logger.error(got_key.message)
|
logger.error(got_key.message)
|
||||||
# return got_key
|
return got_key
|
||||||
# logger.info("Got public key..")
|
public_key = got_key.data
|
||||||
|
logger.info("Got public key..")
|
||||||
|
|
||||||
notification = "Preparing Cryptography Locally"
|
notification = "Preparing Cryptography Locally"
|
||||||
if ticket_observer is not None:
|
if ticket_observer is not None:
|
||||||
|
|
@ -95,6 +91,7 @@ def prepare_tickets(
|
||||||
# ok now we have the pre-reqs, let's use this high level orchestrator,
|
# ok now we have the pre-reqs, let's use this high level orchestrator,
|
||||||
prep_results = ticket_prep_orchestrator(
|
prep_results = ticket_prep_orchestrator(
|
||||||
how_many_profiles=how_many_profiles,
|
how_many_profiles=how_many_profiles,
|
||||||
|
public_key=public_key,
|
||||||
ticket_observer=ticket_observer,
|
ticket_observer=ticket_observer,
|
||||||
connection_observer=connection_observer,
|
connection_observer=connection_observer,
|
||||||
which_ticket=which_ticket, # only relevant for single ticket prep
|
which_ticket=which_ticket, # only relevant for single ticket prep
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ if TYPE_CHECKING:
|
||||||
# services
|
# services
|
||||||
from core.services.crypto.TicketCustomer import TicketCustomer
|
from core.services.crypto.TicketCustomer import TicketCustomer
|
||||||
from core.services.helpers.validate_number_format import number_of_valid_length
|
from core.services.helpers.validate_number_format import number_of_valid_length
|
||||||
from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
# from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
||||||
from core.services.prepare_tickets.get_pub_key import key_is_in_valid_format, get_pub_key
|
from core.services.prepare_tickets.get_pub_key import key_is_in_valid_format, get_pub_key
|
||||||
from core.services.failed_verification.test_if_new_key_works import test_if_new_key_works
|
from core.services.failed_verification.test_if_new_key_works import test_if_new_key_works
|
||||||
from core.services.networking.make_url import make_url
|
from core.services.networking.make_url import make_url
|
||||||
|
|
|
||||||
252
core/services/payment_phase/old_get_pub_key.py
Normal file
252
core/services/payment_phase/old_get_pub_key.py
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
# services
|
||||||
|
from core.services.networking.make_url import make_url
|
||||||
|
from core.services.networking.httpx import connect
|
||||||
|
from core.services.helpers.get_plan_data import get_plan_data
|
||||||
|
from core.services.payment_phase.payment_state import TicketPaymentData
|
||||||
|
|
||||||
|
# utils
|
||||||
|
from core.utils.get_data import read_and_convert_with_eval
|
||||||
|
from core.models.Result import Result, ResultError
|
||||||
|
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||||
|
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||||
|
from core.utils.basic_operations.write_string_to_text_file import write_string_to_text_file
|
||||||
|
from core.errors.logger import logger
|
||||||
|
from core.Constants import Constants
|
||||||
|
|
||||||
|
# generic
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
|
def key_is_in_valid_format(public_key: Any) -> bool:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Confirms a Public Key's Format with X and Y in a dictionary.
|
||||||
|
Called by:
|
||||||
|
get_pub_key (this module)
|
||||||
|
validate_blind_signatures' make_sure_we_have_inputs (external modules)
|
||||||
|
"""
|
||||||
|
return set(public_key.keys()) == {"x", "y"}
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_key_from_server(which_key: str) -> dict|bool:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Gets the public key from the API.
|
||||||
|
Called by:
|
||||||
|
get_and_save_pub_key (this module)
|
||||||
|
get_public_key_used (this module)
|
||||||
|
"""
|
||||||
|
url = make_url(which_key)
|
||||||
|
|
||||||
|
public_key_results = connect.single_endpoint(
|
||||||
|
method="get",
|
||||||
|
url=url,
|
||||||
|
payload=None
|
||||||
|
)
|
||||||
|
|
||||||
|
if not public_key_results.valid:
|
||||||
|
error_msg = f"Error with API getting the Public Key: {public_key_results.error_type} and {public_key_results.message}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# extract:
|
||||||
|
public_key = public_key_results.data
|
||||||
|
|
||||||
|
return public_key
|
||||||
|
|
||||||
|
|
||||||
|
def get_and_save_pub_key(which_key: str) -> Result:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Fetches a public key and saves it. But you have to know which key you want.
|
||||||
|
Called by:
|
||||||
|
TicketPayController's initiate_payment
|
||||||
|
"""
|
||||||
|
from core.Constants import Constants
|
||||||
|
data_folder = Constants.HV_TICKETING_DATA_HOME
|
||||||
|
file_path = f"{data_folder}/{str(which_key)}.json"
|
||||||
|
|
||||||
|
if not which_key:
|
||||||
|
error_msg = "You have to know which key you want to use this function."
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
public_key = fetch_key_from_server(which_key)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = "Failed to connect to the API Server to get the public key."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
||||||
|
|
||||||
|
if not key_is_in_valid_format(public_key):
|
||||||
|
error_msg = f"The server gave the {which_key} public key in an Invalid Format."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_API_REPLY, message=error_msg)
|
||||||
|
|
||||||
|
# save it:
|
||||||
|
if not write_string_to_text_file(public_key, file_path):
|
||||||
|
error_msg = f"Error with saving the public key {which_key}. Please check your file system permissions. It tried to use this path: {file_path}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message=error_msg)
|
||||||
|
|
||||||
|
# finally:
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def get_from_config(get_what: str) -> str|bool:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Wrapper with config file structure for external loaders.
|
||||||
|
Called by:
|
||||||
|
actions.begin_ticket_prep
|
||||||
|
"""
|
||||||
|
from core.Constants import Constants
|
||||||
|
filepath = Constants.TICKET_BILLING
|
||||||
|
return _get_from_config(filepath, get_what)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_from_config(filepath: str, what_want: str) -> str|bool:
|
||||||
|
"""
|
||||||
|
Get some data from a dict-based file, and handle errors.
|
||||||
|
It assumes you have loaded the path on your own.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return get_value_from_json_file(filepath, what_want)
|
||||||
|
except (ValueError, KeyError) as e:
|
||||||
|
logger.error(f"We could not get {what_want} from the config at {filepath}, because {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def find_out_which_key_we_used() -> Result:
|
||||||
|
"""Returns which key plan was used based on the local config."""
|
||||||
|
|
||||||
|
billing_data = TicketPaymentData()
|
||||||
|
which_key = billing_data.which_key
|
||||||
|
|
||||||
|
if which_key:
|
||||||
|
return Result(valid=True, data=which_key)
|
||||||
|
|
||||||
|
|
||||||
|
# OLD DEAD CODE:
|
||||||
|
|
||||||
|
billing_folder = Constants.HV_TICKETING_CONFIG_HOME
|
||||||
|
filepath = f"{billing_folder}/billing_choices.json"
|
||||||
|
|
||||||
|
if not does_file_exist(filepath):
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message="The Billing Choices file is missing, we can't figure out what key or plan was used.")
|
||||||
|
|
||||||
|
which_key = _get_from_config(filepath, "which_key")
|
||||||
|
if which_key:
|
||||||
|
return Result(valid=True, data=which_key)
|
||||||
|
|
||||||
|
# can't find plan? try to get temp billing id.
|
||||||
|
temp_billing_code = _get_from_config(filepath, "billing_code")
|
||||||
|
|
||||||
|
if not temp_billing_code:
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message="The Billing Choices file does not have what key or plan was used.")
|
||||||
|
|
||||||
|
# fetch from server:
|
||||||
|
fetching_result = get_plan_data(temp_billing_code)
|
||||||
|
|
||||||
|
if not fetching_result.valid:
|
||||||
|
return fetching_result # this is already Result format with the error.
|
||||||
|
|
||||||
|
plan_data = fetching_result.data
|
||||||
|
which_key = plan_data.get("which_key", False)
|
||||||
|
|
||||||
|
if which_key:
|
||||||
|
return Result(valid=True, data=which_key)
|
||||||
|
else:
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_API_REPLY, message="The API gave us a reply, but it lacked the critical key data we needed.")
|
||||||
|
|
||||||
|
|
||||||
|
def get_local_copy_of_public_key(which_key: str) -> Result:
|
||||||
|
"""Once we know which key we're looking for, get and convert it from local files."""
|
||||||
|
|
||||||
|
from core.Constants import Constants
|
||||||
|
filepath = f"{Constants.HV_TICKETING_DATA_HOME}/{which_key}.json"
|
||||||
|
|
||||||
|
if not does_file_exist(filepath):
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message=f"The file doesn't exist, or you lack the permissions to open it, at {filepath}")
|
||||||
|
|
||||||
|
# Convert it to the format we need:
|
||||||
|
public_key = read_and_convert_with_eval(filepath)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = f"The local key of {which_key} is in the wrong format, even though the file exists."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
# this just checks if it has an X and Y in a dictionary:
|
||||||
|
if not key_is_in_valid_format(public_key) or not isinstance(public_key, dict):
|
||||||
|
error_msg = f"The local key of {which_key} is in the wrong format, even though the file exists."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def get_public_key_used(local_only: Optional[bool] = False, save_it: Optional[bool] = False) -> Result:
|
||||||
|
"""
|
||||||
|
1. Use the local config to figure out which key/plan
|
||||||
|
2. See if there's a local copy first, convert it.
|
||||||
|
3. If not fetch that from the API (unless local_only flag is on.)
|
||||||
|
|
||||||
|
Called by:
|
||||||
|
TicketPrepController's prepare_tickets
|
||||||
|
FailedVerificationController's evaluate_if_its_the_key
|
||||||
|
"""
|
||||||
|
# -------------------------
|
||||||
|
# Step 1. Which key was used?
|
||||||
|
# -------------------------
|
||||||
|
key_results = find_out_which_key_we_used()
|
||||||
|
|
||||||
|
if not key_results.valid:
|
||||||
|
return key_results
|
||||||
|
|
||||||
|
which_key = key_results.data
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Step 2. Do we have it locally?
|
||||||
|
# -------------------------
|
||||||
|
local_copy_result = get_local_copy_of_public_key(which_key)
|
||||||
|
|
||||||
|
if local_only:
|
||||||
|
return local_copy_result
|
||||||
|
|
||||||
|
if local_copy_result.valid:
|
||||||
|
return local_copy_result
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Step 3. Fetch it from the API
|
||||||
|
# -------------------------
|
||||||
|
public_key = fetch_key_from_server(which_key)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = f"Failed to connect to the API Server to get the public key {which_key}."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
||||||
|
|
||||||
|
if save_it:
|
||||||
|
return save_key(public_key, which_key)
|
||||||
|
|
||||||
|
# if they didn't flag on save_it, then we're done:
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def save_key(public_key: dict, which_key: str) -> Result:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Saves a public key locally, with a file path based on it's name.
|
||||||
|
Called by:
|
||||||
|
get_public_key_used (this module)
|
||||||
|
"""
|
||||||
|
from core.Constants import Constants
|
||||||
|
filepath = f"{Constants.HV_TICKETING_DATA_HOME}/{which_key}.json"
|
||||||
|
|
||||||
|
if write_string_to_text_file(public_key, filepath):
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
else:
|
||||||
|
error_msg = f"Error with saving the public key {which_key}. Please check your file system permissions. It tried to use this path: {filepath}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message=error_msg)
|
||||||
|
|
||||||
|
|
@ -1,120 +1,244 @@
|
||||||
from __future__ import annotations
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
from typing import Any
|
|
||||||
# services
|
# services
|
||||||
from core.services.networking.make_url import make_url
|
from core.services.networking.make_url import make_url
|
||||||
from core.services.networking.httpx import connect
|
from core.services.networking.httpx import connect
|
||||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
from core.services.helpers.get_plan_data import get_plan_data
|
||||||
|
|
||||||
# utils
|
# utils
|
||||||
|
from core.utils.get_data import read_and_convert_with_eval
|
||||||
|
from core.models.Result import Result, ResultError
|
||||||
|
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||||
from core.utils.basic_operations.write_string_to_text_file import write_string_to_text_file
|
from core.utils.basic_operations.write_string_to_text_file import write_string_to_text_file
|
||||||
# errors & constants
|
|
||||||
from core.Constants import Constants
|
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
from core.Constants import Constants
|
||||||
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
|
||||||
# generic
|
# generic
|
||||||
import ast
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
def key_is_in_valid_format(public_key: Any) -> bool:
|
def key_is_in_valid_format(public_key: Any) -> bool:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Confirms a Public Key's Format with X and Y in a dictionary.
|
||||||
|
Called by:
|
||||||
|
get_pub_key (this module)
|
||||||
|
validate_blind_signatures' make_sure_we_have_inputs (external modules)
|
||||||
|
"""
|
||||||
return set(public_key.keys()) == {"x", "y"}
|
return set(public_key.keys()) == {"x", "y"}
|
||||||
|
|
||||||
|
|
||||||
def get_from_server_and_save(
|
def fetch_key_from_server(which_key: str, connection_observer: ConnectionObserver) -> dict|bool:
|
||||||
string_form_of_key_name: str,
|
"""
|
||||||
file_path: str,
|
Purpose:
|
||||||
connection_observer: ConnectionObserver,
|
Gets the public key from the API.
|
||||||
) -> dict:
|
Called by:
|
||||||
|
get_and_save_pub_key (this module)
|
||||||
url = make_url(string_form_of_key_name)
|
get_public_key_used (this module)
|
||||||
|
"""
|
||||||
|
url = make_url(which_key)
|
||||||
|
|
||||||
public_key_results = connect.single_endpoint(
|
public_key_results = connect.single_endpoint(
|
||||||
method="get",
|
method="get",
|
||||||
url=url,
|
url=url,
|
||||||
observer=connection_observer,
|
payload=None,
|
||||||
payload=None
|
observer=connection_observer
|
||||||
)
|
)
|
||||||
|
|
||||||
if not public_key_results.valid:
|
if not public_key_results.valid:
|
||||||
error_msg = f"Error with API getting the Public Key: {public_key_results.error_type} and {public_key_results.message}"
|
error_msg = f"Error with API getting the Public Key: {public_key_results.error_type} and {public_key_results.message}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
return {"valid": False, "message": error_msg}
|
return False
|
||||||
|
|
||||||
# extract:
|
# extract:
|
||||||
public_key = public_key_results.data
|
public_key = public_key_results.data
|
||||||
|
|
||||||
print(f"public_key is {public_key}")
|
return public_key
|
||||||
|
|
||||||
|
|
||||||
|
def get_and_save_pub_key(which_key: str, connection_observer: ConnectionObserver) -> Result:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Fetches a public key and saves it. But you have to know which key you want.
|
||||||
|
Called by:
|
||||||
|
TicketPayController's initiate_payment
|
||||||
|
"""
|
||||||
|
data_folder = Constants.HV_TICKETING_DATA_HOME
|
||||||
|
file_path = f"{data_folder}/{str(which_key)}.json"
|
||||||
|
|
||||||
|
if not which_key:
|
||||||
|
error_msg = "You have to know which key you want to use this function."
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
public_key = fetch_key_from_server(which_key, connection_observer)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = "Failed to connect to the API Server to get the public key."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
||||||
|
|
||||||
|
if not key_is_in_valid_format(public_key):
|
||||||
|
error_msg = f"The server gave the {which_key} public key in an Invalid Format."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_API_REPLY, message=error_msg)
|
||||||
|
|
||||||
# save it:
|
# save it:
|
||||||
did_it_save = write_string_to_text_file(public_key, file_path)
|
if not write_string_to_text_file(public_key, file_path):
|
||||||
|
error_msg = f"Error with saving the public key {which_key}. Please check your file system permissions. It tried to use this path: {file_path}"
|
||||||
|
log_and_notify(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message=error_msg)
|
||||||
|
|
||||||
if not did_it_save:
|
# finally:
|
||||||
logger.error(f"Error with saving the public key {public_key} with write_string_to_text_file, but still returning data..")
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
# regardless of saving:
|
|
||||||
return {"valid": True, "data": public_key}
|
|
||||||
|
|
||||||
|
|
||||||
def get_pub_key(
|
def get_from_config(get_what: str) -> str|bool:
|
||||||
which_key: str,
|
"""
|
||||||
connection_observer: ConnectionObserver,
|
Purpose:
|
||||||
check_locally: str,
|
Wrapper with config file structure for external loaders.
|
||||||
) -> dict:
|
Called by:
|
||||||
|
actions.begin_ticket_prep
|
||||||
|
"""
|
||||||
|
from core.Constants import Constants
|
||||||
|
filepath = Constants.TICKET_BILLING
|
||||||
|
return _get_from_config(filepath, get_what)
|
||||||
|
|
||||||
# prep file path for either saving or using the existing one:
|
|
||||||
data_folder = Constants.HV_TICKETING_DATA_HOME
|
|
||||||
string_form_of_key_name = str(which_key)
|
|
||||||
file_path = f"{data_folder}/{string_form_of_key_name}.json"
|
|
||||||
|
|
||||||
# do we want to use the key if it's already stored locally?
|
def _get_from_config(filepath: str, what_want: str) -> str|bool:
|
||||||
if check_locally == "local":
|
"""
|
||||||
# does the public key already exist locally?
|
Get some data from a dict-based file, and handle errors.
|
||||||
exists_already = does_file_exist(file_path)
|
It assumes you have loaded the path on your own.
|
||||||
else:
|
"""
|
||||||
logger.debug("Getting Public Key from API..", exc_info=True)
|
|
||||||
# setting this to false bypasses it being local for the next section, and skips to the end
|
|
||||||
exists_already = False
|
|
||||||
|
|
||||||
# Next Section
|
|
||||||
if exists_already == True:
|
|
||||||
# we're going to try to get it from the file locally:
|
|
||||||
try:
|
try:
|
||||||
with open(file_path, "r") as file:
|
return get_value_from_json_file(filepath, what_want)
|
||||||
public_key_as_string = file.read()
|
except (ValueError, KeyError) as e:
|
||||||
|
logger.error(f"We could not get {what_want} from the config at {filepath}, because {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
# this gets in pyth dict with a single ', which is how the crypto functions need it.
|
|
||||||
public_key = ast.literal_eval(public_key_as_string)
|
|
||||||
|
|
||||||
if key_is_in_valid_format(public_key):
|
def find_out_which_key_we_used() -> Result:
|
||||||
return {"valid": True, "data": public_key}
|
"""Returns which key plan was used based on the local config."""
|
||||||
|
|
||||||
|
from core.Constants import Constants
|
||||||
|
billing_folder = Constants.HV_TICKETING_CONFIG_HOME
|
||||||
|
filepath = f"{billing_folder}/billing_choices.json"
|
||||||
|
|
||||||
|
if not does_file_exist(filepath):
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message="The Billing Choices file is missing, we can't figure out what key or plan was used.")
|
||||||
|
|
||||||
|
which_key = _get_from_config(filepath, "which_key")
|
||||||
|
if which_key:
|
||||||
|
return Result(valid=True, data=which_key)
|
||||||
|
|
||||||
|
# can't find plan? try to get temp billing id.
|
||||||
|
temp_billing_code = _get_from_config(filepath, "temp_billing_code")
|
||||||
|
|
||||||
|
if not temp_billing_code:
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message="The Billing Choices file does not have what key or plan was used.")
|
||||||
|
|
||||||
|
# fetch from server:
|
||||||
|
fetching_result = get_plan_data(temp_billing_code)
|
||||||
|
|
||||||
|
if not fetching_result.valid:
|
||||||
|
return fetching_result # this is already Result format with the error.
|
||||||
|
|
||||||
|
plan_data = fetching_result.data
|
||||||
|
which_key = plan_data.get("which_key", False)
|
||||||
|
|
||||||
|
if which_key:
|
||||||
|
return Result(valid=True, data=which_key)
|
||||||
else:
|
else:
|
||||||
print(
|
return Result(valid=False, error_type=ResultError.INVALID_API_REPLY, message="The API gave us a reply, but it lacked the critical key data we needed.")
|
||||||
"Key format is Invalid! Let's replace it by getting a new one from the server,"
|
|
||||||
)
|
|
||||||
public_key_results = get_from_server_and_save(
|
|
||||||
string_form_of_key_name, file_path, connection_observer
|
|
||||||
)
|
|
||||||
return public_key_results
|
|
||||||
|
|
||||||
# but if the local key doesn't format properly, then get it from the server,
|
|
||||||
except:
|
|
||||||
public_key_results = get_from_server_and_save(
|
|
||||||
string_form_of_key_name, file_path, connection_observer
|
|
||||||
)
|
|
||||||
|
|
||||||
return public_key_results
|
def get_local_copy_of_public_key(which_key: str) -> Result:
|
||||||
|
"""Once we know which key we're looking for, get and convert it from local files."""
|
||||||
|
|
||||||
# no local key? get from server,
|
from core.Constants import Constants
|
||||||
|
filepath = f"{Constants.HV_TICKETING_DATA_HOME}/{which_key}.json"
|
||||||
|
|
||||||
|
if not does_file_exist(filepath):
|
||||||
|
return Result(valid=False, error_type=ResultError.MISSING_DATA, message=f"The file doesn't exist, or you lack the permissions to open it, at {filepath}")
|
||||||
|
|
||||||
|
# Convert it to the format we need:
|
||||||
|
public_key = read_and_convert_with_eval(filepath)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = f"The local key of {which_key} is in the wrong format, even though the file exists."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
# this just checks if it has an X and Y in a dictionary:
|
||||||
|
if not key_is_in_valid_format(public_key) or not isinstance(public_key, dict):
|
||||||
|
error_msg = f"The local key of {which_key} is in the wrong format, even though the file exists."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
|
||||||
|
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def get_public_key_used(local_only: Optional[bool] = False, save_it: Optional[bool] = False) -> Result:
|
||||||
|
"""
|
||||||
|
1. Use the local config to figure out which key/plan
|
||||||
|
2. See if there's a local copy first, convert it.
|
||||||
|
3. If not fetch that from the API (unless local_only flag is on.)
|
||||||
|
|
||||||
|
Called by:
|
||||||
|
TicketPrepController's prepare_tickets
|
||||||
|
FailedVerificationController's evaluate_if_its_the_key
|
||||||
|
"""
|
||||||
|
# -------------------------
|
||||||
|
# Step 1. Which key was used?
|
||||||
|
# -------------------------
|
||||||
|
key_results = find_out_which_key_we_used()
|
||||||
|
|
||||||
|
if not key_results.valid:
|
||||||
|
return key_results
|
||||||
|
|
||||||
|
which_key = key_results.data
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Step 2. Do we have it locally?
|
||||||
|
# -------------------------
|
||||||
|
local_copy_result = get_local_copy_of_public_key(which_key)
|
||||||
|
|
||||||
|
if local_only:
|
||||||
|
return local_copy_result
|
||||||
|
|
||||||
|
if local_copy_result.valid:
|
||||||
|
return local_copy_result
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Step 3. Fetch it from the API
|
||||||
|
# -------------------------
|
||||||
|
public_key = fetch_key_from_server(which_key)
|
||||||
|
|
||||||
|
if not public_key:
|
||||||
|
error_msg = f"Failed to connect to the API Server to get the public key {which_key}."
|
||||||
|
logger.error(error_msg)
|
||||||
|
return Result(valid=False, error_type=ResultError.CONNECTION, message=error_msg)
|
||||||
|
|
||||||
|
if save_it:
|
||||||
|
return save_key(public_key, which_key)
|
||||||
|
|
||||||
|
# if they didn't flag on save_it, then we're done:
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def save_key(public_key: dict, which_key: str) -> Result:
|
||||||
|
"""
|
||||||
|
Purpose:
|
||||||
|
Saves a public key locally, with a file path based on it's name.
|
||||||
|
Called by:
|
||||||
|
get_public_key_used (this module)
|
||||||
|
"""
|
||||||
|
from core.Constants import Constants
|
||||||
|
filepath = f"{Constants.HV_TICKETING_DATA_HOME}/{which_key}.json"
|
||||||
|
|
||||||
|
if write_string_to_text_file(public_key, filepath):
|
||||||
|
return Result(valid=True, data=public_key)
|
||||||
else:
|
else:
|
||||||
logger.debug(
|
error_msg = f"Error with saving the public key {which_key}. Please check your file system permissions. It tried to use this path: {filepath}"
|
||||||
"You do not have the public key locally. So we are getting it from the server.."
|
log_and_notify(error_msg)
|
||||||
)
|
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message=error_msg)
|
||||||
public_key_results = get_from_server_and_save(
|
|
||||||
string_form_of_key_name, file_path, connection_observer
|
|
||||||
)
|
|
||||||
|
|
||||||
return public_key_results
|
|
||||||
|
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
# services & helpers
|
|
||||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
|
||||||
from core.services.prepare_tickets.get_pub_key import get_pub_key
|
|
||||||
from core.services.prepare_tickets.get_pub_key import key_is_in_valid_format
|
|
||||||
from core.services.helpers.get_plan_data import get_plan_data
|
|
||||||
# utils
|
|
||||||
from core.utils.basic_operations.filter_data import filter_data
|
|
||||||
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
|
||||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
|
||||||
# constants
|
|
||||||
from core.Constants import Constants
|
|
||||||
# generic
|
|
||||||
import ast
|
|
||||||
|
|
||||||
"""
|
|
||||||
This service tries to get a public key, based on the config file.
|
|
||||||
It first checks if the config file has which key it wants.
|
|
||||||
Then it checks for a temp billing code, and if there is one, asks the server what the key is.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
# Get which key plan they have.
|
|
||||||
def get_public_key_FROM_config(filepath) -> str | None:
|
|
||||||
try:
|
|
||||||
which_key = get_value_from_json_file(filepath, "which_key")
|
|
||||||
return which_key
|
|
||||||
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_public_key_by_config(connection_observer: ConnectionObserver) -> dict:
|
|
||||||
list_of_failures = [None, False, ""]
|
|
||||||
billing_folder = Constants.HV_TICKETING_CONFIG_HOME
|
|
||||||
filepath = f"{billing_folder}/billing_choices.json"
|
|
||||||
|
|
||||||
which_key = get_public_key_FROM_config(filepath)
|
|
||||||
|
|
||||||
# if there is no key in the config?
|
|
||||||
if which_key is None:
|
|
||||||
|
|
||||||
# then try to get the temp billing id.
|
|
||||||
temp_billing_code = get_value_from_json_file(filepath, "temp_billing_code")
|
|
||||||
|
|
||||||
# but what if there is not even a temp billing ID?
|
|
||||||
if temp_billing_code in list_of_failures:
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issue with finding key plan or billing code. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Now we're assuming we have a temp billing code,
|
|
||||||
# So we can use that to get the key from the server,
|
|
||||||
api_reply_object = get_plan_data(temp_billing_code, connection_observer)
|
|
||||||
|
|
||||||
complete_failure_msg = {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issues with both finding your local key plan and even connecting to the server for it. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
if not api_reply_object.valid:
|
|
||||||
return complete_failure_msg
|
|
||||||
|
|
||||||
reply = api_reply_object.data
|
|
||||||
|
|
||||||
if reply in list_of_failures:
|
|
||||||
return complete_failure_msg
|
|
||||||
|
|
||||||
if not isinstance(reply, dict):
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Server returned an invalid format, and even accessing via local files. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
# from the server's reply, get the key
|
|
||||||
which_key = filter_data(reply, "which_key")
|
|
||||||
if which_key in list_of_failures:
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issues with both finding your local key plan and getting it from the server. Please check {filepath}",
|
|
||||||
}
|
|
||||||
# The reason we convert it to integer, only to convert it back to a string in the next functions,
|
|
||||||
# is because those functions can be accessed directly in other ways that would have the key as an integer.
|
|
||||||
# which_key = int(which_key)
|
|
||||||
|
|
||||||
# send to service:
|
|
||||||
public_key_results = get_pub_key(which_key, connection_observer, "local")
|
|
||||||
|
|
||||||
# if public_key_results is None:
|
|
||||||
# return {'status': False, 'message': "no_public_key"}
|
|
||||||
|
|
||||||
# assert public_key_results is not None
|
|
||||||
return public_key_results
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
This seems like a duplicate function, but it's used in situations where there was a failed validation.
|
|
||||||
The other functions get the key from local files OR the api. And they save it, which would replace the key we want to study.
|
|
||||||
Instead, this function gets it only from local files.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_public_key_from_LOCAL_files_only(
|
|
||||||
connection_observer: ConnectionObserver,
|
|
||||||
) -> dict:
|
|
||||||
billing_folder = Constants.HV_TICKETING_CONFIG_HOME
|
|
||||||
filepath = f"{billing_folder}/billing_choices.json"
|
|
||||||
try:
|
|
||||||
which_key = get_value_from_json_file(filepath, "which_key")
|
|
||||||
except:
|
|
||||||
which_key = None
|
|
||||||
finally:
|
|
||||||
list_of_failures = [None, False, ""]
|
|
||||||
if which_key in list_of_failures:
|
|
||||||
# can't find plan? try to get temp billing id.
|
|
||||||
temp_billing_code = get_value_from_json_file(filepath, "temp_billing_code")
|
|
||||||
|
|
||||||
if temp_billing_code in list_of_failures:
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issue with finding key plan or billing code. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
api_reply_object = get_plan_data(temp_billing_code, connection_observer)
|
|
||||||
|
|
||||||
complete_failure_msg = {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issues with both finding your local key plan and even connecting to the server for it. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
if not api_reply_object.valid:
|
|
||||||
return complete_failure_msg
|
|
||||||
|
|
||||||
reply = api_reply_object.data
|
|
||||||
|
|
||||||
if reply in list_of_failures:
|
|
||||||
return complete_failure_msg
|
|
||||||
|
|
||||||
if not isinstance(reply, dict):
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Server returned an invalid format, and even accessing via local files. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
which_key = filter_data(reply, "which_key")
|
|
||||||
if which_key in list_of_failures:
|
|
||||||
return {
|
|
||||||
"status": False,
|
|
||||||
"message": f"Issues with both finding your local key plan and getting it from the server. Please check {filepath}",
|
|
||||||
}
|
|
||||||
|
|
||||||
# now that we know the key plan, move on to getting the data:
|
|
||||||
data_folder = Constants.HV_TICKETING_DATA_HOME
|
|
||||||
string_form_of_key_name = str(which_key)
|
|
||||||
file_path = f"{data_folder}/{string_form_of_key_name}.json"
|
|
||||||
|
|
||||||
# does it exist?
|
|
||||||
exists_already = does_file_exist(file_path)
|
|
||||||
if not exists_already:
|
|
||||||
return {"valid": False, "message": "Local key file doesn't exist"}
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(file_path, "r") as file:
|
|
||||||
public_key_as_string = file.read()
|
|
||||||
|
|
||||||
# this gets in pyth dict with a single ', which is how the crypto functions need it.
|
|
||||||
public_key = ast.literal_eval(public_key_as_string)
|
|
||||||
|
|
||||||
# this only checks if the key has 'x' and 'y' keys:
|
|
||||||
if key_is_in_valid_format(public_key):
|
|
||||||
return {"valid": True, "public_key": public_key}
|
|
||||||
else:
|
|
||||||
return {
|
|
||||||
"valid": False,
|
|
||||||
"message": "Key file exists but is in an invalid format.",
|
|
||||||
}
|
|
||||||
except:
|
|
||||||
return {
|
|
||||||
"valid": False,
|
|
||||||
"message": "Key file exists but is in an invalid format or unreadable.",
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
from essentials.observers.ConnectionObserver import ConnectionObserver
|
||||||
#
|
#
|
||||||
from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
# from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
||||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||||
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
|
|
|
||||||
181
core/services/prepare_tickets/old_validate_blind_signatures.py
Normal file
181
core/services/prepare_tickets/old_validate_blind_signatures.py
Normal file
|
|
@ -0,0 +1,181 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from core.observers.TicketObserver import TicketObserver
|
||||||
|
from essentials.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
# services
|
||||||
|
from core.services.crypto.TicketCustomer import TicketCustomer
|
||||||
|
from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
||||||
|
from core.services.prepare_tickets.get_pub_key import key_is_in_valid_format, get_pub_key
|
||||||
|
# utils
|
||||||
|
from core.utils.save_data import save_data
|
||||||
|
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||||
|
# observers, constants, errors
|
||||||
|
from core.observers.BaseObserver import BaseObserver
|
||||||
|
from core.models.Event import Event
|
||||||
|
from core.Constants import Constants
|
||||||
|
from core.errors.exceptions import *
|
||||||
|
from core.errors.logger import logger
|
||||||
|
# generic
|
||||||
|
import traceback
|
||||||
|
import json
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
def make_sure_we_have_inputs(
|
||||||
|
ALL_signed_blind_signatures: list,
|
||||||
|
profile_object: TicketCustomer,
|
||||||
|
ticket_observer: TicketObserver,
|
||||||
|
connection_observer: ConnectionObserver,
|
||||||
|
) -> dict:
|
||||||
|
|
||||||
|
try:
|
||||||
|
if ALL_signed_blind_signatures == False or ALL_signed_blind_signatures == None:
|
||||||
|
error_msg = "The Server gave back no data or it's missing for ALL_signed_blind_signatures in the unblind_and_prove_ALL_profiles function . This can't unblind blank data."
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
logger.debug(error_msg)
|
||||||
|
return {"valid": False, "error_msg": error_msg}
|
||||||
|
|
||||||
|
# get the public key for entire loop:
|
||||||
|
public_key_results = get_public_key_by_config(connection_observer)
|
||||||
|
|
||||||
|
# did we actually get the public key?
|
||||||
|
if "data" not in public_key_results:
|
||||||
|
error_msg = (
|
||||||
|
"The validation function can't even get the public key to do it's loop"
|
||||||
|
)
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
logger.debug(error_msg)
|
||||||
|
return {"valid": False, "error_msg": error_msg}
|
||||||
|
|
||||||
|
public_key = public_key_results.get("data")
|
||||||
|
|
||||||
|
rejected_reasons = [None, False, ""]
|
||||||
|
if public_key in rejected_reasons:
|
||||||
|
error_msg = "The validation function can't get the public key"
|
||||||
|
logger.debug(error_msg)
|
||||||
|
return {"valid": False, "error_msg": error_msg}
|
||||||
|
|
||||||
|
# this just checks if it has an X and Y in a dictionary:
|
||||||
|
if not key_is_in_valid_format(public_key) or not isinstance(public_key, dict):
|
||||||
|
return {"valid": False, "error_msg": "invalid_key_format"}
|
||||||
|
|
||||||
|
logger.debug("Checking if the public key is even able to be loaded...")
|
||||||
|
valid_key = profile_object.load_key(public_key)
|
||||||
|
|
||||||
|
if valid_key:
|
||||||
|
logger.debug("Public Key can be loaded")
|
||||||
|
return {"valid": True, "public_key": public_key}
|
||||||
|
|
||||||
|
else:
|
||||||
|
error_msg = "The validation function is working with an invalid public key"
|
||||||
|
logger.debug(error_msg)
|
||||||
|
return {"valid": False, "error_msg": error_msg}
|
||||||
|
|
||||||
|
except:
|
||||||
|
error_msg = (
|
||||||
|
"We lack the ability to get all the inputs for the verification loop"
|
||||||
|
)
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
logger.debug(error_msg)
|
||||||
|
return {"valid": False, "error_msg": error_msg}
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Technically this entire module is optional, as it isn't used for the actual ticket preparation.
|
||||||
|
|
||||||
|
This module exists so the customer can be sure that the server did not maliciously sign with a fake new key,
|
||||||
|
to try to secretly identify users (by using different keys for each one).
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def validate_blind_signatures(
|
||||||
|
ALL_signed_blind_signatures: list,
|
||||||
|
ticket_observer: TicketObserver,
|
||||||
|
connection_observer: ConnectionObserver,
|
||||||
|
which_ticket: Optional[int] = None,
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
# Setup the entire class object of "profile_object" for using all these other functions,
|
||||||
|
profile_object = TicketCustomer()
|
||||||
|
|
||||||
|
# start: confirm inputs
|
||||||
|
inputs = make_sure_we_have_inputs(
|
||||||
|
ALL_signed_blind_signatures,
|
||||||
|
profile_object,
|
||||||
|
ticket_observer,
|
||||||
|
connection_observer,
|
||||||
|
)
|
||||||
|
if not inputs["valid"]:
|
||||||
|
logger.debug("ending the validation process early.")
|
||||||
|
return inputs
|
||||||
|
public_key = inputs["public_key"]
|
||||||
|
# end: confirm inputs
|
||||||
|
|
||||||
|
# setup basic counters, flags, and lists for the loop below:
|
||||||
|
|
||||||
|
if which_ticket is None:
|
||||||
|
which_ticket = 1
|
||||||
|
|
||||||
|
did_we_answer_the_key_question_yet = "no"
|
||||||
|
list_of_failed_verifications = []
|
||||||
|
|
||||||
|
"""
|
||||||
|
LOOP STARTS:
|
||||||
|
|
||||||
|
Looping through each signature, verifying it against the single public key.
|
||||||
|
"""
|
||||||
|
for each_blind_signature in ALL_signed_blind_signatures:
|
||||||
|
# prep from server's format:
|
||||||
|
blind_signature = json.loads(each_blind_signature)
|
||||||
|
|
||||||
|
#### Check blind signature validity for THAT signature:
|
||||||
|
validity_data = profile_object.test_blind_signature_validity(
|
||||||
|
which_ticket, blind_signature, public_key
|
||||||
|
)
|
||||||
|
|
||||||
|
if validity_data["valid"] == True:
|
||||||
|
# verification went fine:
|
||||||
|
notification = f"Verified {which_ticket}'s blind signature"
|
||||||
|
ticket_observer.notify("preparing", subject=notification)
|
||||||
|
else:
|
||||||
|
# is it an invalid pub key?
|
||||||
|
if validity_data["message"] == "invalid_key":
|
||||||
|
notification = f"Verification of all blind signatures is halted, because you have an invalid public key!"
|
||||||
|
ticket_observer.notify("preparing", subject=notification)
|
||||||
|
return [which_ticket]
|
||||||
|
|
||||||
|
# otherwise:
|
||||||
|
list_of_failed_verifications.append(which_ticket)
|
||||||
|
notification = f"Invalid {which_ticket} blind signature"
|
||||||
|
ticket_observer.notify("preparing", subject=notification)
|
||||||
|
|
||||||
|
# bump loop for next round:
|
||||||
|
which_ticket = which_ticket + 1
|
||||||
|
|
||||||
|
### LOOP DONE
|
||||||
|
logger.debug(
|
||||||
|
f"Exiting the validation loop with the list_of_failed_verifications: {list_of_failed_verifications}"
|
||||||
|
)
|
||||||
|
return list_of_failed_verifications
|
||||||
|
|
||||||
|
except FailedToSave as e:
|
||||||
|
error_msg = f"FailedToSave: {e}"
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
return {"valid": False, "message": "error", "error": error_msg}
|
||||||
|
|
||||||
|
except InvalidData as e:
|
||||||
|
error_msg = f"InvalidData error: {e}"
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
return {"valid": False, "message": "error", "error": error_msg}
|
||||||
|
|
||||||
|
except MissingData as e:
|
||||||
|
error_msg = f"MissingData: {e}"
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
return {"valid": False, "message": "error", "error": error_msg}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tb = traceback.extract_tb(e.__traceback__)[-1]
|
||||||
|
error_msg = f"error type {type(e).__name__} happened on line {tb.lineno}, in function {tb.name}, giving error: {e}. The actual code in question is: {tb.line}. in this file: {tb.filename}"
|
||||||
|
logger.error(error_msg, exc_info=True)
|
||||||
|
return {"valid": False, "message": "error", "error": error_msg}
|
||||||
|
|
@ -6,22 +6,18 @@ if TYPE_CHECKING:
|
||||||
from core.observers.TicketObserver import TicketObserver
|
from core.observers.TicketObserver import TicketObserver
|
||||||
|
|
||||||
# services
|
# services
|
||||||
# from core.services.networking.httpx import connect
|
|
||||||
# from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
|
||||||
from core.services.networking.make_url import make_url
|
from core.services.networking.make_url import make_url
|
||||||
# from core.services.payment_phase.ticket_config_tools import get_which_billing_key
|
|
||||||
|
|
||||||
# models & their controllers
|
# models & their controllers
|
||||||
from core.models.manage.server_reply_tools import api_call_and_extraction, ApiCall, translate_server_failure
|
from core.models.manage.server_reply_tools import api_call_and_extraction, ApiCall, translate_server_failure
|
||||||
from core.models.pydantic_models.ServerReply import ServerReply, ServerError
|
from core.models.pydantic_models.ServerReply import ServerReply, ServerError
|
||||||
# from core.models.session.SessionProfile import SessionProfile
|
from core.services.payment_phase.payment_state import TicketPaymentData
|
||||||
# from core.models.system.SystemProfile import SystemProfile
|
|
||||||
|
|
||||||
# utils
|
# utils
|
||||||
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||||
|
|
||||||
# constants & errors
|
# constants & errors
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
# from core.errors.exceptions import InvalidData, ServerSideError
|
|
||||||
from core.models.Result import Result, ResultError
|
from core.models.Result import Result, ResultError
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
||||||
|
|
@ -40,12 +36,15 @@ def prep_payload_for_bulk(list_of_all_blinded_data: list) -> dict:
|
||||||
Rank:
|
Rank:
|
||||||
Mini-Helper
|
Mini-Helper
|
||||||
"""
|
"""
|
||||||
# get temp billing id from local storage:
|
# billing code
|
||||||
temp_billing_code = get_value_from_json_file(billing_path, "temp_billing_code")
|
billing_data = TicketPaymentData()
|
||||||
|
billing_code = billing_data.billing_code
|
||||||
|
|
||||||
|
# temp_billing_code = get_value_from_json_file(billing_path, "temp_billing_code")
|
||||||
|
|
||||||
# prep the JSON payload, it doesn't need the public key, since the server can look that up,
|
# prep the JSON payload, it doesn't need the public key, since the server can look that up,
|
||||||
payload = {
|
payload = {
|
||||||
"temp_billing_code": temp_billing_code,
|
"billing_code": billing_code,
|
||||||
"blinded_data": list_of_all_blinded_data,
|
"blinded_data": list_of_all_blinded_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.observers.TicketObserver import TicketObserver
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
|
|
||||||
|
from core.observers.TicketObserver import TicketObserver
|
||||||
|
|
||||||
from core.services.crypto.make_commitments import make_ALL_commitments
|
from core.services.crypto.make_commitments import make_ALL_commitments
|
||||||
from core.services.prepare_tickets.unblind_all_tickets import unblind_ALL_tickets
|
from core.services.prepare_tickets.unblind_all_tickets import unblind_ALL_tickets
|
||||||
|
|
@ -46,6 +46,7 @@ Called by:
|
||||||
@type_checker
|
@type_checker
|
||||||
def ticket_prep_orchestrator(
|
def ticket_prep_orchestrator(
|
||||||
how_many_profiles: int,
|
how_many_profiles: int,
|
||||||
|
public_key: dict,
|
||||||
ticket_observer: TicketObserver,
|
ticket_observer: TicketObserver,
|
||||||
connection_observer: ConnectionObserver,
|
connection_observer: ConnectionObserver,
|
||||||
which_ticket: Optional[int] = None,
|
which_ticket: Optional[int] = None,
|
||||||
|
|
@ -106,11 +107,14 @@ def ticket_prep_orchestrator(
|
||||||
# verify the server's blind signatures against the public key,
|
# verify the server's blind signatures against the public key,
|
||||||
notification = "Evaluating the Server's Blind Replies"
|
notification = "Evaluating the Server's Blind Replies"
|
||||||
ticket_observer.notify("preparing", subject=notification)
|
ticket_observer.notify("preparing", subject=notification)
|
||||||
failed_validations = validate_blind_signatures(
|
validations = validate_blind_signatures(
|
||||||
blind_signatures, ticket_observer, connection_observer, which_ticket
|
ALL_signed_blind_signatures=blind_signatures,
|
||||||
|
public_key=public_key,
|
||||||
|
ticket_observer=ticket_observer,
|
||||||
|
which_ticket=which_ticket
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f"failed_validations is {failed_validations}")
|
failed_validations = validations.data
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# FAILED BLIND SIG VERIFICATION
|
# FAILED BLIND SIG VERIFICATION
|
||||||
|
|
@ -129,14 +133,6 @@ def ticket_prep_orchestrator(
|
||||||
message=notification
|
message=notification
|
||||||
)
|
)
|
||||||
|
|
||||||
#####################################################
|
|
||||||
# PAID
|
|
||||||
#####################################################
|
|
||||||
# saving on config that it's paid:
|
|
||||||
config_marked = ConfigurationController.mark_as_paid(True)
|
|
||||||
if not config_marked:
|
|
||||||
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message="Failed to mark as paid in the config. You still have the tickets locally, just can't use them till this file system error is resolved.")
|
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# UNBLIND
|
# UNBLIND
|
||||||
#####################################################
|
#####################################################
|
||||||
|
|
@ -149,6 +145,7 @@ def ticket_prep_orchestrator(
|
||||||
connection_observer=connection_observer,
|
connection_observer=connection_observer,
|
||||||
which_ticket=which_ticket
|
which_ticket=which_ticket
|
||||||
)
|
)
|
||||||
|
logger.info(f"Unblind completed. Was it a success? {did_prep_work}")
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# TICKET TRACKER & APP-WIDE CONFIG
|
# TICKET TRACKER & APP-WIDE CONFIG
|
||||||
|
|
@ -157,6 +154,7 @@ def ticket_prep_orchestrator(
|
||||||
setup_tracker = setup_ticket_tracker(how_many_profiles)
|
setup_tracker = setup_ticket_tracker(how_many_profiles)
|
||||||
if not setup_tracker:
|
if not setup_tracker:
|
||||||
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message="Failed to setup the ticket tracker. You still have the tickets locally, just can't use them till this file system error is resolved.")
|
return Result(valid=False, error_type=ResultError.FILE_SYSTEM, message="Failed to setup the ticket tracker. You still have the tickets locally, just can't use them till this file system error is resolved.")
|
||||||
|
logger.info("Ticket tracker setup completed.")
|
||||||
|
|
||||||
#####################################################
|
#####################################################
|
||||||
# FINAL EVALUATION
|
# FINAL EVALUATION
|
||||||
|
|
@ -165,6 +163,7 @@ def ticket_prep_orchestrator(
|
||||||
# this means it unblinded, & setup the tracker without erroring out,
|
# this means it unblinded, & setup the tracker without erroring out,
|
||||||
# but it does NOT mean that verification of the blind sigs worked.
|
# but it does NOT mean that verification of the blind sigs worked.
|
||||||
ConfigurationController.tickets_setup(True)
|
ConfigurationController.tickets_setup(True)
|
||||||
|
logger.info("Setup Complete.")
|
||||||
return Result(valid=True, message="Setup worked.")
|
return Result(valid=True, message="Setup worked.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,17 @@
|
||||||
from __future__ import annotations
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from core.observers.TicketObserver import TicketObserver
|
from core.observers.TicketObserver import TicketObserver
|
||||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
# services
|
# services
|
||||||
from core.services.crypto.TicketCustomer import TicketCustomer
|
from core.services.crypto.TicketCustomer import TicketCustomer
|
||||||
from core.services.prepare_tickets.get_public_key_by_config import get_public_key_by_config
|
|
||||||
from core.services.prepare_tickets.get_pub_key import key_is_in_valid_format, get_pub_key
|
|
||||||
# utils
|
# utils
|
||||||
from core.utils.save_data import save_data
|
from core.models.Result import Result #, ResultError
|
||||||
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
|
||||||
# observers, constants, errors
|
|
||||||
from core.observers.BaseObserver import BaseObserver
|
|
||||||
from core.models.Event import Event
|
|
||||||
from core.Constants import Constants
|
|
||||||
from core.errors.exceptions import *
|
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
||||||
# generic
|
# generic
|
||||||
import traceback
|
|
||||||
import json
|
import json
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
def make_sure_we_have_inputs(
|
REJECTED_INPUTS = [False, None, "error"]
|
||||||
ALL_signed_blind_signatures: list,
|
|
||||||
profile_object: TicketCustomer,
|
|
||||||
ticket_observer: TicketObserver,
|
|
||||||
connection_observer: ConnectionObserver,
|
|
||||||
) -> dict:
|
|
||||||
|
|
||||||
try:
|
|
||||||
if ALL_signed_blind_signatures == False or ALL_signed_blind_signatures == None:
|
|
||||||
error_msg = "The Server gave back no data or it's missing for ALL_signed_blind_signatures in the unblind_and_prove_ALL_profiles function . This can't unblind blank data."
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
logger.debug(error_msg)
|
|
||||||
return {"valid": False, "error_msg": error_msg}
|
|
||||||
|
|
||||||
# get the public key for entire loop:
|
|
||||||
public_key_results = get_public_key_by_config(connection_observer)
|
|
||||||
|
|
||||||
# did we actually get the public key?
|
|
||||||
if "data" not in public_key_results:
|
|
||||||
error_msg = (
|
|
||||||
"The validation function can't even get the public key to do it's loop"
|
|
||||||
)
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
logger.debug(error_msg)
|
|
||||||
return {"valid": False, "error_msg": error_msg}
|
|
||||||
|
|
||||||
public_key = public_key_results.get("data")
|
|
||||||
|
|
||||||
rejected_reasons = [None, False, ""]
|
|
||||||
if public_key in rejected_reasons:
|
|
||||||
error_msg = "The validation function can't get the public key"
|
|
||||||
logger.debug(error_msg)
|
|
||||||
return {"valid": False, "error_msg": error_msg}
|
|
||||||
|
|
||||||
# this just checks if it has an X and Y in a dictionary:
|
|
||||||
if not key_is_in_valid_format(public_key) or not isinstance(public_key, dict):
|
|
||||||
return {"valid": False, "error_msg": "invalid_key_format"}
|
|
||||||
|
|
||||||
logger.debug("Checking if the public key is even able to be loaded...")
|
|
||||||
valid_key = profile_object.load_key(public_key)
|
|
||||||
|
|
||||||
if valid_key:
|
|
||||||
logger.debug("Public Key can be loaded")
|
|
||||||
return {"valid": True, "public_key": public_key}
|
|
||||||
|
|
||||||
else:
|
|
||||||
error_msg = "The validation function is working with an invalid public key"
|
|
||||||
logger.debug(error_msg)
|
|
||||||
return {"valid": False, "error_msg": error_msg}
|
|
||||||
|
|
||||||
except:
|
|
||||||
error_msg = (
|
|
||||||
"We lack the ability to get all the inputs for the verification loop"
|
|
||||||
)
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
logger.debug(error_msg)
|
|
||||||
return {"valid": False, "error_msg": error_msg}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Technically this entire module is optional, as it isn't used for the actual ticket preparation.
|
Technically this entire module is optional, as it isn't used for the actual ticket preparation.
|
||||||
|
|
@ -91,40 +23,28 @@ to try to secretly identify users (by using different keys for each one).
|
||||||
|
|
||||||
def validate_blind_signatures(
|
def validate_blind_signatures(
|
||||||
ALL_signed_blind_signatures: list,
|
ALL_signed_blind_signatures: list,
|
||||||
|
public_key: dict,
|
||||||
ticket_observer: TicketObserver,
|
ticket_observer: TicketObserver,
|
||||||
connection_observer: ConnectionObserver,
|
which_ticket: Optional[int] = None, # Single or Multiple Ticket Prep. If there's a value here, it's a single ticket.
|
||||||
which_ticket: Optional[int] = None,
|
) -> Result:
|
||||||
):
|
|
||||||
try:
|
|
||||||
# Setup the entire class object of "profile_object" for using all these other functions,
|
# Setup the entire class object of "profile_object" for using all these other functions,
|
||||||
profile_object = TicketCustomer()
|
profile_object = TicketCustomer()
|
||||||
|
|
||||||
# start: confirm inputs
|
#-----------------------------------
|
||||||
inputs = make_sure_we_have_inputs(
|
# PREPARE FOR UPCOMING LOOP
|
||||||
ALL_signed_blind_signatures,
|
#-----------------------------------
|
||||||
profile_object,
|
|
||||||
ticket_observer,
|
|
||||||
connection_observer,
|
|
||||||
)
|
|
||||||
if not inputs["valid"]:
|
|
||||||
logger.debug("ending the validation process early.")
|
|
||||||
return inputs
|
|
||||||
public_key = inputs["public_key"]
|
|
||||||
# end: confirm inputs
|
|
||||||
|
|
||||||
# setup basic counters, flags, and lists for the loop below:
|
# setup basic counters, flags, and lists for the loop below:
|
||||||
|
|
||||||
if which_ticket is None:
|
if which_ticket is None: # this is if it's a single or multiple ticket prep. And not just basic filtering
|
||||||
which_ticket = 1
|
which_ticket = 1
|
||||||
|
|
||||||
did_we_answer_the_key_question_yet = "no"
|
|
||||||
list_of_failed_verifications = []
|
list_of_failed_verifications = []
|
||||||
|
|
||||||
"""
|
#-----------------------------------
|
||||||
LOOP STARTS:
|
# LOOP:
|
||||||
|
#-----------------------------------
|
||||||
Looping through each signature, verifying it against the single public key.
|
# Looping through each signature, verifying it against the single public key.
|
||||||
"""
|
|
||||||
for each_blind_signature in ALL_signed_blind_signatures:
|
for each_blind_signature in ALL_signed_blind_signatures:
|
||||||
# prep from server's format:
|
# prep from server's format:
|
||||||
blind_signature = json.loads(each_blind_signature)
|
blind_signature = json.loads(each_blind_signature)
|
||||||
|
|
@ -136,46 +56,23 @@ def validate_blind_signatures(
|
||||||
|
|
||||||
if validity_data["valid"] == True:
|
if validity_data["valid"] == True:
|
||||||
# verification went fine:
|
# verification went fine:
|
||||||
notification = f"Verified {which_ticket}'s blind signature"
|
logger.info(f"Verified {which_ticket}'s blind signature")
|
||||||
ticket_observer.notify("preparing", subject=notification)
|
|
||||||
else:
|
else:
|
||||||
# is it an invalid pub key?
|
# is it an invalid pub key?
|
||||||
if validity_data["message"] == "invalid_key":
|
if validity_data["message"] == "invalid_key":
|
||||||
notification = f"Verification of all blind signatures is halted, because you have an invalid public key!"
|
error_msg = "Verification of all blind signatures is halted, because you have an invalid public key!"
|
||||||
ticket_observer.notify("preparing", subject=notification)
|
return Result(valid=True, data=[which_ticket], message=error_msg)
|
||||||
return [which_ticket]
|
|
||||||
|
|
||||||
# otherwise:
|
# otherwise:
|
||||||
list_of_failed_verifications.append(which_ticket)
|
list_of_failed_verifications.append(which_ticket)
|
||||||
notification = f"Invalid {which_ticket} blind signature"
|
logger.error(f"Invalid {which_ticket} blind signature")
|
||||||
ticket_observer.notify("preparing", subject=notification)
|
|
||||||
|
|
||||||
# bump loop for next round:
|
# bump loop for next round:
|
||||||
which_ticket = which_ticket + 1
|
which_ticket = which_ticket + 1
|
||||||
|
|
||||||
### LOOP DONE
|
### LOOP DONE
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Exiting the validation loop with the list_of_failed_verifications: {list_of_failed_verifications}"
|
f"Exiting the validation loop with the list_of_failed_verifications: {list_of_failed_verifications}"
|
||||||
)
|
)
|
||||||
return list_of_failed_verifications
|
return Result(valid=True, data=list_of_failed_verifications)
|
||||||
|
|
||||||
except FailedToSave as e:
|
|
||||||
error_msg = f"FailedToSave: {e}"
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
return {"valid": False, "message": "error", "error": error_msg}
|
|
||||||
|
|
||||||
except InvalidData as e:
|
|
||||||
error_msg = f"InvalidData error: {e}"
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
return {"valid": False, "message": "error", "error": error_msg}
|
|
||||||
|
|
||||||
except MissingData as e:
|
|
||||||
error_msg = f"MissingData: {e}"
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
return {"valid": False, "message": "error", "error": error_msg}
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
tb = traceback.extract_tb(e.__traceback__)[-1]
|
|
||||||
error_msg = f"error type {type(e).__name__} happened on line {tb.lineno}, in function {tb.name}, giving error: {e}. The actual code in question is: {tb.line}. in this file: {tb.filename}"
|
|
||||||
logger.error(error_msg, exc_info=True)
|
|
||||||
return {"valid": False, "message": "error", "error": error_msg}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue