import logging from service.tasks.data_model import initialize_schema, set_company_trial from service.tasks.emailing.email_welcome import send_welcome_email from service.tasks.management.cognito import create_user from service.utils.aws_connectors import run_query from .utils import ( POOL_NAME, esc, generate_password, generate_schema_id, make_date_in_future, ) logger = logging.getLogger(__name__) IGNORE_FIELDS = ["user_agent", "referrer", "b"] BILLING_CYCLE = {"0": "monthly", "1": "annual"} def make_pretty_data(d, h, **kv): return ( "" + "".format( **kv ) + "{timestamp}".format(**kv) + "".join( f"{esc(d[hf])}" if hf == "website" else f"{esc(d[hf] if hf in d else '')}" for hf in h ) + "" ) def page_pre_signup(message="", post_data=None, naughty_bits=None): """ Generate pre-signup list and allow operations delete/create accounts/ set trial period :return: """ if post_data is None: post_data = {} signups = run_query( """SELECT id, TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI:SS"') AS "timestamp", data FROM commons.raw_pre_signup WHERE onboarded is NULL""", return_type="dict", ) sign_frag = "{pretty_data}" header_fields = [] for sign in signups: header_fields.extend( k for k in sign["data"] if k not in IGNORE_FIELDS and k not in header_fields ) header = ( " signup" + "".join(f"{k}" for k in header_fields) + "" ) lines = "".join( sign_frag.format( **sign, pretty_data=make_pretty_data( sign["data"], header_fields, **sign, checked="checked" if f"row-select-{sign['id']}" in post_data else "", ), ) for sign in signups ) trial_end = ( post_data["trial-end"] if "trial-end" in post_data else make_date_in_future(weeks=2) ) package_select = ( f"" + "".join( f"" for p in run_query( "SELECT id, package_name, campaign_name FROM commons.packages ORDER BY id", return_type="dict", ) ) ) return f""" Fansifter Admin: Pre-Signup
{message}
 
""" def ingest_pre_signup_instructions(post_data, naughty_bits): """ Extract delete/create accounts info, send invite emails, etc. :param post_data: :param naughty_bits - xss token :return: """ message = "Nice try, nothing happened." if post_data.get("naughty-bits") == naughty_bits: message = "" if "delete" in post_data: if "delete-confirm" in post_data: del_ids = [] for pk, pd in post_data.items(): if pk.startswith("row-select-"): del_ids.append(int(pd)) if del_ids: try: run_query( f"DELETE FROM commons.raw_pre_signup WHERE id IN ({','.join(str(rid) for rid in del_ids)})" ) message = f"Deleted rows {del_ids}" except Exception as e: logger.exception("deletion failed", exc_info=e) else: message = "Nothing was selected for deleting, did nothing" else: message = "Please also check the confirm delete checkbox" if "onboard-trial" in post_data: onb_ids = [] for pk, pd in post_data.items(): if pk.startswith("row-select-"): onb_ids.append(int(pd)) if onb_ids: trial_end = post_data["trial-end"] try: new_users = run_query( f"SELECT id, data FROM commons.raw_pre_signup WHERE id IN ({','.join(str(rid) for rid in onb_ids)})" ) for ud in new_users: data = ud[1] try: new_email = data["email"] for existing_user in run_query( "SELECT email FROM commons.user_company WHERE email = %(email)s", {"email": new_email}, ): raise RuntimeError( f"User {existing_user[0]} already exists" ) temp_passwd = generate_password() management_schema = generate_schema_id() first_name = data["firstName"] last_name = data["lastName"] company_name = data["company"] package_name = data["package"] billing_cycle = ( BILLING_CYCLE[data["b"]] if "b" in data and data["b"] else "monthly" ) user_id = create_user( new_email, temp_passwd, management_schema, POOL_NAME, first_name, last_name, company_name, ) initialize_schema( management_schema, user_id, "company", new_email ) set_company_trial( management_schema, trial_end, package_name, billing_cycle, ) send_welcome_email( "welcome", new_email, first_name, temp_passwd=temp_passwd, ) message += f" onboarded {new_email} " run_query( "UPDATE commons.raw_pre_signup SET onboarded = now(), trial_end = %(trial_end)s " "WHERE id = %(pre_id)s", {"pre_id": ud[0], "trial_end": trial_end}, ) except Exception as e: message += f' Failed to onboard {ud[0]} : "{e}" ' except Exception as e: logger.exception("onboarding failed", exc_info=e) else: message = ( "Nothing was selected for onboarding, did nothing" ) if "onboard-package" in post_data: onb_ids = [] for pk, pd in post_data.items(): if pk.startswith("row-select-"): onb_ids.append(int(pd)) if onb_ids: trial_end = None try: new_users = run_query( f"SELECT id, data FROM commons.raw_pre_signup WHERE id IN ({','.join(str(rid) for rid in onb_ids)})" ) for ud in new_users: data = ud[1] try: new_email = data["email"] for existing_user in run_query( "SELECT email, default_schema FROM commons.user_company WHERE email = %(email)s", {"email": new_email}, ): # management_schema = existing_user[1] raise RuntimeError( f"User {existing_user[0]} already exists" ) else: management_schema = generate_schema_id() temp_passwd = generate_password() first_name = data["firstName"] last_name = data["lastName"] company_name = data["company"] billing_cycle = ( BILLING_CYCLE[data["b"]] if "b" in data and data["b"] else "monthly" ) if ( "package-select" in post_data and post_data["package-select"] == "keep" ): campaign_name = ( data["campaign"] if "campaign" in data else None ) package_name = data["package"] else: for package in run_query( "SELECT package_name, campaign_name FROM commons.packages WHERE id = %(pid)s", {"pid": post_data["package-select"]}, ): package_name = package[0] campaign_name = package[1] break else: campaign_name = None package_name = "Lite" user_id = create_user( new_email, temp_passwd, management_schema, POOL_NAME, first_name, last_name, company_name, ) initialize_schema( management_schema, user_id, "company", new_email ) set_company_trial( management_schema, trial_end, package_name, billing_cycle, trial=False, campaign=campaign_name, ) send_welcome_email( "welcome", new_email, first_name, temp_passwd=temp_passwd, ) message += f" onboarded {new_email} " run_query( "UPDATE commons.raw_pre_signup SET onboarded = now(), trial_end = %(trial_end)s " "WHERE id = %(pre_id)s", {"pre_id": ud[0], "trial_end": trial_end}, ) except Exception as e: message += f' Failed to onboard {ud[0]} : "{e}" ' except Exception as e: logger.exception("onboarding failed", exc_info=e) else: message = ( "Nothing was selected for onboarding, did nothing" ) return message