Sync Duo Users to Directory

This is a Python script for syncing individual Duo user into your Directory


Pre-Requisites:
  • Python Modules: pytz, colorama
  • Assuming you have already installed the Duo Admin API
  • The file my_duo_keys is where you have your Duo Admin API credentials. Check this article if you need help in how to obtain the integration keys: My Duo Keys for Admin API using Python.
  • The Directory Key which will be coming from Duo Admin Console

#IMPORTING MODULES
from __future__ import print_function
from __future__ import absolute_import
import datetime
from datetime import datetime, timedelta
import duo_client
from six.moves import input
import pytz
from pytz import timezone
from colorama import init
from colorama import Fore, Back, Style

#import Duo Admin API credentials
from my_duo_keys import *
admin_api = duo_client.Admin(ikey=DUO_IKEY, skey=DUO_SKEY, host=DUO_APIHOSTNAME)

init()
tz_PST = timezone('Asia/Singapore')
sa_time = datetime.now(tz_PST)
current_time = (sa_time.strftime('%Y-%m-%d %H:%M:%S') + " " + str(tz_PST))
print("")
print(Fore.WHITE + '----------------------------------------')
print(Fore.WHITE + "Sync Individual User from Azure to Duo")
print(Fore.WHITE + "Current Time: " + current_time)
print(Fore.WHITE + '----------------------------------------')
##Accept Input
username = input("Enter Username: ")
domain = "YOUR_DOMAIN"
logs = admin_api.get_users_by_name(username = username)
if not logs:
    #Check if user exists in Duo
    print(Fore.WHITE + '----------------------------------------')
    print(Fore.WHITE + 'Result: ' + Fore.RED + "User not found in Duo!!!")
    print(Fore.WHITE + "* Possible Reasons:")
    print(Fore.WHITE + "*** SSO Account is not yet created")
    print(Fore.WHITE + "*** User is not yet synced in AD/Azure")
    print(Fore.WHITE + "*** You are providing incorrect username")
    print(Fore.WHITE + '----------------------------------------')
else: 
    #Sync User
    print(Fore.WHITE + "Syncing user...")
    admin_api.sync_user(username = username + domain,directory_key ='YOUR_DIRECTORY_KEY',)
    logs = admin_api.get_users_by_name(username = username)
    print(Fore.WHITE + '----------------------------------------')

    if not logs:
        print(Fore.WHITE + 'Result: ' + Fore.RED + "User not found in Duo!!!")
        print(Fore.WHITE + "* Possible Reasons:")
        print(Fore.WHITE + "*** SSO Account is not yet created")
        print(Fore.WHITE + "*** User is not yet synced in AD/Azure")
        print(Fore.WHITE + "*** You are providing incorrect username")
        print(Fore.WHITE + '----------------------------------------')
        
    #Displaying Result
    for log in logs:
        print(Fore.WHITE + 'Result: ' + Fore.CYAN + 'User Synced Successfully!!!')
        print(Fore.WHITE + 'FullName: ' + Fore.CYAN + log['realname'])
        print(Fore.WHITE + 'User ID: '+ Fore.CYAN + log['user_id'])
        print(Fore.WHITE + 'Email Address: '+ Fore.CYAN + log['email'])
        if(log['status'] == "active" or log['status'] == "Active"): print(Fore.WHITE + 'Status: '+ Fore.CYAN + log['status'])
        else: 
            print(Fore.WHITE + 'Status: '+ Fore.RED + log['status'])
            print(Fore.RED + "* If user is still active, please check why user is disabled in AD.")
        print(Fore.WHITE + 'Enrolled: '+ Fore.CYAN + str(log['is_enrolled']))
        print(Fore.WHITE + 'Alias 1: '+ Fore.CYAN + str(log['alias1']))
        print(Fore.WHITE + 'Alias 2: '+ Fore.CYAN + str(log['alias2']))
        print(Fore.WHITE + 'Alias 3: '+ Fore.CYAN + str(log['alias3']))
        print(Fore.WHITE + 'Alias 4: '+ Fore.CYAN + str(log['alias4']))
        print(Fore.WHITE + '----------------------------------------')
        print(Fore.WHITE + 'Date Created (UTC): '+ Fore.CYAN +datetime.utcfromtimestamp(log['created']).strftime('%Y-%m-%d %H:%M:%S'))
        print(Fore.WHITE + 'Last Directory Sync (UTC): '+ Fore.CYAN +datetime.utcfromtimestamp(log['last_directory_sync']).strftime('%Y-%m-%d %H:%M:%S'))   
        print(Fore.WHITE + '----------------------------------------')
        for phone in log["phones"]:
            print(Fore.WHITE + 'Phone OS: '+ Fore.CYAN + phone['platform'])
            print(Fore.WHITE + 'Phone Model: '+ Fore.CYAN + phone['model'])
            print(Fore.WHITE + 'Phone Number: '+ Fore.CYAN + phone['number'])
            print(Fore.WHITE + 'ID: '+ Fore.CYAN + phone['phone_id'])
        print(Fore.WHITE + '----------------------------------------')
        print(Fore.WHITE + 'Group Membership:')
        if not log["groups"]: print(Fore.RED + "*** No Group Membership Found ***")
        for grp in log["groups"]:
            print(Fore.CYAN +grp['name'])      
        print(Fore.WHITE + '----------------------------------------')
        print(Fore.WHITE + 'Last Login: '+ Fore.CYAN +datetime.utcfromtimestamp(log['last_login']).strftime('%Y-%m-%d %H:%M:%S'))
        print(Fore.WHITE + '----------------------------------------')
        
   

 

Sample Output: The script will ask for the username first, then will extract the latest data for this user from Duo.


References for Python Modules

* Colorama
* PYZT