Anyone know how to find who is using AppPasswords vs TOTP?
Question asked by rick - 8/26/2026 at 7:13 PM
Answered
Any possible way to find who is using AppPassword so we can notify users in advance of coming update?
J. LaDow Replied
On the version we're on, the "USER STATUSES" item on the left menu brings up a list of all users in the system, and on ours, there is a column that at least denotes 2FA is enabled.

Then, when viewing accounts under a domain, we see users noted with a [2] next to their name shows 2FA enabled like so:
MailEnable survivor / convert --
Tony Scholz Replied
Employee Post Marked As Answer
You can use the API to accomplish this as well.
- Authenticate to the server (api/v1/auth/authenticate-user)
- List all domains (api/v1/settings/sysadmin/domains)
- List all domain admins (api/v1/settings/sysadmin/domain-admins/{domain})
- Impersonate the domain admins (api/v1/settings/domain/impersonate-user/)
- Grab a list of users (api/v1/settings/domain/account-search-quick)

This last call can be sorted by (authType == 3) to find those that are using 2FA/MFA

Example: 

#!/usr/local/bin/python3

import requests

SM_HOST = "http://localhost:17017/"
SM_USER = "admin"
SM_PASS = "admin"

def authenticate():
  authUri = f"{SM_HOST}api/v1/auth/authenticate-user"
  auth_obj = {
      'username': SM_USER, 
      'password': SM_PASS,
  }
  headers = {'Content-Type': 'application/json'}
  authresponse = requests.post(authUri, json=auth_obj, headers=headers, verify=True)
  authresponse.raise_for_status()
  headers['Authorization'] = f"Bearer {authresponse.json()['accessToken']}"
  return headers

def get_all_domains_and_admins(headers):
  domain_admins = dict()
  domains = requests.get(url=f"{SM_HOST}api/v1/settings/sysadmin/domains", headers=headers)
  domain_names = [ n['name'] for n in domains.json()['data'] ]
  for domain in domain_names:
    dAdmins = requests.get(url=f"{SM_HOST}api/v1/settings/sysadmin/domain-admins/{domain}", headers=headers)
    #print(dAdmins.json()['domainAdmins'][0])
    domain_admins[domain] = dAdmins.json()['domainAdmins'][0]
  return domain_admins


def impersonate_user(user_email, headers):
  uri = f"{SM_HOST}api/v1/settings/domain/impersonate-user/"
  payload = {"email": user_email}
  response = requests.post(uri, headers=headers, json=payload)
  response.raise_for_status()
  impersonation_headers = {'Content-Type': 'application/json'}
  impersonation_headers['Authorization'] = f"Bearer {response.json()['impersonateAccessToken']}"
  return impersonation_headers

def search_domain_for_auth_type(headers, auth_type: int = 3): 
  endpoint = "api/v1/settings/domain/account-search-quick"
  payload = {
      "searchFlags": [
          "users"
      ]
  }
  users_response = requests.post(url=f"{SM_HOST}{endpoint}", json=payload, headers=headers)
  users_response.raise_for_status()
  MFA_users = [u['userName'] for u in users_response.json()['users'] if u['authType'] == auth_type ]
  return MFA_users


def main(): 
  headers = authenticate()
  domain_admins = get_all_domains_and_admins(headers)
  matching_users = dict()

  results = dict()
  for domains in domain_admins.items():
    domain = domains[0]
    #print(f"d = {domain}")
    user = domains[1]
    #print(f"u = {user}")
    impersonation = impersonate_user(user_email=user, headers=headers)
    users = search_domain_for_auth_type(headers=impersonation, auth_type=3)
    #print(users)
    results[domain] = users

  print(results)

if __name__ == "__main__":
  main()
Tony Scholz
Lead Network/System Administrator
SmarterTools Inc.

Reply to Thread

Enter the verification text