# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/routes/instance_config_mfa.ipynb.

# %% auto 0
__all__ = ['MFA_UPDATE_Error', 'MFA_UPDATE_Value_Error', 'toggle_enable_mfa', 'MFA_GET_Error', 'get_mfa_config',
           'set_mfa_max_code_attempts', 'set_mfa_num_days_valid']

# %% ../../nbs/routes/instance_config_mfa.ipynb 2
import httpx

import domolibrary.client.get_data as gd
import domolibrary.client.ResponseGetData as rgd
import domolibrary.client.DomoAuth as dmda
import domolibrary.client.DomoError as dmde

# %% ../../nbs/routes/instance_config_mfa.ipynb 7
class MFA_UPDATE_Error(dmde.DomoError):
    def __init__(
        self,
        res: rgd.ResponseGetData,
        message=None,
    ):

        super().__init__(
            domo_instance=res.auth.domo_instance,
            function_name=res.traceback_details.function_name,
            status=res.status,
            message=message or res.response,
        )


class MFA_UPDATE_Value_Error(dmde.DomoError):
    
    def __init__(
        self,
        message,
    ):

        super().__init__(
            message=message,
        )


@gd.route_function
async def toggle_enable_mfa(
    auth: dmda.DomoAuth,
    is_enable_MFA: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    parent_class: str = None,
    debug_num_stacks_to_drop: int = 1,
) -> rgd.ResponseGetData:

    url = f"https://{auth.domo_instance}.domo.com/api/content/v1/customer-states/domo.policy.multifactor.required"

    payload = {
        "name": "domo.policy.multifactor.required",
        "value": "yes" if is_enable_MFA else "no",
    }

    res = await gd.get_data(
        auth=auth,
        url=url,
        method="PUT",
        body=payload,
        debug_api=debug_api,
        session=session,
        parent_class=parent_class,
        num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    if not res.is_success:
        if res.status == 403:
            raise MFA_UPDATE_Value_Error(
                message=f"this endpoint requires OTP elevation."
            )
        raise MFA_UPDATE_Error(
            res=res,
            message=f"failed to toggle MFA in {auth.domo_instance}",
        )

    res.response = f'toggled MFA {"on" if is_enable_MFA else "off"}'

    return res

# %% ../../nbs/routes/instance_config_mfa.ipynb 10
class MFA_GET_Error(dmde.DomoError):
    def __init__(
        self,
        res : rgd.ResponseGetData,
        message = None,
    ):

        super().__init__(
            domo_instance=res.auth.domo_instance,
            function_name=res.traceback_details.function_name,
            status=res.status,
            message=message or res.response,
        )
        
@gd.route_function
async def get_mfa_config(
    auth: dmda.DomoAuth,
    
    incl_is_multifactor_required: bool = True,
    incl_num_days_valid: bool = True, # how long MFA is valid
    incl_max_code_attempts: bool = True,
    
    session: httpx.AsyncClient = None,
    parent_class: str = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 1,

    return_raw: bool = False

) -> rgd.ResponseGetData:

    params = {"ignoreCache" :True}
    
    state_ls = []

    if incl_is_multifactor_required:
        state_ls.append('domo.policy.multifactor.required')

    if incl_num_days_valid:
        state_ls.append('domo.policy.multifactor.factorExpires')
    
    
    if incl_max_code_attempts:
        state_ls.append('domo.policy.multifactor.maxCodeAttempts')
    
    params.update({'stateName' : ",".join(state_ls)})
        
    url = f'https://{auth.domo_instance}.domo.com/api/content/v1/customer-states'
    
    res = await gd.get_data(
        auth=auth,
        url=url,
        method="GET",
        debug_api=debug_api,
        session=session,
        parent_class=parent_class,
        num_stacks_to_drop=debug_num_stacks_to_drop,
        params = params
    )

    if return_raw:
        return res
    
    if not res.is_success:
        raise MFA_GET_Error(
            res=res,
            message=f"failed to retrieve {auth.domo_instance} MFA configuration settings",
        )
    

    new_obj = {obj['name'] : obj['value']   for obj in res.response}

    is_multifactor_required = True if new_obj.get('domo.policy.multifactor.required') == 'yes' else False
    
    num_days_valid = new_obj.get('domo.policy.multifactor.factorExpires')
    if num_days_valid and num_days_valid.isdigit():
        num_days_valid = int(num_days_valid) 

    
    max_code_attempts=new_obj.get('domo.policy.multifactor.maxCodeAttempts')
    if max_code_attempts and max_code_attempts.isdigit():
        max_code_attempts = int(max_code_attempts)

    res.response = {
        "is_multifactor_required" : is_multifactor_required,
        "num_days_valid" : num_days_valid, 
        "max_code_attempts" : max_code_attempts
    }

    return res


# %% ../../nbs/routes/instance_config_mfa.ipynb 15
@gd.route_function
async def set_mfa_max_code_attempts(
    auth: dmda.DomoAuth,
    max_code_attempts: int, 
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    parent_class: str = None,
    debug_num_stacks_to_drop: int = 1
) -> rgd.ResponseGetData:
    
    '''Sets the max number of invalid log in attempts before the MFA code is reset'''
    
    url = f'https://{auth.domo_instance}.domo.com/api/content/v1/customer-states/domo.policy.multifactor.maxCodeAttempts'
    
    if not max_code_attempts > 0:
        raise MFA_UPDATE_Value_Error(
            message="max max_code_attempts must be greater than 0. unable to set MFA max code attempts",
        )
        
    payload = {'name': "domo.policy.multifactor.maxCodeAttempts", 'value': max_code_attempts}
    
    res = await gd.get_data(
        auth=auth,
        url=url,
        method="PUT",
        body=payload,
        debug_api=debug_api,
        session=session,
        parent_class=parent_class,
        num_stacks_to_drop=debug_num_stacks_to_drop
    )
    
    if not res.is_success:
        if res.status == 403:
                raise MFA_UPDATE_Error(
            res=res,
            message=f"MFA modification requires OTP elevation to update max code attempts in {auth.domo_instance}",
        )

        raise MFA_UPDATE_Error(
            res=res,
            message=f"failed to update max number of code attempts for MFA in {auth.domo_instance}",
        )

    res.response = f"set max number of code attempts to {max_code_attempts} in {auth.domo_instance}"

    return res

# %% ../../nbs/routes/instance_config_mfa.ipynb 18
@gd.route_function
async def set_mfa_num_days_valid(
    auth: dmda.DomoAuth,
    num_days_valid: int, 
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    parent_class: str = None,
    debug_num_stacks_to_drop: int = 1
) -> rgd.ResponseGetData:
    '''Sets the number of days before the user must re-authenticate'''
    
    url = f'https://{auth.domo_instance}.domo.com/api/content/v1/customer-states/domo.policy.multifactor.factorExpires'
    
    if not num_days_valid > 0:
        raise MFA_UPDATE_Value_Error(
            message="max num_days must be greater than 0. unable to set days before MFA expires",
        )
        
    payload = {'name': "domo.policy.multifactor.factorExpires", 'value': num_days_valid}
    
    res = await gd.get_data(
        auth=auth,
        url=url,
        method="PUT",
        body=payload,
        debug_api=debug_api,
        session=session,
        parent_class=parent_class,
        num_stacks_to_drop=debug_num_stacks_to_drop
    )
    
    if not res.is_success:
        raise MFA_UPDATE_Error(
            res=res,
            message=f"failed to set number of days before MFA expires in {auth.domo_instance}",
        )

    res.response = f"num days MFA valid set to {num_days_valid} in {auth.domo_instance}"

    return res
