From d73c052933114060ae6f622f18833bde67b4abfc Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Mon, 28 Mar 2022 11:00:34 -0400 Subject: [PATCH 1/4] DX-2487 Overhaul Sample for New SDK --- .gitignore | 2 + LICENSE | 2 +- README.md | 63 ++++++++++++++++--------------- app.py | 95 ----------------------------------------------- icon-mfa.svg | 1 + main.py | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 128 deletions(-) create mode 100644 .gitignore delete mode 100644 app.py create mode 100644 icon-mfa.svg create mode 100644 main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b81a20 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/venv +__pycache__ \ No newline at end of file diff --git a/LICENSE b/LICENSE index df9461d..c85e706 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Bandwidth Samples +Copyright (c) 2022 Bandwidth Samples Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 634cbab..9e28e15 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,47 @@ -# 2FA CLI Python - - +# Multi-Factor Auth CLI + + + Multi-Factor Auth About Page + # Table of Contents - +* [Description](#description) +* [Pre-Requisites](#pre-requisites) +* [Running the Application](#running-the-application) +* [Environmental Variables](#environmental-variables) -- [2FA CLI Python](#2fa-cli-python) -- [Description](#description) -- [Bandwidth](#bandwidth) -- [Environmental Variables](#environmental-variables) -- [Development Environment Setup](#development-environment-setup) -- [Run The App](#run-the-app) +# Description - +This app allows you to enter your phone number in E164 format to receive a multi-factor auth code either by voice or sms. After entering your phone number and selecting the mfa method, you will receive a text message or phone call with your authentication code. Entering this code in the final prompt will allow you to verify the code. Note that you will need separate applications for voice and messaging depending on which method you would like to use. More information about the application setup can be found in the [Pre-Requisites](#pre-requisites) section. -# Description -A small CLI sample app that creates a 2FA code request, and a 2FA code validation request via Bandwidth's 2FA API +This app also demonstrates basic API Error handling. By entering an invalid code (e.g. 1), you will receive a `400 Bad Request` from the API, which is handled by the `except` statement at the end of the app. -# Bandwidth +# Pre-Requisites -In order to use the Bandwidth 2FA API, users need to have their applications setup. Please reach out to your account manager to set this up. +In order to use the Bandwidth API users need to set up the appropriate application at the [Bandwidth Dashboard](https://dashboard.bandwidth.com/) and create API tokens. -For more information about API credentials see [here](https://dev.bandwidth.com/guides/accountCredentials.html#top) +To create an application log into the [Bandwidth Dashboard](https://dashboard.bandwidth.com/) and navigate to the `Applications` tab. Fill out the **New Application** form selecting the service (Messaging or Voice) that the application will be used for. -# Environmental Variables -The sample app uses the below environmental variables. -```sh -BW_ACCOUNT_ID # Your Bandwidth Account Id -BW_USERNAME # Your Bandwidth API Token -BW_PASSWORD # Your Bandwidth API Secret -BW_NUMBER # Your The Bandwidth Phone Number -BW_VOICE_APPLICATION_ID # Your Voice Application Id created in the dashboard -BW_MESSAGING_APPLICATION_ID # Your Messaging Application Id created in the dashboard -``` +For more information about API credentials see our [Account Credentials](https://dev.bandwidth.com/docs/account/credentials) page. -# Development Environment Setup +# Running the Application -``` -pip install -r requirements.txt +Use the following command to run the application: + +```sh +python main.py ``` -# Run The App +# Environmental Variables -``` -python app.py +The sample app uses the below environmental variables. + +```sh +BW_ACCOUNT_ID # Your Bandwidth Account Id +BW_USERNAME # Your Bandwidth API Username +BW_PASSWORD # Your Bandwidth API Password +BW_NUMBER # The Bandwidth phone number involved with this application +BW_VOICE_APPLICATION_ID # Your Voice Application Id created in the dashboard +BW_MESSAGING_APPLICATION_ID # Your Messaging Application Id created in the dashboard ``` diff --git a/app.py b/app.py deleted file mode 100644 index 6df42e5..0000000 --- a/app.py +++ /dev/null @@ -1,95 +0,0 @@ -""" -app.py - -2FA CLI sample app using Bandwidth's 2FA API -""" -from bandwidth.bandwidth_client import BandwidthClient -from bandwidth.twofactorauth.models.two_factor_code_request_schema import TwoFactorCodeRequestSchema -from bandwidth.twofactorauth.models.two_factor_verify_request_schema import TwoFactorVerifyRequestSchema - -import os - -try: - BW_USERNAME = os.environ['BW_USERNAME'] - BW_PASSWORD = os.environ['BW_PASSWORD'] - BW_ACCOUNT_ID = os.environ['BW_ACCOUNT_ID'] - BW_NUMBER = os.environ['BW_NUMBER'] - BW_VOICE_APPLICATION_ID = os.environ['BW_VOICE_APPLICATION_ID'] - BW_MESSAGING_APPLICATION_ID = os.environ['BW_MESSAGING_APPLICATION_ID'] -except: - print("Please set the environmental variables defined in the README") - exit() - -bandwidth_client = BandwidthClient( - two_factor_auth_basic_auth_user_name=BW_USERNAME, - two_factor_auth_basic_auth_password=BW_PASSWORD -) -auth_client = bandwidth_client.two_factor_auth_client.mfa - -recipient_phone_number = input("Please enter your phone number in E164 format (+15554443333): ") -delivery_method = input("Select your method to receive your 2FA request. Please enter \"voice\" or \"messaging\": ") - -if delivery_method == "messaging": - from_phone = BW_NUMBER - to_phone = recipient_phone_number - application_id = BW_MESSAGING_APPLICATION_ID - scope = "scope" - digits = 6 - - body = TwoFactorCodeRequestSchema( - mfrom = from_phone, - to = to_phone, - application_id = application_id, - scope = scope, - digits = digits, - message = "Your temporary {NAME} {SCOPE} code is {CODE}" - ) - auth_client.create_messaging_two_factor(BW_ACCOUNT_ID, body) - - code = input("Please enter your received code: ") - - body = TwoFactorVerifyRequestSchema( - to = to_phone, - application_id = application_id, - scope = scope, - code = code, - expiration_time_in_minutes = 3 - ) - response = auth_client.create_verify_two_factor(BW_ACCOUNT_ID, body) - - if response.body.valid: - print("Success!") - else: - print("Failure") -else: - from_phone = BW_NUMBER - to_phone = recipient_phone_number - application_id = BW_VOICE_APPLICATION_ID - scope = "scope" - digits = 6 - - body = TwoFactorCodeRequestSchema( - mfrom = from_phone, - to = to_phone, - application_id = application_id, - scope = scope, - digits = digits, - message = "Your temporary {NAME} {SCOPE} code is {CODE}" - ) - auth_client.create_voice_two_factor(BW_ACCOUNT_ID, body) - - code = input("Please enter your received code: ") - - body = TwoFactorVerifyRequestSchema( - to = to_phone, - application_id = application_id, - scope = scope, - code = code, - expiration_time_in_minutes = 3 - ) - response = auth_client.create_verify_two_factor(BW_ACCOUNT_ID, body) - - if response.body.valid: - print("Success!") - else: - print("Failure") diff --git a/icon-mfa.svg b/icon-mfa.svg new file mode 100644 index 0000000..b0f823a --- /dev/null +++ b/icon-mfa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..9d5520d --- /dev/null +++ b/main.py @@ -0,0 +1,103 @@ +import os +import re + +# TODO: Needs to be changed when the SDK becomes python package. +import sys +sys.path.insert(0, 'C:/Users/ckoegel/Documents/sdks/bandwidth_python') +import bandwidth_python +from bandwidth_python.api.mfa_api import MFAApi +from bandwidth_python.model.two_factor_code_request_schema import TwoFactorCodeRequestSchema +from bandwidth_python.model.two_factor_verify_request_schema import TwoFactorVerifyRequestSchema +from bandwidth_python.exceptions import ApiException +# --------------------------------------------------- + + +BW_ACCOUNT_ID = os.environ.get('BW_ACCOUNT_ID') +BW_USERNAME = os.environ.get('BW_USERNAME') +BW_PASSWORD = os.environ.get('BW_PASSWORD') +BW_NUMBER = os.environ.get('BW_NUMBER') +BW_VOICE_APPLICATION_ID = os.environ.get('BW_VOICE_APPLICATION_ID') +BW_MESSAGING_APPLICATION_ID = os.environ.get('BW_MESSAGING_APPLICATION_ID') + + +configuration = bandwidth_python.Configuration( # TODO: # Configure HTTP basic authorization: httpBasic + username=BW_USERNAME, + password=BW_PASSWORD +) + + +api_client = bandwidth_python.ApiClient(configuration) # TODO: package name +mfa_api_instance = MFAApi(api_client) # TODO: package name + +recipient_phone_number = input("\nPlease enter your phone number in E164 format (+19195551234): ") +while True: + if re.match(r"^\+[1-9]\d{4,14}$", recipient_phone_number): + break + else: + recipient_phone_number = input("Invalid phone number. Please enter your phone number in E164 format (+19195551234): ") + + + +delivery_method = input("\nPlease select your MFA method.\nEnter 0 for voice or 1 for messaging: ") +while True: + if re.match(r"^[0-1]$", delivery_method): + break + else: + delivery_method = input("Invalid selection. Enter 0 for voice or 1 for messaging: ") + + +if bool(int(delivery_method)): + + body = TwoFactorCodeRequestSchema( + _from = BW_NUMBER, + to = recipient_phone_number, + application_id = BW_MESSAGING_APPLICATION_ID, + scope = "scope", + digits = 6.0, + message = "Your temporary {NAME} {SCOPE} code is {CODE}" + ) + mfa_api_instance.messaging_two_factor(BW_ACCOUNT_ID, body) + + code = input("\nPlease enter your received code: ") + + body = TwoFactorVerifyRequestSchema( + to = recipient_phone_number, + application_id = BW_MESSAGING_APPLICATION_ID, + scope = "scope", + code = code, + expiration_time_in_minutes = 3.0 + ) +else: + body = TwoFactorCodeRequestSchema( + _from = BW_NUMBER, + to = recipient_phone_number, + application_id = BW_VOICE_APPLICATION_ID, + scope = "scope", + digits = 6.0, + message = "Your temporary {NAME} {SCOPE} code is {CODE}" + ) + mfa_api_instance.voice_two_factor(BW_ACCOUNT_ID, body) + + code = input("\nPlease enter your received code: ") + + body = TwoFactorVerifyRequestSchema( + to = recipient_phone_number, + application_id = BW_VOICE_APPLICATION_ID, + scope = "scope", + code = code, + expiration_time_in_minutes = 3.0 + ) + +try: + response = mfa_api_instance.verify_two_factor(BW_ACCOUNT_ID, body) + + if response.valid: + print("Success!") + else: + print("Incorrect Code") + +except ApiException as e: + print(e) + + + \ No newline at end of file From 1dcc4f82d0a685875a23a40783f983efa8f8fb72 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Mon, 28 Mar 2022 11:06:16 -0400 Subject: [PATCH 2/4] svg --- icon-mfa.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icon-mfa.svg b/icon-mfa.svg index b0f823a..fca45c4 100644 --- a/icon-mfa.svg +++ b/icon-mfa.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 03821f34d681e7a7e596d91ac3582ba859fa22d6 Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Mon, 28 Mar 2022 11:27:01 -0400 Subject: [PATCH 3/4] eof --- main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.py b/main.py index 9d5520d..300a49e 100644 --- a/main.py +++ b/main.py @@ -98,6 +98,3 @@ except ApiException as e: print(e) - - - \ No newline at end of file From 696b76994db6c9e37777b6635d86f8af9a617d8c Mon Sep 17 00:00:00 2001 From: Cameron Koegel Date: Tue, 29 Mar 2022 11:30:35 -0400 Subject: [PATCH 4/4] requirements in readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 9e28e15..9662f9d 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,12 @@ For more information about API credentials see our [Account Credentials](https:/ # Running the Application +To install the required packages for this app, run the command: + +```sh +pip install -r requirements.txt +``` + Use the following command to run the application: ```sh