HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //proc/thread-self/root/home/arjun/projects/buyercall/buyercall/blueprints/user/views.py
import copy
import uuid
import logging
import traceback
<<<<<<< HEAD
from datetime import datetime
import tldextract
import traceback
=======
import requests

>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
from sqlalchemy import func
from flask import (
    Blueprint,
    redirect,
    request,
    flash,
    url_for,
    render_template,
    current_app,
<<<<<<< HEAD
    session,
    g)
from buyercall.blueprints.activity.models import ActivityType, ActivityName, ActivityLogs

=======
    session)
from buyercall.blueprints.activity.models import ActivityType, ActivityName, ActivityLogs
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
from buyercall.blueprints.user.decorators import role_required
from flask_login import (
    login_required,
    login_user,
    current_user,
    logout_user)
from flask_babel import gettext as _
from flask_cors import CORS

from buyercall.lib.safe_next_url import safe_next_url
from buyercall.lib.util_two_factor_auth import send_verification_code
from buyercall.blueprints.user.decorators import anonymous_required
from buyercall.blueprints.user.forms import (
    LoginForm,
    TwoFactorAuthForm,
    BeginPasswordResetForm,
    PasswordResetForm,
    SignupForm,
    UpdateCredentials,
    UpdatePersonalDetails,
    UpdateLocale,
    UpdatePhoneNumber,
    UpdateSecurity,
    PersonalInformationForm,
    SecurtyInformationForm,
    UpdateSecurityForm,
    ThemeSettingsForm)
from buyercall.extensions import bcrypt, db
from buyercall.blueprints.agents.models import Agent
from buyercall.blueprints.widgets.models import Widget
from buyercall.blueprints.filters import format_phone_number
from buyercall.blueprints.user.models import User
from buyercall.blueprints.partnership.models import Partnership, PartnershipAccount
from buyercall.lib.supervisor_manager import (
    current_supervisor_user,
    login_user as supervisor_login_user,
    logout_user as supervisor_logout_user,
    login_required as supervisor_login_required)
from buyercall.blueprints.filters import format_phone_number_bracket
<<<<<<< HEAD
from dateutil.tz import UTC
from buyercall.blueprints.notification.utilities import send_notifications
from buyercall.lib.util_boto3_s3 import refresh_presigned_url, generate_presigned_file_url

# from buyercall.extensions import socket, emit
=======
from buyercall.blueprints.user.utilities.failed_login_notify import FailedLoginNotifier
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b

log = logging.getLogger(__name__)
user = Blueprint('user', __name__, template_folder='templates')
CORS(user)  # enable CORS on the user blueprint
ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png']


def get_partnership():
    # Get partnership details by user's partner_url
    if 'request_config' in g:
        if 'partner_url' in g.request_config:
            partnership = Partnership.query.filter(Partnership.partner_url == g.request_config['partner_url']).first()
            if partnership:
                return partnership
    return Partnership.query.get(1)


@user.route('/login', methods=['GET', 'POST'])
@anonymous_required()
def login():
    domain = request.host.replace('www', '')
    white_label = False
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_logo = primary_partner.logo
    partner_name = primary_partner.name
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                white_label = True
                if partner.logo:
                    partner_logo = partner.logo
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
                partner_name = partner.name
<<<<<<< HEAD
    form = LoginForm(next=request.args.get('next'))
    next_url = request.form.get('next')
    remember = request.form.get('remember', False)
    if remember == 'y':
        remember = True
    else:
        remember = False

    # get partnership details
    partnership = get_partnership()
    partnership_logo = partnership.alternative_logo
    if '::' in partnership_logo:
        bucket_name, key = partnership_logo.split("::")
        partnership_logo = generate_presigned_file_url(key, bucket_name)

    if form.validate_on_submit():
        u = User.find_by_identity(request.form.get('identity').lower())

        try:
            if u and u.authenticated(password=request.form.get('password')):

                # As you can see remember me is always enabled, this was a design
                # decision I made because more often than not users want this
                # enabled. This allows for a less complicated login form.
                #
                # If however you want them to be able to select whether they
                # should remain logged in then perform the following 3 steps:
                # 1) Replace 'True' below with: request.form.get('remember', False)
                # 2) Uncomment the 'remember' field in user/forms.py#LoginForm
                # 3) Add a checkbox to the login form with the id/name 'remember'

                # Check to see if the user has done security on-boarding yet
                if not u.two_factor_auth_onboard:
                    return redirect(url_for('user.additional_user_security_onboarding',
                                            user_sid=u.sid,
                                            url=next_url,
                                            remember=remember))
                # Have the user verify their account with two-factor authentication
                # if two_factor_auth is set to True
                if u.two_factor_auth:
                    code = send_verification_code(u.phonenumber)
                    log.info('the verification code is: {}'.format(code))

                    data = {
                        'user_id': u.sid,
                        'notify_message_type': 'TWO_FACTOR_AUTH_REQUEST',
                        'user_related_entities': "You've",
                        'other_user_related_entities': f'{u.firstname} {u.lastname}',
                        'hyperlink': f'{partnership.partner_url}/dashboard'
                    }
                    response = send_notifications(**data)

                    return redirect(url_for('user.two_factor_auth',
                                            user_sid=u.sid,
                                            url=next_url,
                                            remember=remember))
                # Login the user and redirect them to the appropriate page
                if u.active and login_user(u, remember=remember):
                    u.update_activity_tracking(request.remote_addr)
                    data = {
                        'user_id': u.sid,
                        'notify_message_type': 'LOGGED_IN',
                        'other_user_related_entities': f'{u.firstname} {u.lastname}',
                        'user_related_entities': "You've",
                        'hyperlink': f'{partnership.partner_url}/dashboard'
                    }

                    response = send_notifications(**data)
                    # Handle optionally redirecting to the next URL safely
                    if next_url:
                        return redirect(safe_next_url(next_url))

                    # if current_user.role in ['sysadmin', 'partner'] and not current_user.is_admin_user_with_groups:
                    #
                    #     return redirect(url_for('dashboard.user_dashboard'))
                    # elif current_user.role in ['admin'] and current_user.is_admin_user_with_groups \
                    #         and current_user.is_viewing_partnership \
                    #         and current_user.get_user_viewing_partnership_account_subscription_plan != 'partnershipsingle':
                    #     return redirect(url_for('dashboard.user_dashboard'))
                    # elif current_user.role in ['admin'] and current_user.is_admin_user_with_groups \
                    #         and current_user.is_viewing_partnership \
                    #         and current_user.get_user_viewing_partnership_account_subscription_plan == 'partnershipsingle':
                    #     return redirect(url_for('contacts.user_dashboard'))
                    # elif current_user.is_admin_user_with_groups:
                    #     return redirect(url_for('partnership.user_dashboard'))
                    # elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                    #     return redirect(url_for('contacts.user_dashboard'))
                    # elif current_user.subscription and current_user.subscription.plan == 'partnershipsingle':
                    #     return redirect(url_for('user.user_dashboard'))
                    else:
                        return redirect(url_for('dashboard.user_dashboard'))
                else:
                    flash(_('This account has been disabled.'), 'danger')
            else:
                flash(_('Email or password is incorrect.'), 'danger')
        except Exception as e:
            print("Error : ", e)
            log.error(traceback.format_exc())
            log.info('There is an issue with the password for user: {}'.format(u.email))
            flash(
                _('There is a problem with your password. Please reset your password by clicking '
                  'on the forget your password? link below the submit button.'),
                'danger')
    return render_template('user/login.jinja2', form=form, partnership=partnership, partnership_logo=partnership_logo)


@user.route('/login-old', methods=['GET', 'POST'])
@anonymous_required()
def login_old():
=======
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
    form = LoginForm(next=request.args.get('next'))
    next_url = request.form.get('next')
    remember = request.form.get('remember', False)
    if remember == 'y':
        remember = True
    else:
        remember = False

    recaptcha_response = request.form.get('g-recaptcha-response', None)
    if not recaptcha_response:
        return render_template('user/login.jinja2', white_label=white_label, partner_logo=partner_logo,
                               partner_name=partner_name, partner_url=partner_url,
                               partner_custom_styles=partner_custom_styles, form=form,
                               site_key=current_app.config.get('RC_SITE_KEY_V3'))

    verify_url = 'https://www.google.com/recaptcha/api/siteverify'
    response = requests.post(
        f"{verify_url}?secret={current_app.config.get('RC_SECRET_KEY_V3')}&response={recaptcha_response}").json()
    if not response.get('success', False):
        log.info('Please add a valid Google ReCaptcha keys, or add your domain to the ReCaptcha admin console.')
        return render_template('user/login.jinja2', white_label=white_label, partner_logo=partner_logo,
                               partner_name=partner_name, partner_url=partner_url,
                               partner_custom_styles=partner_custom_styles, form=form,
                               site_key=current_app.config.get('RC_SITE_KEY_V3'))

    if form.validate_on_submit():
        user_email = request.form.get('identity')
        u = User.find_by_identity(user_email.lower())
        if u is None:
            flash(_(f'The email address {user_email} does not exist. Please try again or contact support.'), 'danger')
            return render_template('user/login.jinja2', white_label=white_label, partner_logo=partner_logo,
                                   partner_name=partner_name, partner_url=partner_url,
                                   partner_custom_styles=partner_custom_styles, form=form,
                                   site_key=current_app.config.get('RC_SITE_KEY_V3'))
        if FailedLoginNotifier(u).is_blocked():
            return render_template('user/login.jinja2', white_label=white_label, partner_logo=partner_logo,
                                   partner_name=partner_name, partner_url=partner_url,
                                   partner_custom_styles=partner_custom_styles, form=form,
                                   site_key=current_app.config.get('RC_SITE_KEY_V3'))
        try:
            if u and u.authenticated(password=request.form.get('password')):
                # As you can see remember me is always enabled, this was a design
                # decision I made because more often than not users want this
                # enabled. This allows for a less complicated login form.
                #
                # If however you want them to be able to select whether they
                # should remain logged in then perform the following 3 steps:
                # 1) Replace 'True' below with: request.form.get('remember', False)
                # 2) Uncomment the 'remember' field in user/forms.py#LoginForm
                # 3) Add a checkbox to the login form with the id/name 'remember'

                # Set session variable to be identified during 2FA and TOS
                session["user_identify"] = u.email.lower()
                # logic to save ip address
                u.save_ip_address(ip_address=request.remote_addr)

                # start logic to save user-agent
                new_os_status = u.save_user_agent(os_value=request.user_agent.string)
                if new_os_status:
                    from buyercall.blueprints.user.tasks import send_new_os_notification, send_support_new_os_notification
                    from user_agents import parse
                    from buyercall.blueprints.user.utilities.get_request_location import UserUtilities

                    # fetch user-agent details
                    user_agent = parse(request.user_agent.string)

                    # get partnership name from user
                    partnership_name = u.get_partnership_name(u) or u.email

                    # get partnership logo
                    if u.partnership_id:
                        partnership_logo = u.partnership.logo
                    else:
                        partnership_logo = None

                    # get location details based on ip

                    user_ip = request.environ.get('HTTP_X_FORWARDED_FOR') \
                        if request.environ.get('HTTP_X_FORWARDED_FOR') else request.remote_addr

                    data = UserUtilities().get_request_complete_details(user_ip)

                    # password reset url
                    reset_token = u.serialize_token()

                    # send email for new user-agent to user
                    send_new_os_notification.delay(username=u.name or u.email,
                                                   partnership_name=partnership_name,
                                                   reset_token=reset_token,
                                                   location=f"{data.get('city')},"
                                                            f" {data.get('regionName')},"
                                                            f" {data.get('country')}" if data else None,
                                                   subject=f"New login alert to {partnership_name},"
                                                           f" from {user_agent.browser.family} on {user_agent.os.family}",
                                                   device=f"{user_agent.browser.family}{user_agent.browser.version_string},"
                                                          f" {user_agent.os.family}{user_agent.os.version_string}",
                                                   email=u.email,
                                                   ip=data.get('query'),
                                                   partnership_logo=partnership_logo)
                    """
                    # send email for new user-agent to support
                    send_support_new_os_notification.delay(partnership_name=partnership_name,
                                                           location=f"{data.get('city')},"
                                                                    f" {data.get('regionName')},"
                                                                    f" {data.get('country')}" if data else None,
                                                           subject=f"New login alert to {partnership_name},"
                                                           f" from {user_agent.browser.family} on {user_agent.os.family} ",
                                                           device=f"{user_agent.browser.family}{user_agent.browser.version_string},"
                                                           f" {user_agent.os.family}{user_agent.os.version_string}",
                                                           email=u.email,
                                                           ip=data.get('query'),
                                                           partnership_logo=partnership_logo)
                    """
                # end start logic to save user-agent

                # start password expiry check
                reset_token = u.serialize_token()
                password_status = u.get_password_expire_status(u)
                if not password_status:
                    # Construct the URL with the reset_token as a query parameter
                    reset_url = url_for('user.password_reset') + f"?reset_token={reset_token}"
                    # Redirect to the reset URL
                    flash(_('Your password has expired, please reset your password'), 'danger')
                    return redirect(reset_url)
                # end password expiry check

                # Check to see if the user has done security on-boarding yet
                if not u.two_factor_auth_onboard:
                    return redirect(url_for('user.additional_user_security_onboarding',
                                            user_id=u.id,
                                            url=next_url,
                                            remember=remember))
<<<<<<< HEAD
                # Have the user verify their account with two-factor authentication
                # if two_factor_auth is set to True
                if u.two_factor_auth:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
                    if u.partnership is None:
                        p_name = ''
                        p_no = ''
                    else:
                        p_name = u.partnership.name
                        p_no = u.partnership.operational_number
                    code = send_verification_code(format_phone_number(u.phonenumber), p_name, p_no)
                    log.info('the verification code is: {}'.format(code))
=======
                # Has the user verified their account with two-factor authentication
                # if two_factor_auth is set to True
                if u.two_factor_auth:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
                    send_verification_code(u)
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
                    return redirect(url_for('user.two_factor_auth',
                                            user_id=u.id,
                                            url=next_url,
                                            remember=remember))
                # Has the user agreed to tos
                if not u.tos_agreement:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
                    return redirect(url_for('user.tos_get',
                                            user_id=u.id,
                                            url=next_url,
                                            remember=remember))
                # Login the user and redirect them to the appropriate page
                if u.active and login_user(u, remember=remember):
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
                    u.update_activity_tracking(request.remote_addr)

                    # Reset failed login attempts on successful login
                    FailedLoginNotifier(u).reset_attempt()

                    # Handle optionally redirecting to the next URL safely
                    if next_url:
                        return redirect(safe_next_url(next_url))

<<<<<<< HEAD
                    if current_user.role in ['sysadmin', 'limitsysadmin', 'partner'] and not current_user.is_admin_user_with_groups:
=======
                    if current_user.role in ['sysadmin', 'limitsysadmin',
                                             'partner'] and not current_user.is_admin_user_with_groups:
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
                        return redirect(url_for('admin.dashboard'))
                    elif current_user.role in ['admin'] and current_user.is_admin_user_with_groups \
                            and current_user.is_viewing_partnership \
                            and current_user.get_user_viewing_partnership_account_subscription_plan != 'partnershipsingle':
                        return redirect(url_for('dashboard.user_dashboard_old'))
                    elif current_user.role in ['admin'] and current_user.is_admin_user_with_groups \
                            and current_user.is_viewing_partnership \
                            and current_user.get_user_viewing_partnership_account_subscription_plan == 'partnershipsingle':
                        return redirect(url_for('contacts.contact_list'))
                    elif current_user.is_admin_user_with_groups:
                        return redirect(url_for('partnership.company_accounts'))
                    elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                        return redirect(url_for('contacts.contact_list'))
                    elif current_user.subscription and current_user.subscription.plan == 'partnershipsingle':
                        return redirect(url_for('user.settings'))
                    else:
                        return redirect(url_for('dashboard.user_dashboard_old'))
                else:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
<<<<<<< HEAD
                    flash(_('This account has been disabled.'), 'danger')
            else:
                if u:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
                flash(_('Email or password is incorrect.'), 'danger')
=======
                    if FailedLoginNotifier(u).notify():
                        flash(_("We’ve detected 3 failed attempts to login. The account has been temporarily locked. "
                                "Please try again in 15 minutes."), 'danger')
                    else:
                        flash(_('This account has been disabled.'), 'danger')
            else:
                if u:
                    ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)

                    # Set user login failed attempts
                    if FailedLoginNotifier(u).notify():
                        flash(_("We’ve detected 3 failed attempts to login. The account has been temporarily locked. "
                                "Please try again in 15 minutes."), 'danger')
                    else:
                        flash(_('Email address or password is incorrect.'), 'danger')

                # save email id posted to the request log error
                from buyercall.blueprints.sysadmin.models import RequestLog
                import json
                request_id = request.environ.get('HTTP_X_REQUEST_ID')
                # updating the request log with the error
                RequestLog().update_record(
                    request_id, {"error": f"Login Failed with email: {request.form.get('identity').lower()}"})

                flash(_('Identity or password is incorrect.'), 'danger')
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b

        except Exception as e:
            print(f"The exception in login is {e}")
            log.error(traceback.format_exc())
            if u:
                log.info('There is an issue with the password for user: {}'.format(u.email))
                ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
<<<<<<< HEAD
            flash(_("There is a problem with your password. Please reset your password by clicking on "
                    "the 'forget your password?' link below the submit button."), 'danger')
    return render_template('user/login_old.jinja2', form=form)



# Ask the user if they want to do 2 factor authentication onboarding page
# The user will be able to enable 2 factor authentication, which will be
# prompted every time they login
@user.route('/additional_user_security/<uuid:user_sid>', methods=['GET', 'POST'])
def additional_user_security_onboarding(user_sid):
    domain = request.host.replace('www', '')
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partner_name = primary_partner.name
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
                partner_name = partner.name

    # Find the current active user in the database
    active_user = User.query.filter(User.sid == user_sid, User.is_deactivated.is_(False)).first()
    # The form allowing the user to update their phone number, which will
    # receive the sms two-factor authentication
    form = UpdatePhoneNumber(phonenumber=active_user.phonenumber)
    # Gather the next url from the request. This is the
    # url the user intends to visit after doing the on-boarding
    next_url = request.args.get('url')
    # Get the 'remember me' boolean from the request
    remember = request.args.get('remember')
    if remember == 'True':
        remember = True
    else:
        remember = False

    # Get partnership details by partner_url
    partnership = get_partnership()
    partnership_logo = partnership.alternative_logo
    if '::' in partnership_logo:
        bucket_name, key = partnership_logo.split("::")
        partnership_logo = generate_presigned_file_url(key, bucket_name)
    
    if form.validate_on_submit():
        active_user.phonenumber = request.form.get('phonenumber')
        # Set the on-boarding field to true. If set to True
        # the user will not see the on-boarding screen again
        active_user.two_factor_auth_onboard = True
        # By setting two_factor_auth True two-factor authentication will
        # be enabled for the user
        active_user.two_factor_auth = True

        db.session.commit()
        flash(_('Great. Two step verification has been enabled on your account. After'
                ' logging in you will be asked to verify your account through a verification code.'), 'success')
        # Redirect the user back to log in them to use the two-step verification
        return redirect(url_for('user.login'))

    return render_template('user/two_factor_auth_onboarding.jinja2', form=form,
                           user=active_user,
                           next_url=next_url,
                           remember=remember,
                           partner_custom_styles=partner_custom_styles,
                           partner_url=partner_url,
                           partner_name=partner_name,
                           partnership_logo=partnership_logo
                           )


# This function gets called when the user decides to decline two-factor authentication
# on the on-boarding page
@user.route('/decline_additional_securty/<uuid:user_sid>', methods=['GET', 'POST'])
def decline_additional_security(user_sid):
    active_user = User.query.filter(User.sid == user_sid, User.is_deactivated.is_(False)).first()
    next_url = request.args.get('url')
    remember = request.args.get('remember')
    if remember == 'True':
        remember = True
    else:
        remember = False
    if request.method == 'POST':
        active_user.two_factor_auth_onboard = True
        active_user.two_factor_auth = False
        flash(_('You have opted out of two step verification. You can enable it at any time under '
                'your account settings. two step verification will help keep your account extra secure.'), 'warning')
        # Has the user agreed to the terms and conditions
        if active_user.active and active_user.tos_agreement is False:
            return redirect(url_for('user.tos_get',
                                    user_id=active_user.id,
                                    url=next_url,
                                    remember=remember))
        # Login the user and redirect them to the appropriate page
        if active_user.active and login_user(active_user, remember=remember):
            ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
            active_user.update_activity_tracking(request.remote_addr)
            partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
            if not partnership:
                partnership = Partnership.query.get(1)

            if next_url:
                return redirect(safe_next_url(next_url))
            if active_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                return redirect(url_for('admin.dashboard'))
            elif active_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                return redirect(url_for('contacts.contact_list'))
            elif active_user.subscription and active_user.subscription.plan == 'partnershipsingle':
                return redirect(url_for('user.settings'))
            else:
                return redirect(url_for('dashboard.user_dashboard'))
        else:
            ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
            flash(_('This account has been disabled.'), 'danger')
=======

                # Set user login failed attempts
                if FailedLoginNotifier(u).notify():
                    flash(_("We’ve detected 3 failed attempts to login. The account has been temporarily locked. "
                            "Please try again in 15 minutes."), 'danger')
                else:
                    flash(_("There is a problem with your password. Please reset your password by clicking on "
                            "the 'forget your password?' link below the submit button."), 'danger')
            else:
                flash(_("There is a problem with your password. Please reset your password by clicking on "
                        "the 'forget your password?' link below the submit button."), 'danger')

            flash(_("There is a problem with your password. Please reset your password by clicking on "
                    "the 'forget your password?' link below the submit button."), 'danger')

    return render_template('user/login.jinja2', white_label=white_label, partner_logo=partner_logo,
                           partner_name=partner_name, partner_url=partner_url,
                           partner_custom_styles=partner_custom_styles, form=form,
                           site_key=current_app.config.get('RC_SITE_KEY_V3'))


# Ask the user if they want to do 2-factor authentication onboarding page
# The user will be able to enable 2-factor authentication, which will be
# prompted every time they log in
@user.route('/additional_user_security/<int:user_id>', methods=['GET', 'POST'])
def additional_user_security_onboarding(user_id):
    # Find the current active user in the database
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    if active_user and active_user.email.lower() == session.get('user_identify'):
        choice_len = 0
        domain = request.host.replace('www', '')
        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_url = primary_partner.partner_url
        partner_custom_styles = primary_partner.custom_styles
        partner_name = primary_partner.name
        partners = Partnership.query.filter(Partnership.active.is_(True)).all()
        for partner in partners:
            if partner.partner_url and partner.id != 1:
                partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
                if partner_domain == domain:
                    partner_url = partner_domain
                    if partner.custom_styles:
                        partner_custom_styles = partner.custom_styles
                    partner_name = partner.name

        form = UpdateSecurity()

        crt_user_phone = format_phone_number_bracket(active_user.phonenumber)
        crt_user_email = active_user.email
        sms_label = 'SMS - ' + crt_user_phone
        email_label = 'Email - ' + crt_user_email
        # Generate choices based on boolean fields from the database
        choices = []
        if active_user.role in ('admin', 'agent'):
            if active_user.partnership.is_2fa_sms_enabled and active_user.partnership_account.is_2fa_sms_enabled:
                choices.append(('field1', sms_label))
            if active_user.partnership.is_2fa_email_enabled and active_user.partnership_account.is_2fa_email_enabled:
                if active_user.partnership.is_2fa_sms_enabled and active_user.partnership_account.is_2fa_sms_enabled:
                    choices.append(('field2', email_label))
                else:
                    choices.append(('field1', email_label))
        elif active_user.role == 'partner':
            if active_user.partnership.is_2fa_sms_enabled:
                choices.append(('field1', sms_label))
            if active_user.partnership.is_2fa_email_enabled:
                if active_user.partnership.is_2fa_sms_enabled:
                    choices.append(('field2', email_label))
                else:
                    choices.append(('field1', email_label))

        elif active_user.role in ('sysadmin', 'limitsysadmin'):
            choices.append(('field1', sms_label))
            choices.append(('field2', email_label))

        form.choice.choices = choices
        if len(choices) > 1:
            choice_len = 2

        # Gather the next url from the request. This is the
        # url the user intends to visit after doing the on-boarding
        next_url = request.args.get('url')
        # Get the 'remember me' boolean from the request
        remember = request.args.get('remember', 'False')
        if remember == 'True':
            remember = True
        else:
            remember = False
        if form.validate_on_submit():
            if form.auth_method.data == 'SMS':
                active_user.is_2fa_sms = True
                active_user.is_2fa_email = False
            elif form.auth_method.data == 'EMAIL':
                active_user.is_2fa_sms = False
                active_user.is_2fa_email = True
            # Set the on-boarding field to true. If set to True
            # the user will not see the on-boarding screen again
            active_user.two_factor_auth_onboard = True
            # By setting two_factor_auth True two-factor authentication will
            # be enabled for the user
            active_user.two_factor_auth = True

            db.session.commit()
            flash(_('Great. Two step verification has been enabled on your account. After'
                    ' logging in you will be asked to verify your account through a verification code.'), 'success')
            # Redirect the user back to log in them to use the two-step verification
            return redirect(url_for('user.login'))

        return render_template('user/two_factor_auth_onboarding.jinja2', form=form,
                               user=active_user,
                               next_url=next_url,
                               remember=remember,
                               partner_custom_styles=partner_custom_styles,
                               partner_url=partner_url,
                               partner_name=partner_name,
                               choice_len=choice_len
                               )
    else:
        flash(_('We were unable to identify your account. Please try again or contact support.'), 'danger')
        # Redirect the user back to log in due to failing session check
        return redirect(url_for('user.login'))


# This function gets called when the user decides to decline two-factor authentication
# on the on-boarding page
@user.route('/decline_additional_securty/<int:user_id>', methods=['GET', 'POST'])
def decline_additional_security(user_id):
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    if active_user and active_user.email.lower() == session.get('user_identify'):
        next_url = request.args.get('url')
        remember = request.args.get('remember', 'False')
        if remember == 'True':
            remember = True
        else:
            remember = False
        if request.method == 'POST':
            active_user.two_factor_auth_onboard = True
            active_user.two_factor_auth = False
            db.session.commit()
            # Has the user agreed to the terms and conditions
            if active_user.active and active_user.tos_agreement is False:
                return redirect(url_for('user.tos_get',
                                        user_id=active_user.id,
                                        url=next_url,
                                        remember=remember))
            # Login the user and redirect them to the appropriate page
            """
            if active_user.active and login_user(active_user, remember=remember):
                ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
                active_user.update_activity_tracking(request.remote_addr)
                if next_url:
                    return redirect(safe_next_url(next_url))
                if active_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                    return redirect(url_for('admin.dashboard'))
                elif active_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                    return redirect(url_for('contacts.contact_list'))
                elif active_user.subscription and active_user.subscription.plan == 'partnershipsingle':
                    return redirect(url_for('user.settings'))
                else:
                    return redirect(url_for('dashboard.user_dashboard'))
            else:
                ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
                flash(_('This account has been disabled.'), 'danger')
                return redirect(url_for('user.login'))
            """
            flash(_('You have opted out of two step verification. You can enable it at any time under '
                    'your account settings, which we highly recommend. Please login to continue.'), 'warning')
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
            return redirect(url_for('user.login'))
    else:
        flash(_('We were unable to decline your actions. Please try again or contact support.'), 'danger')
        # Redirect the user back to log in due to failing session check
        return redirect(url_for('user.login'))


<<<<<<< HEAD
# This function allows the user to skip the two-factor authentication on-boarding
=======
"""
# This function allows the user to skip the two factor authentication on-boarding
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
# until the next time they log in.
@user.route('/skip_additional_security/<uuid:user_sid>', methods=['GET', 'POST'])
def skip_additional_security(user_sid):
    active_user = User.query.filter(User.sid == user_sid, User.is_deactivated.is_(False)).first()
    next_url = request.args.get('url')
    remember = request.args.get('remember', 'False')
    if remember == 'True':
        remember = True
    else:
        remember = False

    active_user.two_factor_auth_onboard = False
    active_user.two_factor_auth = False
    db.session.commit()
    flash(_('You have opted to skip the two step verification setup for now. We will ask you again next '
            'time you login.'), 'warning')
    # Has the user agreed to the terms and conditions
<<<<<<< HEAD
    if active_user.active and active_user.tos_agreement is False:
        return redirect(url_for('user.tos_get',
                                user_id=active_user.id,
                                url=next_url,
                                remember=remember))
=======
    #if active_user.active and active_user.tos_agreement is False:
    #    return redirect(url_for('user.tos_get',
    #                            user_id=active_user.id,
    #                            url=next_url,
    #                            remember=remember))
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
    # Login the user and redirect them to the appropriate page
    if active_user.active and login_user(active_user, remember=remember):
        ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_SUCCESS, request)
        active_user.update_activity_tracking(request.remote_addr)
        partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
        if not partnership:
            partnership = Partnership.query.get(1)

        if next_url:
            return redirect(safe_next_url(next_url))
        if active_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
            return redirect(url_for('admin.dashboard'))
        elif active_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
            return redirect(url_for('contacts.contact_list'))
        elif active_user.subscription.plan == 'partnershipsingle':
            return redirect(url_for('user.settings'))
        else:
            return redirect(url_for('dashboard.user_dashboard'))
    else:
        ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
        flash(_('This account has been disabled.'), 'danger')
        return redirect(url_for('user.login'))
"""


# This function will be called if two-factor authentication is enabled
# for the user. The user will need to enter a verification code
<<<<<<< HEAD
@user.route('/verification/<uuid:user_sid>', methods=['POST', 'GET'])
def two_factor_auth(user_sid):
    # Grab the next url if available as argument to send the user
    # to if they did 2-factor auth
    domain = request.host.replace('www', '')
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
    # Grab the next url if available as argument to send the user
    # to if they did 2 factor auth
    active_user = User.query.filter(User.sid == user_sid, User.is_deactivated.is_(False)).first()
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_name = primary_partner.name
    user_partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
    if user_partnership is not None:
        partner_name = user_partnership.name

    next_url = request.args.get('url')
    remember = request.args.get('remember')

    partnership = get_partnership()
    partnership_logo = partnership.alternative_logo
    if '::' in partnership_logo:
        bucket_name, key = partnership_logo.split("::")
        partnership_logo = generate_presigned_file_url(key, bucket_name)

    if remember == 'True':
        remember = True
    else:
        remember = False

    active_user = User.query.filter(User.sid == user_sid, User.is_deactivated.is_(False)).first()
    user_number = format_phone_number_bracket(active_user.phonenumber)
    log.info('the number is {}'.format(user_number))
    form = TwoFactorAuthForm()

    if form.validate_on_submit():

        # Compare the code sent to the user and the one saved in the session
        if request.form['code'] == session['verification_code']:
            ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.TWOFACTAUTH_SUCCESS, request)
            # Has the user agreed to the terms and conditions
            if active_user.active and active_user.tos_agreement is False:
                return redirect(url_for('user.tos_get',
                                        user_id=active_user.id,
                                        url=next_url,
                                        remember=remember))

            # Login the user and redirect them to the appropriate page
            if active_user.active and login_user(active_user, remember=remember):
                active_user.update_activity_tracking(request.remote_addr)
                partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
                if not partnership:
                    partnership = Partnership.query.get(1)

                # Handle optionally redirecting to the next URL safely.
                if next_url:
                    return redirect(safe_next_url(next_url))
                if current_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                    return redirect(url_for('admin.dashboard'))
                elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                    return redirect(url_for('contacts.contact_list'))
                elif current_user.subscription.plan == 'partnershipsingle':
                    return redirect(url_for('user.settings'))
                else:
                    return redirect(url_for('dashboard.user_dashboard'))
            else:
                flash(_('This account has been disabled.'), 'danger')
                return redirect(url_for('user.login'))
        else:
            ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.TWOFACTAUTH_FAILED, request)
            flash(_('You have entered an incorrect verification code. Please try again.'), 'danger')
            return redirect(url_for('user.two_factor_auth',
                                    user_sid=active_user.sid,
                                    url=next_url,
                                    remember=remember))

    else:
        log.error(f'Form error: {form.errors}')

    # Allow the user to resend the verification code if they didn't
    # receive it first time round
    if request.method == 'POST':
        if 'btn_resend_code' in request.form:
            if request.form['btn_resend_code'] == 'btn_resend_code':
                try:
                    send_verification_code(active_user.phonenumber)
                    flash(_('Code sent successfully.'), 'info')
                    log.info('The remember me value is {}'.format(remember))
                    return redirect(url_for('user.two_factor_auth',
                                            user_sid=active_user.sid,
                                            url=next_url,
                                            remember=remember))
                except Exception as e:
                    log.debug(
                        'There was a problem sending a verification code for user sid: {}'.format(active_user.sid))


    return render_template('user/two_factor_auth.jinja2',
                           partner_name=partner_name,
                           form=form,
                           user=active_user,
                           user_number=user_number,
                           next_url=next_url,
                           remember=remember,
                           partner_custom_styles=partner_custom_styles,
                           partner_url=partner_url,
                           partnership_logo=partnership_logo
                           )
=======
@user.route('/verification/<int:user_id>', methods=['POST', 'GET'])
def two_factor_auth(user_id):
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    if active_user and active_user.email.lower() == session.get('user_identify'):
        domain = request.host.replace('www', '')
        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_url = primary_partner.partner_url
        partner_custom_styles = primary_partner.custom_styles
        partners = Partnership.query.filter(Partnership.active.is_(True)).all()
        for partner in partners:
            if partner.partner_url and partner.id != 1:
                partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
                if partner_domain == domain:
                    partner_url = partner_domain
                    if partner.custom_styles:
                        partner_custom_styles = partner.custom_styles

        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_name = primary_partner.name
        user_partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
        if user_partnership is not None:
            partner_name = user_partnership.name
        next_url = request.args.get('url')
        remember = request.args.get('remember', 'False')

        if remember == 'True':
            remember = True
        else:
            remember = False

        user_number = format_phone_number_bracket(active_user.phonenumber)
        form = TwoFactorAuthForm()

        if form.validate_on_submit():
            # Compare the code sent to the user and the one saved in the session
            if request.form['code'] == session['verification_code']:
                ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.TWOFACTAUTH_SUCCESS, request)
                # Has the user agreed to the terms and conditions
                if active_user.active and active_user.tos_agreement is False:
                    return redirect(url_for('user.tos_get',
                                            user_id=active_user.id,
                                            url=next_url,
                                            remember=remember))

                # Login the user and redirect them to the appropriate page
                if active_user.active and login_user(active_user, remember=remember):
                    active_user.update_activity_tracking(request.remote_addr)
                    # Handle optionally redirecting to the next URL safely.
                    if next_url:
                        return redirect(safe_next_url(next_url))
                    if current_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                        return redirect(url_for('admin.dashboard'))
                    elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                        return redirect(url_for('contacts.contact_list'))
                    elif current_user.subscription.plan == 'partnershipsingle':
                        return redirect(url_for('user.settings'))
                    else:
                        return redirect(url_for('dashboard.user_dashboard'))
                else:
                    flash(_('This account has been disabled.'), 'danger')
                    return redirect(url_for('user.login'))
            else:
                ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.TWOFACTAUTH_FAILED, request)
                flash(_('You have entered an incorrect verification code. Please try again.'), 'danger')
                return redirect(url_for('user.two_factor_auth',
                                        user_id=active_user.id,
                                        url=next_url,
                                        remember=remember))

        # Allow the user to resend the verification code if they didn't
        # receive it first time round
        if request.method == 'POST':
            if request.form['btn_resend_code'] == 'btn_resend_code':
                try:
                    send_verification_code(active_user)
                    log.info('The remember me value is {}'.format(remember))
                    return redirect(url_for('user.two_factor_auth',
                                            user_id=active_user.id,
                                            url=next_url,
                                            remember=remember))
                except Exception as e:
                    log.debug('There was a problem sending a verification code for user id: {}'.format(active_user.id))

        return render_template('user/two_factor_auth.jinja2',
                               partner_name=partner_name,
                               form=form,
                               user=active_user,
                               user_number=user_number,
                               next_url=next_url,
                               remember=remember,
                               partner_custom_styles=partner_custom_styles,
                               partner_url=partner_url,
                               partner_id=partner.id
                               )
    else:
        flash(_('We were unable to complete your actions. Please try again or contact support.'), 'danger')
        # Redirect the user back to log in due to failing session check
        return redirect(url_for('user.login'))
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b


@user.route('/tos/<int:user_id>', methods=['GET'])
def tos_get(user_id):
<<<<<<< HEAD
    domain = request.host.replace('www', '')
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_name = primary_partner.name
    user_partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
    if user_partnership is not None:
        partner_name = user_partnership.name

    if active_user:
=======
    print(session.get('user_identify'))
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    if active_user and active_user.email.lower() == session.get('user_identify'):
        domain = request.host.replace('www', '')
        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_url = primary_partner.partner_url
        partner_custom_styles = primary_partner.custom_styles
        partners = Partnership.query.filter(Partnership.active.is_(True)).all()
        for partner in partners:
            if partner.partner_url and partner.id != 1:
                partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
                if partner_domain == domain:
                    partner_url = partner_domain
                    if partner.custom_styles:
                        partner_custom_styles = partner.custom_styles
        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_name = primary_partner.name
        user_partnership = Partnership.query.filter(Partnership.id == active_user.partnership_id).first()
        if user_partnership is not None:
            partner_name = user_partnership.name

>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
        if active_user.is_deactivated is True:
            flash(_('This account has been disabled.'), 'danger')
            return redirect(url_for('user.login'))
        else:
            return render_template('user/tos.jinja2',
                                   partner_name=partner_name,
                                   user=active_user,
                                   partner_url=partner_url,
<<<<<<< HEAD
                                   partner_custom_styles=partner_custom_styles)
    else:
=======
                                   partner_custom_styles=partner_custom_styles,
                                   partner_id=partner.id)
    else:
        flash(_('We were unable to complete your TOS action. Please try again or contact support.'), 'danger')
        # Redirect the user back to log in due to failing session check
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
        return redirect(url_for('user.login'))


@user.route('/tos_agree/<int:user_id>', methods=['POST'])
def tos_agree_post(user_id):
<<<<<<< HEAD
    next_url = request.args.get('url')
    remember = request.args.get('remember')
    if remember == 'True':
        remember = True
    else:
        remember = False
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()

    if active_user:
        active_user.tos_agreement = True
        ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_ACCEPTTERMS, request)
        db.session.commit()

=======
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
    if active_user and active_user.email.lower() == session.get('user_identify'):
        next_url = request.args.get('url')
        remember = request.args.get('remember', 'False')
        if remember == 'True':
            remember = True
        else:
            remember = False

        active_user.tos_agreement = True
        ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_ACCEPTTERMS, request)
        db.session.commit()
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
        # Login the user and redirect them to the appropriate page
        if active_user.active and login_user(active_user, remember=remember):
            active_user.update_activity_tracking(request.remote_addr)
            # Handle optionally redirecting to the next URL safely.
            if next_url:
<<<<<<< HEAD
                return redirect(safe_next_url(next_url))
            if current_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                return redirect(url_for('admin.dashboard'))
            elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                return redirect(url_for('contacts.contact_list'))
            elif current_user.subscription.plan == 'partnershipsingle':
                return redirect(url_for('user.settings'))
            else:
=======
                flash(_('Thank you for accepting our Terms of Service.'), 'success')
                return redirect(safe_next_url(next_url))
            if current_user.role in ['sysadmin', 'limitsysadmin', 'partner']:
                flash(_('Thank you for accepting our Terms of Service.'), 'success')
                return redirect(url_for('admin.dashboard'))
            elif current_user.role in ['agent'] and current_user.subscription.plan != 'partnershipsingle':
                flash(_('Thank you for accepting our Terms of Service.'), 'success')
                return redirect(url_for('contacts.contact_list'))
            elif current_user.subscription.plan == 'partnershipsingle':
                flash(_('Thank you for accepting our Terms of Service.'), 'success')
                return redirect(url_for('user.settings'))
            else:
                flash(_('Thank you for accepting our Terms of Service.'), 'success')
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
                return redirect(url_for('dashboard.user_dashboard'))
        else:
            flash(_('This account has been disabled.'), 'danger')
            ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_FAILED, request)
            return redirect(url_for('user.login'))
<<<<<<< HEAD

    return redirect(url_for('user.login'))
=======
    else:
        flash(_('We were unable to complete your TOS confirmation. Please try again or contact support.'), 'danger')
        # Redirect the user back to log in due to failing session check
        return redirect(url_for('user.login'))
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b


@user.route('/tos_disagree/<int:user_id>', methods=['POST'])
def tos_disagree_post(user_id):
    active_user = User.query.filter(User.id == user_id, User.is_deactivated.is_(False)).first()
<<<<<<< HEAD

    if active_user:
        active_user.tos_agreement = False
        ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_DECLINETERMS, request)
        db.session.commit()
        return redirect(url_for('user.login'))

    return redirect(url_for('user.login'))
=======
    if active_user and active_user.email.lower() == session.get('user_identify'):
        active_user.tos_agreement = False
        ActivityLogs.add_log(active_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGIN_DECLINETERMS, request)
        db.session.commit()
        flash(_('We require acceptance of our Terms of Service to continue. '
                'Please contact support if you have any questions.'), 'danger')
        return redirect(url_for('user.login'))
    else:
        flash(_('We were unable to complete your TOS declaration. Please try again or contact support.'), 'danger')
        return redirect(url_for('user.login'))
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b


@user.route('/logout')
@login_required
def logout():
    # logging out supervisor as well
    if current_supervisor_user.is_authenticated:
        supervisor_logout_user()

    ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGOUT, request)
    logout_user()
    flash(_('You have been logged out.'), 'success')
    return redirect(url_for('user.login'))


@user.route('/account/begin_password_reset', methods=['GET', 'POST'])
@anonymous_required()
def begin_password_reset():
    domain = request.host.replace('www', '')
    white_label = False
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_name = primary_partner.name
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                white_label = True
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
                partner_name = partner.name

    form = BeginPasswordResetForm()

    # Get partnership details by partner_url
    partnership = get_partnership()
    partnership_logo = partnership.alternative_logo
    if '::' in partnership_logo:
        bucket_name, key = partnership_logo.split("::")
        partnership_logo = generate_presigned_file_url(key, bucket_name)

    if form.validate_on_submit():
        user_email = request.form.get('identity')
        u = User.initialize_password_reset(user_email.lower())
        log.info('The user email requesting a password reset is: {}'.format(user_email.lower()))

        flash(_('An email has been sent to %(email)s.',
                email=u.email), 'success')
        return redirect(url_for('user.login'))

    return render_template('user/begin_password_reset.jinja2', form=form, partner_name=partner_name,
                           white_label=white_label, partner_url=partner_url,
<<<<<<< HEAD
                           partner_custom_styles=partner_custom_styles, partnership_logo=partnership_logo)

=======
                           partner_custom_styles=partner_custom_styles)
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b


@user.route('/account/password_reset', methods=['GET', 'POST'])
@anonymous_required()
def password_reset():
    domain = request.host.replace('www', '')
    white_label = False
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_name = primary_partner.name
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                white_label = True
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
                partner_name = partner.name

<<<<<<< HEAD
    form = PasswordResetForm(reset_token=request.args.get('reset_token'))

    # Get partnership details by partner_url
    partnership = get_partnership()
    partnership_logo = partnership.alternative_logo
    if '::' in partnership_logo:
        bucket_name, key = partnership_logo.split("::")
        partnership_logo = generate_presigned_file_url(key, bucket_name)

    if form.validate_on_submit():
        u = User.deserialize_token(request.form.get('reset_token'))
        if not u:
            flash(_('Your reset token has expired or was tampered with.'),
                  'danger')
            return redirect(url_for('user.begin_password_reset'))
        form.populate_obj(u)
        u.password = User.encrypt_password(request.form.get('password', None))
        u.save()

        # Send notification
        partnership = Partnership.query.filter(Partnership.id == u.partnership_id).first()
        if not partnership:
            partnership = Partnership.query.get(1)
        es_data = {
            'user_id': u.sid,
            'notify_message_type': 'PASSWORD_RESET',
            'user_related_entities': "You've",
            'other_user_related_entities': f'{u.firstname} {u.lastname}',
            'hyperlink': f'{partnership.partner_url}/settings'
        }
        response = send_notifications(**es_data)

        if login_user(u):
            flash(_('Your password has been reset.'), 'success')
            return redirect(url_for('user.settings'))

    return render_template('user/password_reset.jinja2', form=form, partnership=partnership, partnership_logo=partnership_logo)


@user.route('/account/password_reset_old', methods=['GET', 'POST'])
@anonymous_required()
def password_reset_old():
=======
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
    form = PasswordResetForm(reset_token=request.args.get('reset_token'))

    if form.validate_on_submit():
        u = User.deserialize_token(request.form.get('reset_token'))

        if u is None:
            flash(_('Your reset token has expired or was tampered with.'),
                  'danger')
            return redirect(url_for('user.begin_password_reset'))

        # start check old password is same as new password
        status = User.check_password_match(u.password, request.form.get('password', None))
        if status:
            ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.PASSWORDRESET_FAILED, request)
            flash(_('your password is same as old password, please try a new one.'), 'danger')
            # Construct the URL with the reset_token as a query parameter
            reset_url = url_for('user.password_reset') + f"?reset_token={request.form.get('reset_token')}"
            # Redirect to the reset URL
            return redirect(reset_url)
        # end check old password is same as new password

        form.populate_obj(u)
        u.password = User.encrypt_password(request.form.get('password', None))
        u.save()

        # save password updated date
        u.save_password_updated_date()

        ActivityLogs.add_log(u.id, ActivityType.AUTHORIZATION, ActivityName.PASSWORDRESET_SUCCESS, request)

        #redirect to login page
        flash(_('Your password has been reset.'), 'success')
        return redirect(url_for('user.login'))

    return render_template('user/password_reset.jinja2', form=form, white_label=white_label,
                           partner_name=partner_name, partner_url=partner_url,
                           partner_custom_styles=partner_custom_styles)


@user.route('/signup', methods=['GET', 'POST'])
@anonymous_required()
# TODO: review
def signup():
<<<<<<< HEAD
    try:
        current_app.config['RECAPTCHA_PUBLIC_KEY'] = current_app.config['RC_SITE_KEY']
        current_app.config['RECAPTCHA_PRIVATE_KEY'] = current_app.config['RC_SECRET_KEY']
=======
    domain = request.host.replace('www', '')
    white_label = False
    primary_partner = Partnership.query.filter(Partnership.id == 1).first()
    partner_name = primary_partner.name
    partner_url = primary_partner.partner_url
    partner_custom_styles = primary_partner.custom_styles
    partners = Partnership.query.filter(Partnership.active.is_(True)).all()
    for partner in partners:
        if partner.partner_url and partner.id != 1:
            partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
            if partner_domain == domain:
                partner_url = partner_domain
                white_label = True
                if partner.custom_styles:
                    partner_custom_styles = partner.custom_styles
                partner_name = partner.name
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b

        domain = request.host.replace('www', '')
        white_label = False
        primary_partner = Partnership.query.filter(Partnership.id == 1).first()
        partner_name = primary_partner.name
        partner_url = primary_partner.partner_url
        partner_custom_styles = primary_partner.custom_styles
        partners = Partnership.query.filter(Partnership.active.is_(True)).all()
        for partner in partners:
            if partner.partner_url and partner.id != 1:
                partner_domain = partner.partner_url.replace('https://', '').replace('www', '')
                if partner_domain == domain:
                    partner_url = partner_domain
                    white_label = True
                    if partner.custom_styles:
                        partner_custom_styles = partner.custom_styles
                    partner_name = partner.name


        form = SignupForm()

        partnership_token = request.args.get('partnership', None)
        account_token = request.args.get('account', None)
        partnership_ = None

<<<<<<< HEAD
        partnership = Partnership.query \
            .filter(Partnership.account_invitation_url_token == partnership_token) \
=======
    if not partnership:
        log.error('No partnership found. Most likely because no partnership token was provided.')
        return redirect(url_for('page.home'))

    if form.is_submitted():
        form_email = request.form.get('email').lower()
        u = User.query \
            .filter(func.lower(User.email) == form_email) \
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
            .first()

        if not partnership:
            log.error('No partnership found. Most likely because no partnership token was provided.')
            return redirect(url_for('page.home'))

        partnership_logo = partnership.alternative_logo
        if '::' in partnership_logo:
            bucket_name, key = partnership_logo.split("::")
            partnership_logo = generate_presigned_file_url(key, bucket_name)

        account = None
        if partnership_token:
            partnership_ = Partnership.get_by_invitation_token(partnership_token)
            if not partnership_:
                flash(_('Invalid partnership invitation url.'), 'danger')
                return render_template('user/signup.jinja2', form=form, partnership=partnership, partnership_logo=partnership_logo)
        if account_token:
            account = PartnershipAccount.get_by_invitation_token(account_token)
            if not account:
                flash(_('Invalid account invitation url.'), 'danger')
                return render_template('user/signup.jinja2', form=form, partnership=partnership, partnership_logo=partnership_logo)

        if form.validate_on_submit():
            form_email = request.form.get('email').lower()
            u = User.query \
                .filter(func.lower(User.email) == form_email) \
                .first()
            was_deactivated = False

<<<<<<< HEAD
            if u:
                if not u.is_deactivated:
                    form.email.errors = {'Already exists'}
                    return render_template('user/signup.jinja2', form=form, partnership=partnership, partnership_logo=partnership_logo)
                elif u.is_deactivated:
                    was_deactivated = True
                    u.is_deactivated = False
                    u.deactivated_on = None
                    db.session.commit()
=======
            if not u.is_deactivated:
                form.email.errors = {'Already exists'}
                return render_template('user/signup.jinja2', form=form, partnership=partnership)
            elif u.is_deactivated:
                was_deactivated = True
                u.is_deactivated = False
                u.deactivated_on = None
                db.session.commit()
        else:
            partnership_id = partnership.id
            u = User()
            account = PartnershipAccount()
            account.business_type = partnership.business_type
            account.name = u.email if not form.company else form.company.data
            account.partnership_id = partnership_id
            account.billing_type = partnership.default_billing_type
            if account.billing_type in ['invoice','partnership']:
                account.subscription_id = partnership.subscription_id
            db.session.add(account)
            db.session.commit()

            partnership_account_id = account.id

            form.populate_obj(u)
            u.password = User.encrypt_password(request.form.get('password', None))
            u.partnership_id = partnership_id
            u.email = request.form.get('email').lower()
            u.partnership_account_id = partnership_account_id
            u.role = 'admin'
            u.save()

            # save password updated date
            u.save_password_updated_date()

            agent = Agent(
                user_id=u.id,
                firstname=u.firstname,
                lastname=u.lastname,
                email=u.email,
                title=u.title or '',
                department=u.department or '',
                phonenumber=u.phonenumber,
                mobile='',
                extension=u.extension or None,
                partnership_account_id=partnership_account_id
            )
            widget = Widget(
                guid=str(uuid.uuid4()),
                partnership_account_id=partnership_account_id,
                name='Default',
                options=default
            )
            db.session.add(agent)
            db.session.add(widget)
            db.session.commit()

        if login_user(u):
            if was_deactivated:
                flash(_('Your account has been reactivated!'), 'success')
                return render_template('user/settings.jinja2')
            elif account.billing_type in ['invoice','partnership']:
                if current_user.role == 'partner':
                    return redirect(url_for('user.settings'))
                else:
                    return redirect(url_for('user.welcome'))
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
            else:
                u = User()
                form.populate_obj(u)
                u.password = User.encrypt_password(request.form.get('password', None))
                u.partnership_id = partnership.id
                u.email = request.form.get('email').lower()
                if partnership_:
                    u.role = 'partner'
                    u.partnership_account_id = 1
                elif account:
                    u.partnership_account_id = account.id
                    u.role = 'admin'
                u.save()

                # account = PartnershipAccount()
                # account.business_type = partnership.business_type
                # account.name = u.email if not form.company else form.company.data
                # account.partnership_id = partnership_id
                # account.billing_type = partnership.default_billing_type
                # if account.billing_type in ['invoice', 'partnership']:
                #     account.subscription_id = partnership.subscription_id
                # db.session.add(account)
                # db.session.commit()

                # Send notification
                # data = {
                #     'user_id': u.sid,
                #     'notify_message_type': 'ACCOUNT_CREATED',
                #     'user_related_entities': f'{u.email}',
                #     'other_user_related_entities': f'{u.email}',
                #     'hyperlink': f'{partnership.partner_url}/settings'
                # }
                # response = send_notifications(**data)

                agent = Agent(
                    user_id=u.id,
                    firstname=u.firstname,
                    lastname=u.lastname,
                    email=u.email,
                    title=u.title or '',
                    department=u.department or '',
                    phonenumber=u.phonenumber,
                    mobile='',
                    extension=u.extension or None,
                    partnership_account_id=u.partnership_account_id
                )
                # widget = Widget(
                #     guid=str(uuid.uuid4()),
                #     partnership_account_id=u.partnership_account_id,
                #     name='Default',
                #     options=default
                # )
                db.session.add(agent)
                # db.session.add(widget)
                db.session.commit()

                # Send notification
                data = {
                    'user_id': u.sid,
                    'notify_message_type': 'USER_CREATED',
                    'user_related_entities': f'{u.email}',
                    'other_user_related_entities': f'{u.email}',
                    'hyperlink': f'{partnership.partner_url}/settings'
                }
                response = send_notifications(**data)

            if login_user(u):
                if was_deactivated:
                    flash(_('Your account has been reactivated!'), 'success')
                    return render_template('user/settings.jinja2')
                # elif account.billing_type in ['invoice', 'partnership']:
                # if current_user.role == 'partner':
                return redirect(url_for('dashboard.user_dashboard'))
                # else:
                #     return redirect(url_for('dashboard.user_dashboard'))
                # # else:
                #     flash(_('Awesome, thanks for signing up!'), 'success')
                #     return redirect(url_for('billing.pricing'))

    except Exception as e:
        print('Error : ', e)
        white_label = None
        form = SignupForm()
    return render_template('user/signup.jinja2', form=form, partnership=partnership,
                           white_label=white_label, partner_name=partner_name,
                           partner_url=partner_url, partner_custom_styles=partner_custom_styles, partnership_logo=partnership_logo)

<<<<<<< HEAD
=======
    return render_template('user/signup.jinja2', form=form, partnership=partnership,
                           white_label=white_label, partner_name=partner_name,
                           partner_url=partner_url, partner_custom_styles=partner_custom_styles)
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b


@user.route('/welcome', methods=['GET', 'POST'])
@login_required
def welcome():
    agent = Agent.query \
        .filter(Agent.partnership_account_id == current_user.partnership_account_id).first()

    if agent:
        phonenumber = format_phone_number(current_user.phonenumber)

        flash(_("Great, you have signed up successfully!"), 'success')
        return render_template('user/welcome.jinja2', agent=agent, phonenumber=phonenumber)
    else:
        return render_template('user/settings.jinja2')


@user.route('/settings', methods=['GET', 'POST'])
@login_required
def settings():
<<<<<<< HEAD
    # Get partnership details by partner_url
    partnership = get_partnership()
    profile_form = PersonalInformationForm()
    security_info_form = SecurtyInformationForm()
    two_factor_auth_form = UpdateSecurityForm()
    theme_settings_form = ThemeSettingsForm()

    # Get languages from app configurations
    languages = current_app.config['LANGUAGES']

    # Get login information of user
    login_access_info = {'sign_in_count': current_user.sign_in_count,
                         'current_sign_in_on': current_user.current_sign_in_on,
                         'current_sign_in_ip': current_user.current_sign_in_ip,
                         'last_sign_in_on': current_user.last_sign_in_on,
                         'last_sign_in_ip': current_user.last_sign_in_ip
                         }

    partnership = Partnership.query.filter(Partnership.id == current_user.partnership_id).first()
    if not partnership:
        partnership = Partnership.query.get(1)

=======
>>>>>>> 2d4ba41568adf348959bbf7b64ffa061df87d07b
    if current_user.role in ['sysadmin', 'limitsysadmin']:
        return render_template('sysadmin/settings.jinja2')
    elif current_user.role == 'admin' and current_user.is_viewing_partnership:
        return redirect(url_for('dashboard.user_dashboard'))

    else:
        if not partnership.partner_url:
            partnership = Partnership.query.get(1)
    user = User.query.get(current_user.id)

    data = {
        'user_id': current_user.sid,
        'notify_message_type': 'PROFILE_SETTINGS_VIEWED',
        'user_related_entities': ["You've", 'your'],
        'other_user_related_entities': [f'{current_user.firstname} {current_user.lastname}', "his"],
        'hyperlink': f'{partnership.partner_url}/settings'
    }
    response = send_notifications(**data)

    try:
        if profile_form.btn_profile_form.data and profile_form.validate_on_submit():
            avatar = request.files['avatar']
            if avatar:
                from buyercall.lib.util_boto3_s3 import generate_presigned_file_url, upload_file_object
                avatar_ext = avatar.filename.split('.')[-1]
                if avatar_ext in ALLOWED_EXTENSIONS:
                    partnership = Partnership.query.get(current_user.partnership_id)

                    key = f'{partnership.name}_{partnership.sid}/avatar_{current_user.sid}.{avatar_ext}'
                    key = key.replace(' ', '_')
                    resp = upload_file_object(avatar, current_app.config['USER_AVATAR_BUCKET'], key)
                    user.user_avatar = f"{current_app.config['USER_AVATAR_BUCKET']}::{key}"
                    user.save()
                else:
                    flash(_('Unsupported image format for profile avatar'), 'warning')
                    return redirect(url_for('user.settings'))

            user.firstname = profile_form.first_name.data
            user.lastname = profile_form.last_name.data
            user.title = profile_form.job_title.data
            user.department = profile_form.department.data
            user.agent.timezone = profile_form.timezone.data
            user.locale = profile_form.locale.data
            user.save()

            flash(_('Successfully updated your personal informations'), 'success')
            return redirect(url_for('user.settings'))

        elif profile_form.btn_profile_form.data:
            flash(_(profile_form.errors), 'warning')
            return redirect(url_for('user.settings'))

        if security_info_form.validate_on_submit() and security_info_form.btn_security_info_form.data:
            user.email = security_info_form.email_address.data
            user.phonenumber = security_info_form.phone_number.data
            if security_info_form.password.data:
                user.password = User.encrypt_password(security_info_form.password.data)
            user.save()

            flash(_('Successfully updated your security informations'), 'success')
            return redirect(url_for('user.settings'))

        elif security_info_form.btn_security_info_form.data:
            flash(_(security_info_form.errors), 'warning')
            return redirect(url_for('user.settings'))

        if two_factor_auth_form.validate_on_submit() and two_factor_auth_form.btn_two_factor_auth_form.data:
            user.two_factor_auth = two_factor_auth_form.two_factor_auth.data
            user.save()
            flash(_('Successfully updated two factor authentication.'), 'success')
            return redirect(url_for('user.settings'))

        elif two_factor_auth_form.btn_two_factor_auth_form.data:
            flash(_(two_factor_auth_form.errors), 'warning')
            return redirect(url_for('user.settings'))

        if theme_settings_form.validate_on_submit() and theme_settings_form.btn_theme_settings_form.data:
            user.dark_mode = theme_settings_form.dark_mode.data
            user.save()
            flash(_('Successfully updated theme settings.'), 'success')
            return redirect(url_for('user.settings'))

        elif theme_settings_form.btn_theme_settings_form.data:
            flash(_(theme_settings_form.errors), 'warning')
            return redirect(url_for('user.settings'))

    except Exception as e:
        print("Exception : ", e)
        log.error(f"Error getting user settings. ")
    return render_template('user/settings.jinja2',
                           user=user,
                           partnership=partnership,
                           profile_form=profile_form,
                           security_info_form=security_info_form,
                           two_factor_auth_form=two_factor_auth_form,
                           theme_settings_form=theme_settings_form,
                           login_access_info=login_access_info,
                           languages=languages)


@user.route('/settings-old')
@login_required
def settings_old():
    if current_user.role == 'sysadmin':
        return render_template('sysadmin/settings_old.jinja2')
    elif current_user.role == 'admin' and current_user.is_viewing_partnership:
        return redirect(url_for('dashboard.user_dashboard_old'))
    else:
        return render_template('user/settings_old.jinja2')


@user.route('/settings/update_credentials', methods=['GET', 'POST'])
@login_required
def update_credentials():
    form = UpdateCredentials(current_user, uid=current_user.id)

    if form.validate_on_submit():
        # saving old password on to a variable
        old_password = current_user.password

        # We cannot form.populate_obj() because the password is optional.
        new_password = request.form.get('password', '')
        current_user.email = request.form.get('email')

        if new_password:
            current_user.password = User.encrypt_password(new_password)

        current_user.save()

        # start check password is same
        if old_password and new_password:
            status = User.check_password_match(old_password, new_password)
            if not status:
                current_user.save_password_updated_date()
        # end check password is same

        ActivityLogs.add_log(current_user.id, ActivityType.AUTHORIZATION, ActivityName.LOGOUT, request)
        logout_user()
        flash(_('Your sign in settings have been updated. Please log in again with your new credentials.'), 'success')
        return redirect(url_for('user.login'))

    return render_template('user/update_credentials.jinja2', form=form)


@user.route('/settings/update_personaldetails', methods=['GET', 'POST'])
@login_required
def update_personaldetails():
    form = UpdatePersonalDetails(current_user, uid=current_user.id)

    if form.validate_on_submit():
        form.populate_obj(current_user)
        current_user.save()

        flash(_('Your personal details have been updated.'), 'success')
        return redirect(url_for('user.settings'))

    return render_template('user/update_personaldetails.jinja2', form=form)


@user.route('/settings/update_locale', methods=['GET', 'POST'])
@login_required
def update_locale():
    form = UpdateLocale(locale=current_user.locale)

    if form.validate_on_submit():
        form.populate_obj(current_user)
        current_user.save()

        flash(_('Your locale settings have been updated.'), 'success')
        return redirect(url_for('user.settings'))

    return render_template('user/update_locale.jinja2', form=form)


@user.route('/settings/update_security', methods=['GET', 'POST'])
@login_required
def update_security():
    form = UpdateSecurity(two_factor_auth=current_user.two_factor_auth)

    crt_user = User.query.filter(User.id == current_user.id).first()
    if crt_user:
        crt_user_phone = format_phone_number_bracket(crt_user.phonenumber)
        crt_user_email = crt_user.email
        sms_label = 'SMS - ' + crt_user_phone
        email_label = 'Email - ' + crt_user_email
        # Generate choices based on boolean fields from the database
        choices = []
        if crt_user.role in ('admin', 'agent'):
            if crt_user.partnership.is_2fa_sms_enabled and crt_user.partnership_account.is_2fa_sms_enabled:
                choices.append(('field1', sms_label))
            if crt_user.partnership.is_2fa_email_enabled and crt_user.partnership_account.is_2fa_email_enabled:
                if crt_user.partnership.is_2fa_sms_enabled and crt_user.partnership_account.is_2fa_sms_enabled:
                    choices.append(('field2', email_label))
                else:
                    choices.append(('field1', email_label))
        elif crt_user.role == 'partner':
            if crt_user.partnership.is_2fa_sms_enabled:
                choices.append(('field1', sms_label))
            if crt_user.partnership.is_2fa_email_enabled:
                if crt_user.partnership.is_2fa_sms_enabled:
                    choices.append(('field2', email_label))
                else:
                    choices.append(('field1', email_label))

        elif crt_user.role in ('sysadmin', 'limitsysadmin'):
            choices.append(('field1', sms_label))
            choices.append(('field2', email_label))

        form.choice.choices = choices
        # Preselect the choice based on the database values
        if len(choices) > 1:
            if crt_user.is_2fa_sms:
                form.choice.data = 'field1'
            elif crt_user.is_2fa_email:
                form.choice.data = 'field2'

    if form.validate_on_submit():
        form.populate_obj(current_user)
        if current_user.partnership:
            if current_user.partnership.is_2fa_enforced:
                current_user.two_factor_auth = True
                current_user.two_factor_auth_onboard = True
        # Update the database record based on the selected option
        if form.auth_method.data == 'SMS':
            current_user.is_2fa_sms = True
            current_user.is_2fa_email = False
        elif form.auth_method.data == 'EMAIL':
            current_user.is_2fa_sms = False
            current_user.is_2fa_email = True
        current_user.save()

        flash(_('Your security settings have been updated.'), 'success')
        return redirect(url_for('user.settings'))

    return render_template('user/update_security.jinja2', form=form)


@user.route('/settings/rest_api', methods=['GET'])
@login_required
@role_required('admin', 'partner')
def rest_api_view():
    generated = False, ''

    if current_user.is_partnership_account_user:
        if current_user.partnership_account.api_token_hash:
            generated = True
    elif current_user.is_partnership_user:
        if current_user.partnership.api_token_hash:
            generated = True
    return render_template('user/rest_api.jinja2', generated=generated)


@user.route('/settings/rest_api', methods=['POST'])
@login_required
@role_required('admin', 'partner')
def rest_api_update():
    token = ''

    if current_user.is_partnership_account_user:

        partnership_account_id = current_user.partnership_account_id
        partnership_account_group_viewing = current_user.is_viewing_partnership

        # Check if being viewed by super partner
        if partnership_account_group_viewing:
            partnership_account_id = current_user.get_user_viewing_partnership_account_id

        token = current_user.partnership_account.regenerate_api_token(partnership_account_id)
    elif current_user.is_partnership_user:
        token = current_user.partnership.regenerate_api_token(current_user.partnership.id)

    return render_template(
        'user/rest_api.jinja2',
        generated=True,
        token=token
    )


@user.route('/user/switch_back', methods=['GET'])
# @role_required('admin', 'partner', 'sysadmin')
@login_required
@supervisor_login_required
def switch_back():
    target_user = copy.deepcopy(current_supervisor_user)
    u = current_user

    logout_user()
    login_user(target_user, remember=False, force=True)

    supervisor_logout_user()

    return redirect(url_for('user.settings'))


# Add Subdomain to the global request variable
@user.before_request
def before_request():
    """
    The URL that user visits is stored to a global variable partner_url in request_config
    This global variable can be accessed from anywhere in this user app
    Subdomains containing www is removed.
    Request protocol isn't stored because it will be either http or https
    The only things that affects identifying the partner are subdomain, domain and suffix(or tld)

    Possible formats:
        subdomain.domain.tld
        domain.tld
        subdomain.domain (To support sub.localhost)
        domain (To support localhost)

    """
    url = request.host_url
    extract = tldextract.extract(url)
    subdomain = extract.subdomain
    domain = extract.domain
    suffix = extract.suffix

    if subdomain[:4] == 'wwww.':  # Removing www from sites like www.subdomain.domain.tld
        subdomain = subdomain[4:]
    if subdomain == 'www':  # Removing www from sites like www.domain.tld
        subdomain = ''

    partner_url = ''

    if subdomain:
        partner_url = f'{subdomain}.'
    if suffix:
        partner_url += f'{domain}.{suffix}'
    else:
        partner_url += f'{domain}'

    g.request_config = {'partner_url': partner_url}


@user.route('/elasticsearch', methods=['GET'])
@login_required
def test_elasticsearch():
    try:
        a = []
        b = a[1]
    except Exception as e:
        pass
        # status = insert_error_data(request, es_client)
        # print(status)

        partnership = Partnership.query.get(current_user.partnership_id)
        if not partnership:
            partnership = Partnership.query.get(1)
        partnership_account = PartnershipAccount.query.get(current_user.partnership_account_id)
        if partnership_account:
            account_id = partnership_account.sid
        else:
            account_id = 'NO-PARTNERSHIP-ACCOUNT'
        params = {}
        for p in request.args:
            print(p)
        data = {
            'environment': 'DEVELOPMENT',
            'hostname': request.host,
            'ip': request.remote_addr,
            'created': datetime.now(tz=UTC),
            'method': request.method,
            'is_api': False,
            'params': {
                'key': 'name',
                'value': 'Jay'
            },
            'url': request.host_url,
            'status_code': 500,
            'status_code_root': 500,
            'error_detail': traceback.format_exc(),
            'user_id': current_user.sid,
            'partnership_id': partnership.sid,
            'account_id': account_id
        }
        # errorlog = insert_error_data(data=data, es_client=es_client)
    return


@user.route('/push')
@login_required
def test_notify():
    partnership = Partnership.query.get(current_user.partnership_id)
    if not partnership:
        partnership = Partnership.query.get(1)
    data = {
        'user_id': current_user.sid,
        'notify_message_type': 'DASHBOARD_VIEWED',
        'user_related_entities': ["You've"],
        'other_user_related_entities': [f'{current_user.firstname} {current_user.lastname}'],
        'hyperlink': 'http://localhost:8000/settings'
    }

    response = send_notifications(**data)

    # Send mail
    mail_subject = "You've a new notification"
    mail_data = render_template('user/mail/notification.jinja2', user=current_user,
                                config=current_app.config, logo=partnership.logo)
    recipients = 'namaste@ecosustain.in'

    # celery
    from buyercall.blueprints.user.tasks import send_notification_mail
    mail_status = send_notification_mail(mail_subject, mail_data, recipients)
    return response



@user.route('/user-management', methods=['GET'])
@login_required
@role_required('admin', 'partner')
def userManagement():
    
    return render_template('user/user_management.jinja2')