class_docstr: Duo base app integration. This is subclassed for the auth and admin APIs
class_docstr_tok: ["Duo","base","app","integration",".","This","is","subclassed","for","the","auth","and","admin","APIs"]
docstr: Get all logs from the endpoint for this timeframe
  
  Returns:
      [
          {
              'access_device': {
                  'browser': 'Chrome',
                  'browser_version': '1.2.3',
                  'flash_version': 'uninstalled',
                  'java_version': 'uninstalled',
                  'os': 'Mac OS X',
                  'os_version': '10.15.3',
                  'trusted_endpoint_status': 'unknown'
              },
              'alias': '',
              'device': '123-456-7890',
              'factor': 'Duo Push',
              'integration': 'web.site.com',
              'ip': '1.1.1.1',
              'location': {
                  'city': 'Portland',
                  'country': 'US',
                  'state': 'Oregon'
              },
              'new_enrollment': False,
              'reason': 'User approved',
              'result': 'SUCCESS',
              'timestamp': 1581705165,
              'username': 'user.name@site.com'
          }
      ]
docstr_tok: ["Get","all","logs","from","the","endpoint","for","this","timeframe","Returns",":","[","{","'access_device","'",":","{","'browser","'",":","'Chrome","'",",","'browser_version","'",":","'","1.2.3","'",",","'flash_version","'",":","'uninstalled","'",",","'java_version","'",":","'uninstalled","'",",","'os","'",":","'Mac","OS","X","'",",","'os_version","'",":","'10.15.3","'",",","'trusted_endpoint_status","'",":","'unknown'","}",",","'alias","'",":","``",",","'device","'",":","'123-456-7890","'",",","'factor","'",":","'Duo","Push","'",",","'integration","'",":","'web.site.com","'",",","'ip","'",":","'","1.1.1.1","'",",","'location","'",":","{","'city","'",":","'Portland","'",",","'country","'",":","'US","'",",","'state","'",":","'Oregon'","}",",","'new_enrollment","'",":","False",",","'reason","'",":","'User","approved","'",",","'result","'",":","'SUCCESS","'",",","'timestamp","'",":","1581705165",",","'username","'",":","'user.name","@","site.com'","}","]"]
code: def _get_duo_logs(self, hostname, full_url):
      """Get all logs from the endpoint for this timeframe
  
      Returns:
          [
              {
                  'access_device': {
                      'browser': 'Chrome',
                      'browser_version': '1.2.3',
                      'flash_version': 'uninstalled',
                      'java_version': 'uninstalled',
                      'os': 'Mac OS X',
                      'os_version': '10.15.3',
                      'trusted_endpoint_status': 'unknown'
                  },
                  'alias': '',
                  'device': '123-456-7890',
                  'factor': 'Duo Push',
                  'integration': 'web.site.com',
                  'ip': '1.1.1.1',
                  'location': {
                      'city': 'Portland',
                      'country': 'US',
                      'state': 'Oregon'
                  },
                  'new_enrollment': False,
                  'reason': 'User approved',
                  'result': 'SUCCESS',
                  'timestamp': 1581705165,
                  'username': 'user.name@site.com'
              }
          ]
      """
      # Get the last timestamp and add one to it to avoid duplicates
      # Sanity check mintime as unix timestamp, then transform to string
      params = {"mintime": str(int(self._last_timestamp + 1))}
  
      # Contstruct the headers for this request. Every request must be signed
      headers = self._generate_auth(hostname, params)
      if not headers:
          return False
  
      try:
          # Make the request to the api, resulting in a bool or dict
          result, response = self._make_get_request(
              full_url, headers=headers, params=params
          )
      except requests.exceptions.ConnectionError:
          LOGGER.exception("Received bad response from duo")
          return False
  
      if not result:
          return False
  
      # Duo stores the list of logs in the 'response' key of the response
      logs = response["response"]
      if not logs:
          LOGGER.info("No logs in response from duo")
          return False
  
      # Get the timestamp from the latest event. Duo produces these sequentially
      # so we can just extract the timestamp from the last item in the list
      self._last_timestamp = logs[-1]["timestamp"]
  
      # Check if the max amount of logs was returned with this request. If the value
      # is not the max, then we are done polling logs for this timeframe
      # Setting _more_to_poll to true here will allow the caller to try to poll again
      self._more_to_poll = len(logs) >= self._MAX_RESPONSE_LOGS
  
      # Return the list of logs to the caller so they can be send to the batcher
      return logs
  
imports: from base64 import b64encode
  from datetime import datetime
  import hashlib
  import hmac
  import re
  import urllib.request
  import urllib.parse
  import urllib.error
  import requests
  from .None import AppIntegration, StreamAlertApp, get_logger
label_desc: Use image node_id 5 for calling the DuoApp obj's underlying member method code with example usage: obj._get_duo_logs(hostname, full_url) and returns: logs, False, False, False, False