def delete_token(ikey, skey, host, token_id, ca=None): """ Deletes a token. If the token is already deleted, does nothing. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host token_id - Token ID ca - Optional CA cert Returns nothing on success. """ url = '/admin/v1/tokens/' + token_id client.call_json_api(ikey, skey, host, 'DELETE', url, ca)
def status(ikey, skey, host, txid, ca=None): """ Returns a 3-tuple: (complete, success, description) complete - True if the authentication request has completed, else False. success - True if the authentication request has completed and was a success, else False. description - A string describing the current status of the authentication request. """ path = "/rest/v1/status" response = client.call_json_api(ikey, skey, host, "GET", path, ca, sig_version=SIG_VERSION, txid=txid) complete = False success = False if "result" in response: complete = True success = response['result'] == 'allow' description = response['status'] return (complete, success, description)
def get_authentication_log(ikey, skey, host, ca=None, mintime=0): """ Returns authentication log events. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert mintime - Fetch events only >= mintime (to avoid duplicate records that have already been fetched) Returns: [ {'timestamp': <int:unix timestamp>, 'eventtype': "authentication", 'host': <str:host>, 'username': <str:username>, 'factor': <str:factor>, 'result': <str:result>, 'ip': <str:ip address>, 'integration': <str:integration>}, ... ] Raises RuntimeError on error. """ # Sanity check mintime as unix timestamp, then transform to string mintime = str(int(mintime)) response = client.call_json_api( ikey, skey, host, 'GET', '/admin/v1/logs/authentication.json', ca, mintime=mintime) for row in response: row['eventtype'] = "authentication" row['host'] = host return response
def update_admin(ikey, skey, host, admin_id, name=None, phone=None, password=None, ca=None): """ Create an administrator and adds it to a customer. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert admin_id - The id of the administrator. name - <str:the name of the administrator> (optional) phone - <str:phone number> (optional) password - <str:password> (optional) Returns the updated administrator. See the adminapi docs. Raises RuntimeError on error. """ url = '/admin/v1/admins/%s' % admin_id kwargs = {} if name is not None: kwargs['name'] = name if phone is not None: kwargs['phone'] = phone if password is not None: kwargs['password'] = password response = client.call_json_api( ikey, skey, host, 'POST', url, ca, **kwargs) return response
def add_admin(ikey, skey, host, name, email, phone, password, ca=None): """ Create an administrator and adds it to a customer. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert name - <str:the name of the administrator> email - <str:email address> phone - <str:phone number> password - <str:pasword> Returns the added administrator. See the adminapi docs. Raises RuntimeError on error. """ url = '/admin/v1/admins' kwargs = {} if name is not None: kwargs['name'] = name if email is not None: kwargs['email'] = email if phone is not None: kwargs['phone'] = phone if password is not None: kwargs['password'] = phone response = client.call_json_api( ikey, skey, host, 'POST', url, ca, **kwargs) return response
def delete_user(ikey, skey, host, user_id, ca=None): """ Deletes a user. If the user is already deleted, does nothing. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host user_id - User ID ca - Optional CA cert Returns nothing. Raises RuntimeError on error. """ url = '/admin/v1/users/' + user_id client.call_json_api(ikey, skey, host, 'DELETE', url, ca)
def delete_phone(ikey, skey, host, phone_id, ca=None): """ Deletes a phone. If the phone has already been deleted, does nothing. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host phone_id - Phone ID. ca - Optional CA cert Returns nothing. Raises RuntimeError on error. """ url = '/admin/v1/phones/' + phone_id client.call_json_api(ikey, skey, host, 'DELETE', url, ca)
def get_info_telephony_credits_used(ikey, skey, host, mintime=None, maxtime=None, ca=None): """ Returns number of telephony credits used during the time period. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert mintime - Limit report to data for events after this UNIX timestamp. Defaults to thirty days ago. maxtime - Limit report to data for events before this UNIX timestamp. Defaults to the current time. Raises RuntimeError on error. """ response = client.call_json_api( ikey, skey, host, 'GET', '/admin/v1/info/telephony_credits_used', ca, ) return response
def update_user(ikey, skey, host, user_id, username=None, realname=None, status=None, notes=None, ca=None): """ Update username, realname, status, or notes for a user. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host user_id - User ID username - Username (optional) realname - User's real name (optional) status - User's status, defaults to USER_STATUS_ACTIVE notes - Comment field (optional) ca - Optional CA cert Returns updated user object. Raises RuntimeError on error. """ url = '/admin/v1/users/' + user_id kwargs = {} if username is not None: kwargs['username'] = username if realname is not None: kwargs['realname'] = realname if status is not None: kwargs['status'] = status if notes is not None: kwargs['notes'] = notes response = client.call_json_api(ikey, skey, host, 'POST', url, ca, **kwargs) return response
def get_telephony_log(ikey, skey, host, ca=None, mintime=0): """ Returns telephony log events. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert mintime - Fetch events only >= mintime (to avoid duplicate records that have already been fetched) Returns: [ {'timestamp': <int:unix timestamp>, 'eventtype': "telephony", 'host': <str:host>, 'context': <str:context>, 'type': <str:type>, 'phone': <str:phone number>, 'credits': <str:credits>}, ... ] Raises RuntimeError on error. """ # Sanity check mintime as unix timestamp, then transform to string mintime = str(int(mintime)) response = client.call_json_api( ikey, skey, host, 'GET', '/admin/v1/logs/telephony.json', ca, mintime=mintime) for row in response: row['eventtype'] = "telephony" row['host'] = host return response
def reset_admin(ikey, skey, host, admin_id, ca=None): """ Resets the admin lockout. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert admin_id - <int:admin id> Returns None. Raises RuntimeError on error. """ url = '/admin/v1/admins/%s/reset' % admin_id client.call_json_api(ikey, skey, host, 'POST', url, ca)
def delete_admin(ikey, skey, host, admin_id, ca=None): """ Deletes an administrator. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert admin_id - The id of the administrator. Returns None. Raises RuntimeError on error. """ url = '/admin/v1/admins/%s' % admin_id client.call_json_api(ikey, skey, host, 'DELETE', url, ca)
def lookup_phone(ikey, skey, host, phone): """ Return the response for a phone lookup API call. """ response = client.call_json_api( ikey, skey, host, 'GET', '/verify/v1/lookup/phone.json', phone=[phone]) return response
def lookup_ip(ikey, skey, host, ip): """ Return the response for an IP lookup API call. """ response = client.call_json_api( ikey, skey, host, 'GET', '/verify/v1/lookup/ip.json', ip=[ip]) return response
def call(ikey, skey, host, phone): """ Return a (PIN, txid) tuple from the response for a call API call. """ response = client.call_json_api( ikey, skey, host, 'POST', '/verify/v1/call.json', phone=phone, message='The PIN is <pin>') return (response['pin'], response['txid'])
def status(ikey, skey, host, txid): """ Return the response for a status API call. """ response = client.call_json_api( ikey, skey, host, 'GET', '/verify/v1/status.json', txid=txid) return response
def ping(ikey, skey, host, ca=None): """ Returns True if and only if the Duo service is up and responding. """ path = "/rest/v1/ping" response = client.call_json_api(ikey, skey, host, 'GET', path, ca, sig_version=SIG_VERSION) return response == 'pong'
def sms(ikey, skey, host, phone): """ Return the PIN from the response for a SMS API call. """ response = client.call_json_api( ikey, skey, host, 'POST', '/verify/v1/sms.json', phone=[phone], message=['The PIN is <pin>']) return response['pin']
def check(ikey, skey, host, ca=None): """ Returns True if and only if the integration key, secret key, and signature generation are valid. """ path = "/rest/v1/check" response = client.call_json_api(ikey, skey, host, 'GET', path, ca, sig_version=SIG_VERSION) return response == 'valid'
def get_child_accounts(ikey, skey, host, ca=None): """ Return a list of all child accounts of the integration's account. """ response = client.call_json_api(ikey, skey, host, 'POST', '/accounts/v1/account/list', ca=ca) return response
def delete_integration(ikey, skey, host, integration_key, ca=None): """Deletes an integration. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert integration_key - The integration key of the integration to delete. Returns None. Raises RuntimeError on error. """ url = '/admin/v1/integrations/%s' % integration_key client.call_json_api(ikey, skey, host, 'DELETE', url, ca) return None
def create_account(ikey, skey, host, name, ca=None): """ Create a new child account of the integration's account. """ response = client.call_json_api(ikey, skey, host, 'POST', '/accounts/v1/account/create', name=name, ca=ca) return response
def delete_account(ikey, skey, host, account_id, ca=None): """ Delete a child account of the integration's account. """ response = client.call_json_api(ikey, skey, host, 'POST', '/accounts/v1/account/delete', account_id=account_id, ca=ca) return response
def preauth(ikey, skey, host, username, ca=None): path = "/rest/v1/preauth" response = client.call_json_api(ikey, skey, host, "POST", path, ca, sig_version=SIG_VERSION, user=username) return response
def status(ikey, skey, host, txid, ca=None): """ Return the response for a status API call. """ response = client.call_json_api( ikey, skey, host, 'GET', '/verify/v1/status.json', ca=ca, sig_version=SIG_VERSION, txid=txid) return response
def status(ikey, skey, host, txid): """ Return the response for a status API call. """ response = client.call_json_api(ikey, skey, host, 'GET', '/verify/v1/status.json', txid=[txid]) return response
def sms(ikey, skey, host, phone, ca=None): """ Return the PIN from the response for a SMS API call. """ response = client.call_json_api( ikey, skey, host, 'POST', '/verify/v1/sms.json', ca=ca, sig_version=SIG_VERSION, phone=phone, message='The PIN is <pin>') return response['pin']
def call(ikey, skey, host, phone): """ Return a (PIN, txid) tuple from the response for a call API call. """ response = client.call_json_api(ikey, skey, host, 'POST', '/verify/v1/call.json', phone=[phone], message=['The PIN is <pin>']) return (response['pin'], response['txid'])
def status(ikey, skey, host, txid, ca=None): """ Return the response for a status API call. """ response = client.call_json_api(ikey, skey, host, 'GET', '/verify/v1/status.json', ca=ca, sig_version=SIG_VERSION, txid=txid) return response
def resync_hotp_token(ikey, skey, host, token_id, code1, code2, code3, ca=None): """ Resync HOTP counter. The user must generate 3 consecutive OTP from their token and input them as code1, code2, and code3. This function will scan ahead in the OTP sequence to find a counter that resyncs with those 3 codes. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host token_id - Token ID code1 - First OTP from token code2 - Second OTP from token code3 - Third OTP from token ca - Optional CA cert Returns nothing on success. """ url = '/admin/v1/tokens/' + token_id + '/resync' kwargs = {'code1': code1, 'code2': code2, 'code3': code3} client.call_json_api(ikey, skey, host, 'POST', url, ca, **kwargs)
def sms(ikey, skey, host, phone, ca=None): """ Return the PIN from the response for a SMS API call. """ response = client.call_json_api(ikey, skey, host, 'POST', '/verify/v1/sms.json', ca=ca, sig_version=SIG_VERSION, phone=phone, message='The PIN is <pin>') return response['pin']
def get_tokens(ikey, skey, host, ca=None): """ Returns list of tokens. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert Returns list of token objects. """ response = client.call_json_api( ikey, skey, host, 'GET', '/admin/v1/tokens', ca) return response
def call(ikey, skey, host, phone, ca=None): """ Return a (PIN, txid) tuple from the response for a call API call. """ response = client.call_json_api(ikey, skey, host, 'POST', '/verify/v1/call.json', ca=ca, sig_version=SIG_VERSION, phone=phone, message='The PIN is <pin>') return (response['pin'], response['txid'])
def get_phones(ikey, skey, host, ca=None): """ Returns list of phones. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host ca - Optional CA cert Returns list of phone objects. Raises RuntimeError on error. """ response = client.call_json_api( ikey, skey, host, 'GET', '/admin/v1/phones', ca) return response
def get_token_by_id(ikey, skey, host, token_id, ca=None): """ Returns a token. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host token_id - Token ID ca - Optional CA cert Returns a token object. """ url = '/admin/v1/tokens/' + token_id response = client.call_json_api( ikey, skey, host, 'GET', url, ca) return response
def send_sms_activation_to_phone(ikey, skey, host, phone_id, valid_secs=None, install=None, installation_msg=None, activation_msg=None, ca=None): """ Generate a Duo Mobile activation code and send it to the phone via SMS, optionally sending an additional message with a URL to install Duo Mobile. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host phone_id - Phone ID. valid_secs - The number of seconds activation code should be valid for. Default: 86400 seconds (one day). install - '1' to also send an installation SMS message before the activation message; '0' to not send. Default: '0'. installation_msg - Custom installation message template to send to the user if install was 1. Must contain <insturl>, which is replaced with the installation URL. activation_msg - Custom activation message template. Must contain <acturl>, which is replaced with the activation URL. ca - Optional CA cert Returns: { "activation_msg": "To activate the Duo Mobile app, click this link: https://m-eval.duosecurity.com/iphone/7dmi4Oowz5g3J47FARLs", "installation_msg": "Welcome to Duo! To install the Duo Mobile app, click this link: http://m-eval.duosecurity.com", "valid_secs": 3600 } Raises RuntimeError on error. """ url = '/admin/v1/phones/' + phone_id + '/send_sms_activation' kwargs = {} if valid_secs is not None: kwargs['valid_secs'] = valid_secs if install is not None: kwargs['install'] = str(install) if installation_msg is not None: kwargs['installation_msg'] = installation_msg if activation_msg is not None: kwargs['activation_msg'] = activation_msg return client.call_json_api(ikey, skey, host, 'POST', url, ca, **kwargs)
def get_tokens_by_serial(ikey, skey, host, type, serial, ca=None): """ Returns a token. ikey - Admin API integration ikey skey - Admin API integration skey host - Duo host type - Token type, one of TOKEN_HOTP_6, TOKEN_HOTP_8, TOKEN_YUBIKEY serial - Token serial number ca - Optional CA cert Returns a list of 0 or 1 token objects. """ url = '/admin/v1/tokens' response = client.call_json_api( ikey, skey, host, 'GET', url, ca, type=type, serial=serial) return response