forked from Netflix/dispatch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creates a new plugin for Duo that provides on-demand MFA across Dispa…
…tch (Netflix#3035) * initial scaffolding for duo plugin * Create example for Slack plugin * Add duo requirement * remove index-url * remove new line * Apply black formatter * add docstring * Update src/dispatch/plugins/dispatch_duo/plugin.py * Change MFA plugin type to auth-mfa and remove example
- Loading branch information
1 parent
67ee226
commit 0443be6
Showing
10 changed files
with
138 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ bcrypt | |
cachetools | ||
chardet | ||
click | ||
duo-client | ||
email-validator | ||
emails | ||
fastapi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
""" | ||
.. module: dispatch.plugins.bases.mfa | ||
:platform: Unix | ||
:copyright: (c) 2023 by Netflix Inc., see AUTHORS for more | ||
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Will Sheldon <[email protected]> | ||
""" | ||
from dispatch.plugins.base import Plugin | ||
|
||
|
||
class MultiFactorAuthenticationPlugin(Plugin): | ||
type = "auth-mfa" | ||
|
||
def send_push_notification(self, items, **kwargs): | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from ._version import __version__ # noqa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = "0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from pydantic import Field, SecretStr | ||
from dispatch.config import BaseConfigurationModel | ||
|
||
|
||
class DuoConfiguration(BaseConfigurationModel): | ||
"""Duo configuration description.""" | ||
|
||
integration_key: SecretStr = Field( | ||
title="Integration Key", description="Admin API integration key ('DI...'):" | ||
) | ||
integration_secret_key: SecretStr = Field( | ||
title="Integration Secret Key", | ||
description="Secret token used in conjunction with integration key.", | ||
) | ||
host: str = Field( | ||
title="API Hostname", | ||
description="API hostname ('api-....duosecurity.com'): ", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
""" | ||
.. module: dispatch.plugins.dispatch_duo.plugin | ||
:platform: Unix | ||
:copyright: (c) 2023 by Netflix Inc., see AUTHORS for more | ||
:license: Apache, see LICENSE for more details. | ||
.. moduleauthor:: Will Sheldon <[email protected]> | ||
""" | ||
import logging | ||
from typing import NewType | ||
|
||
from dispatch.decorators import apply, counter, timer | ||
from dispatch.plugins.bases import MultiFactorAuthenticationPlugin | ||
from dispatch.plugins.dispatch_duo import service as duo_service | ||
from dispatch.plugins.dispatch_duo.config import DuoConfiguration | ||
from . import __version__ | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
DuoAuthResponse = NewType( | ||
"DuoAuthResponse", | ||
dict[ | ||
str, | ||
dict[str, str] | str, | ||
], | ||
) | ||
|
||
|
||
@apply(timer, exclude=["__init__"]) | ||
@apply(counter, exclude=["__init__"]) | ||
class DuoMfaPlugin(MultiFactorAuthenticationPlugin): | ||
title = "Duo Plugin - Multi Factor Authentication" | ||
slug = "duo-auth-mfa" | ||
description = "Uses Duo to validate user actions with multi-factor authentication." | ||
version = __version__ | ||
|
||
author = "Netflix" | ||
author_url = "https://github.com/netflix/dispatch.git" | ||
|
||
def __init__(self): | ||
self.configuration_schema = DuoConfiguration | ||
|
||
def send_push_notification( | ||
self, | ||
username: str, | ||
type: str, | ||
device: str = "auto", | ||
) -> DuoAuthResponse: | ||
"""Create a new push notification for authentication. | ||
This function sends a push notification to a Duo-enabled device for multi-factor authentication. | ||
Args: | ||
username (str): The unique identifier for the user, commonly specified by your application during user | ||
creation (e.g. [email protected]). This value may also represent a username alias assigned to a user (e.g. wshel). | ||
type (str): A string that is displayed in the Duo Mobile app push notification and UI. The notification text | ||
changes to "Verify request" and shows your customized string followed by a colon and the application's name, | ||
and the request details screen also shows your customized string and the application's name. | ||
device (str, optional): The ID of the device. This device must have the "push" capability. Defaults to "auto" | ||
to use the first of the user's devices with the "push" capability. | ||
Returns: | ||
DuoAuthResponse: The response from the Duo API. A successful response would appear as: | ||
{"response": {"result": "allow", "status": "allow", "status_msg": "Success. Logging you in..."}, "stat": "OK"} | ||
Example: | ||
>>> plugin = DuoMfaPlugin() | ||
>>> result = plugin.send_push_notification(username='[email protected]', type='Login Request') | ||
>>> result | ||
{'response': {'result': 'allow', 'status': 'allow', 'status_msg': 'Success. Logging you in...'}, 'stat': 'OK'} | ||
Notes: | ||
For more information, see https://duo.com/docs/authapi#/auth | ||
""" | ||
duo_client = duo_service.create_duo_auth_client(self.configuration) | ||
return duo_client.auth( | ||
factor="push", | ||
username=username, | ||
device=device, | ||
type=type, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import duo_client | ||
from duo_client.auth import Auth | ||
|
||
from dispatch.plugins.dispatch_duo.config import DuoConfiguration | ||
|
||
|
||
def create_duo_auth_client(config: DuoConfiguration) -> Auth: | ||
"""Creates a Duo Auth API client.""" | ||
return duo_client.Auth( | ||
ikey=config.integration_key.get_secret_value(), | ||
skey=config.integration_secret_key.get_secret_value(), | ||
host=config.host, | ||
) |