Skip to content

mfa

mfa

MFA_CRUD_Error

MFA_CRUD_Error(
    res: ResponseGetData, message: str | None = None
)

Bases: Config_CRUD_Error

Raised when MFA configuration update operations fail.

This exception is used for failures during MFA configuration changes, including enable/disable operations and policy updates.

Source code in src/crew_dcs/routes/instance_config/mfa.py
76
77
78
79
80
81
82
83
def __init__(
    self,
    res: rgd.ResponseGetData,
    message: str | None = None,
):
    super().__init__(
        res=res, message=message or "Failed to update MFA configuration"
    )

MFA_GET_Error

MFA_GET_Error(
    res: ResponseGetData,
    message: str | None = None,
    **kwargs
)

Bases: Config_GET_Error

Raised when MFA configuration retrieval operations fail.

This exception is used for failures during GET operations on MFA settings, including API errors and unexpected response formats.

Source code in src/crew_dcs/routes/instance_config/mfa.py
56
57
58
59
60
61
62
63
64
65
def __init__(
    self,
    res: rgd.ResponseGetData,
    message: str | None = None,
    **kwargs,
):
    if not message:
        message = "Failed to retrieve MFA configuration"

    super().__init__(message=message, res=res, **kwargs)

get_mfa_config async

get_mfa_config(
    auth: DomoAuth,
    incl_is_multifactor_required: bool = True,
    incl_num_days_valid: bool = True,
    incl_max_code_attempts: bool = True,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Retrieve MFA configuration settings for the Domo instance.

Fetches the current multi-factor authentication configuration including whether MFA is required, validity duration, and maximum code attempts.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing instance and credentials

required
incl_is_multifactor_required bool

Include MFA requirement status (default: True)

True
incl_num_days_valid bool

Include MFA validity duration in days (default: True)

True
incl_max_code_attempts bool

Include maximum invalid code attempts (default: True)

True
return_raw bool

Return raw API response without processing

False

Returns:

Type Description
ResponseGetData

ResponseGetData object containing MFA configuration with keys:

ResponseGetData
  • is_multifactor_required: Boolean indicating if MFA is enabled
ResponseGetData
  • num_days_valid: Integer days before MFA re-authentication required
ResponseGetData
  • max_code_attempts: Integer maximum invalid code attempts allowed

Raises:

Type Description
MFA_GET_Error

If MFA configuration retrieval fails

Example

config_response = await get_mfa_config(auth) config = config_response.response print(f"MFA Required: {config['is_multifactor_required']}") print(f"Valid for {config['num_days_valid']} days")

Source code in src/crew_dcs/routes/instance_config/mfa.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(
        entity_extractor=DomoEntityExtractor(),
        result_processor=DomoEntityResultProcessor(),
    ),
)
async def get_mfa_config(
    auth: DomoAuth,
    incl_is_multifactor_required: bool = True,
    incl_num_days_valid: bool = True,
    incl_max_code_attempts: bool = True,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """
    Retrieve MFA configuration settings for the Domo instance.

    Fetches the current multi-factor authentication configuration including
    whether MFA is required, validity duration, and maximum code attempts.

    Args:
        auth: Authentication object containing instance and credentials
        incl_is_multifactor_required: Include MFA requirement status (default: True)
        incl_num_days_valid: Include MFA validity duration in days (default: True)
        incl_max_code_attempts: Include maximum invalid code attempts (default: True)
        return_raw: Return raw API response without processing

    Returns:
        ResponseGetData object containing MFA configuration with keys:
        - is_multifactor_required: Boolean indicating if MFA is enabled
        - num_days_valid: Integer days before MFA re-authentication required
        - max_code_attempts: Integer maximum invalid code attempts allowed

    Raises:
        MFA_GET_Error: If MFA configuration retrieval fails

    Example:
        >>> config_response = await get_mfa_config(auth)
        >>> config = config_response.response
        >>> print(f"MFA Required: {config['is_multifactor_required']}")
        >>> print(f"Valid for {config['num_days_valid']} days")
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    params: dict[str, Any] = {"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",
        params=params,
        context=context,
    )

    if return_raw:
        return res

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

    new_obj = {
        obj["name"]: obj["value"] for obj in res.response if isinstance(obj, dict)
    }

    is_multifactor_required = new_obj.get("domo.policy.multifactor.required") == "yes"

    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

set_mfa_max_code_attempts async

set_mfa_max_code_attempts(
    auth: DomoAuth,
    max_code_attempts: int,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Set the maximum number of invalid MFA code attempts.

Configures the maximum number of invalid login attempts before the MFA code is reset and user must request a new code.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing instance and credentials

required
max_code_attempts int

Maximum invalid code attempts (must be greater than 0)

required
return_raw bool

Return raw API response without processing

False

Returns:

Type Description
ResponseGetData

ResponseGetData object with confirmation message

Raises:

Type Description
MFA_CRUD_Error

If max code attempts update fails, requires OTP elevation, or if max_code_attempts is not greater than 0

Example

response = await set_mfa_max_code_attempts(auth, 5) print(response.response)

Source code in src/crew_dcs/routes/instance_config/mfa.py
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(result_processor=ResponseGetDataProcessor()),
)
async def set_mfa_max_code_attempts(
    auth: DomoAuth,
    max_code_attempts: int,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """
    Set the maximum number of invalid MFA code attempts.

    Configures the maximum number of invalid login attempts before the MFA
    code is reset and user must request a new code.

    Args:
        auth: Authentication object containing instance and credentials
        max_code_attempts: Maximum invalid code attempts (must be greater than 0)
        return_raw: Return raw API response without processing

    Returns:
        ResponseGetData object with confirmation message

    Raises:
        MFA_CRUD_Error: If max code attempts update fails, requires OTP elevation,
                       or if max_code_attempts is not greater than 0

    Example:
        >>> response = await set_mfa_max_code_attempts(auth, 5)
        >>> print(response.response)
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    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_CRUD_Error(
            res=rgd.ResponseGetData(
                status=400,
                response="max_code_attempts must be greater than 0. Unable to set MFA max code attempts",
                is_success=False,
            ),
            message="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,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        if res.status == 403:
            raise MFA_CRUD_Error(
                res=res,
                message=f"MFA modification requires OTP elevation to update max code attempts in {auth.domo_instance}",
            )

        raise MFA_CRUD_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

set_mfa_num_days_valid async

set_mfa_num_days_valid(
    auth: DomoAuth,
    num_days_valid: int,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Set the number of days before MFA re-authentication is required.

Configures the validity duration for MFA tokens. After this many days, users must complete MFA authentication again.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing instance and credentials

required
num_days_valid int

Number of days before MFA expires (must be greater than 0)

required
return_raw bool

Return raw API response without processing

False

Returns:

Type Description
ResponseGetData

ResponseGetData object with confirmation message

Raises:

Type Description
MFA_CRUD_Error

If MFA validity duration update fails or if num_days_valid is not greater than 0

Example

response = await set_mfa_num_days_valid(auth, 30) print(response.response) # "num days MFA valid set to 30 in..."

Source code in src/crew_dcs/routes/instance_config/mfa.py
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(result_processor=ResponseGetDataProcessor()),
)
async def set_mfa_num_days_valid(
    auth: DomoAuth,
    num_days_valid: int,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """
    Set the number of days before MFA re-authentication is required.

    Configures the validity duration for MFA tokens. After this many days,
    users must complete MFA authentication again.

    Args:
        auth: Authentication object containing instance and credentials
        num_days_valid: Number of days before MFA expires (must be greater than 0)
        return_raw: Return raw API response without processing

    Returns:
        ResponseGetData object with confirmation message

    Raises:
        MFA_CRUD_Error: If MFA validity duration update fails or if
                       num_days_valid is not greater than 0

    Example:
        >>> response = await set_mfa_num_days_valid(auth, 30)
        >>> print(response.response)  # "num days MFA valid set to 30 in..."
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    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_CRUD_Error(
            res=rgd.ResponseGetData(
                status=400,
                response="num_days_valid must be greater than 0. Unable to set days before MFA expires",
                is_success=False,
            ),
            message="num_days_valid 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,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        raise MFA_CRUD_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

toggle_enable_mfa async

toggle_enable_mfa(
    auth: DomoAuth,
    is_enable_MFA: bool = False,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs
) -> ResponseGetData

Enable or disable MFA requirement for the Domo instance.

Toggles the multi-factor authentication requirement policy for all users in the instance. When enabled, users must complete MFA to access Domo.

Parameters:

Name Type Description Default
auth DomoAuth

Authentication object containing instance and credentials

required
is_enable_MFA bool

True to enable MFA, False to disable (default: False)

False
return_raw bool

Return raw API response without processing

False

Returns:

Type Description
ResponseGetData

ResponseGetData object with confirmation message

Raises:

Type Description
MFA_CRUD_Error

If MFA toggle operation fails or requires OTP elevation

Example

response = await toggle_enable_mfa(auth, is_enable_MFA=True) print(response.response) # "toggled MFA on"

Source code in src/crew_dcs/routes/instance_config/mfa.py
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
@gd.route_function
@log_call(
    level_name="route",
    config=LogDecoratorConfig(result_processor=ResponseGetDataProcessor()),
)
async def toggle_enable_mfa(
    auth: DomoAuth,
    is_enable_MFA: bool = False,
    return_raw: bool = False,
    *,
    context: RouteContext | None = None,
    **context_kwargs,
) -> rgd.ResponseGetData:
    """
    Enable or disable MFA requirement for the Domo instance.

    Toggles the multi-factor authentication requirement policy for all users
    in the instance. When enabled, users must complete MFA to access Domo.

    Args:
        auth: Authentication object containing instance and credentials
        is_enable_MFA: True to enable MFA, False to disable (default: False)
        return_raw: Return raw API response without processing

    Returns:
        ResponseGetData object with confirmation message

    Raises:
        MFA_CRUD_Error: If MFA toggle operation fails or requires OTP elevation

    Example:
        >>> response = await toggle_enable_mfa(auth, is_enable_MFA=True)
        >>> print(response.response)  # "toggled MFA on"
    """
    context = RouteContext.build_context(context=context, **context_kwargs)

    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,
        context=context,
    )

    if return_raw:
        return res

    if not res.is_success:
        if res.status == 403:
            raise MFA_CRUD_Error(
                res=res,
                message="MFA toggle requires OTP elevation",
            )
        raise MFA_CRUD_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