File: legacy_mfa.py

package info (click to toggle)
python-hvac 2.3.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,800 kB
  • sloc: python: 29,360; makefile: 42; sh: 14
file content (172 lines) | stat: -rw-r--r-- 6,552 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python
"""Legacy multi-factor authentication methods module."""
from hvac.api.vault_api_base import VaultApiBase
from hvac import exceptions, utils

SUPPORTED_MFA_TYPES = [
    "duo",
]
SUPPORTED_AUTH_METHODS = ["ldap", "okta", "radius", "userpass"]


class LegacyMfa(VaultApiBase):
    """Multi-factor authentication Auth Method (API).

    .. warning::
        This class's methods correspond to a legacy / unsupported set of Vault API routes. Please see the reference link
        for additional context.

    Reference: https://developer.hashicorp.com/vault/docs/v1.10.x/auth/mfa
    """

    def configure(self, mount_point, mfa_type="duo", force=False):
        """Configure MFA for a supported method.

        This endpoint allows you to turn on multi-factor authentication with a given backend.
        Currently only Duo is supported.

        Supported methods:
            POST: /auth/{mount_point}/mfa_config. Produces: 204 (empty body)

        :param mount_point: The "path" the method/backend was mounted on.
        :type mount_point: str | unicode
        :param mfa_type: Enables MFA with given backend (available: duo)
        :type mfa_type: str | unicode
        :param force: If `True`, make the `mfa_config` request regardless of circumstance. If `False` (the default), verify
            the provided `mount_point` is available and one of the types of methods supported by this feature.
        :type force: bool
        :return: The response of the configure MFA request.
        :rtype: requests.Response
        """
        if mfa_type != "duo" and not force:
            # The situation described via this exception is not likely to change in the future.
            # However we provided that flexibility here just in case.
            error_msg = 'Unsupported mfa_type argument provided "{arg}", supported types: "{mfa_types}"'
            raise exceptions.ParamValidationError(
                error_msg.format(
                    mfa_types=",".join(SUPPORTED_MFA_TYPES),
                    arg=mfa_type,
                )
            )
        params = {
            "type": mfa_type,
        }

        api_path = utils.format_url(
            "/v1/auth/{mount_point}/mfa_config", mount_point=mount_point
        )
        return self._adapter.post(
            url=api_path,
            json=params,
        )

    def read_configuration(self, mount_point):
        """Read the MFA configuration.

        Supported methods:
            GET: /auth/{mount_point}/mfa_config. Produces: 200 application/json


        :param mount_point: The "path" the method/backend was mounted on.
        :type mount_point: str | unicode
        :return: The JSON response of the read_configuration request.
        :rtype: dict
        """
        api_path = utils.format_url(
            "/v1/auth/{mount_point}/mfa_config",
            mount_point=mount_point,
        )
        return self._adapter.get(url=api_path)

    def configure_duo_access(self, mount_point, host, integration_key, secret_key):
        """Configure the access keys and host for Duo API connections.

        To authenticate users with Duo, the backend needs to know what host to connect to and must authenticate with an
        integration key and secret key. This endpoint is used to configure that information.

        Supported methods:
            POST: /auth/{mount_point}/duo/access. Produces: 204 (empty body)

        :param mount_point: The "path" the method/backend was mounted on.
        :type mount_point: str | unicode
        :param host: Duo API host
        :type host: str | unicode
        :param integration_key: Duo integration key
        :type integration_key: str | unicode
        :param secret_key: Duo secret key
        :type secret_key: str | unicode
        :return: The response of the `configure_duo_access` request.
        :rtype: requests.Response
        """
        params = {
            "host": host,
            "ikey": integration_key,
            "skey": secret_key,
        }
        api_path = utils.format_url(
            "/v1/auth/{mount_point}/duo/access",
            mount_point=mount_point,
        )
        return self._adapter.post(
            url=api_path,
            json=params,
        )

    def configure_duo_behavior(
        self, mount_point, push_info=None, user_agent=None, username_format="%s"
    ):
        """Configure Duo second factor behavior.

        This endpoint allows you to configure how the original auth method username maps to the Duo username by
        providing a template format string.

        Supported methods:
            POST: /auth/{mount_point}/duo/config. Produces: 204 (empty body)


        :param mount_point: The "path" the method/backend was mounted on.
        :type mount_point: str | unicode
        :param push_info: A string of URL-encoded key/value pairs that provides additional context about the
            authentication attempt in the Duo Mobile app
        :type push_info: str | unicode
        :param user_agent: User agent to connect to Duo (default is empty string `""`)
        :type user_agent: str | unicode
        :param username_format: Format string given auth method username as argument to create Duo username
            (default `%s`)
        :type username_format: str | unicode
        :return: The response of the `configure_duo_behavior` request.
        :rtype: requests.Response
        """
        params = {
            "username_format": username_format,
        }
        if push_info is not None:
            params["push_info"] = push_info
        if user_agent is not None:
            params["user_agent"] = user_agent
        api_path = utils.format_url(
            "/v1/auth/{mount_point}/duo/config",
            mount_point=mount_point,
        )
        return self._adapter.post(
            url=api_path,
            json=params,
        )

    def read_duo_behavior_configuration(self, mount_point):
        """Read the Duo second factor behavior configuration.

        Supported methods:
            GET: /auth/{mount_point}/duo/config. Produces: 200 application/json


        :param mount_point: The "path" the method/backend was mounted on.
        :type mount_point: str | unicode
        :return: The JSON response of the `read_duo_behavior_configuration` request.
        :rtype: dict
        """
        api_path = utils.format_url(
            "/v1/auth/{mount_point}/duo/config",
            mount_point=mount_point,
        )
        return self._adapter.get(url=api_path)