def main(): logging.basicConfig(level=logging.DEBUG) ngrok = ngrokhelper.NgrokHelper(port=5000) bot_url = ngrok.start() logging.debug(f'Bot url: {bot_url}') # Create a new bot bot = TeamsBot(bot_app_name, teams_bot_token=teams_token, teams_bot_url=bot_url, teams_bot_email=bot_email, debug=True) # Spark API api = webexteamssdk.WebexTeamsAPI(teams_token) # Add new command bot.add_command('/chuck', 'get Chuck Norris joke', get_joke) bot.add_command('/traffic', 'show traffic cams', functools.partial(traffic, api)) bot.add_command('/number', 'get fun fact for a number', functools.partial(number, api)) bot.add_command('/dilbert', 'get random dilbert comic', functools.partial(dilbert, api)) bot.add_command('/peanuts', 'get random peanuts comic', peanuts) # run bot bot.run(host='0.0.0.0', port=5000)
def __init__(self, token): bot_identity = BOT_IDENTITY = { 'TOKEN': token, } self.md = rendering.md() # Do we have the basic mandatory config needed to operate the bot self._bot_token = bot_identity.get('TOKEN', None) if not self._bot_token: log.fatal('You need to define the Cisco Webex Teams Bot TOKEN in the BOT_IDENTITY of config.py.') sys.exit(1) print("Setting up SparkAPI") self.webex_teams_api = webexteamssdk.WebexTeamsAPI(access_token=self._bot_token) print("Setting up device on Webex Teams") self.device_info = self._get_device_info() print("Fetching and building identifier for the bot itself.") self.bot_identifier = CiscoWebexTeamsPerson(self, self.webex_teams_api.people.me()) print("Done! I'm connected as {}".format(self.bot_identifier.email)) self._register_identifiers_pickling()
def get_webex_teams_username(): teams = webexteamssdk.WebexTeamsAPI(env_user.WEBEX_TEAMS_ACCESS_TOKEN) data = teams.people.me() if data: return data.displayName return f"random-user-{random.randint(0,100)}"
def main(): api = webexteamssdk.WebexTeamsAPI(access_token=ACCESS_TOKEN) # take 1st few spaces print(f'Getting first {SPACES} spaces...') spaces = list(itertools.islice(api.rooms.list(max=100), SPACES)) print(f'Got first {SPACES} spaces...') _, seconds = get_memberships(api, spaces) _, seconds_concurrent = get_memberships_concurrent(api, spaces) _, seconds_asyncio = asyncio.run(get_memberships_asyncio(spaces)) print(f'get_memberships() took {seconds} seconds') print(f'get_memberships_concurrent() took {seconds_concurrent} seconds') print(f'get_memberships_asyncio() took {seconds_asyncio} seconds')
def verify() -> bool: """Verify access to the Webex Teams APIs.""" print(blue("\n==> Verifying access to the Webex Teams APIs")) # Check to ensure the user has provided their Spark Access Token if not env_user.WEBEX_TEAMS_ACCESS_TOKEN: print( red("\nFAILED: You must provide your WEBEX_TEAMS_ACCESS_TOKEN in the " "env_user.py file.\n")) return False try: teams = webexteamssdk.WebexTeamsAPI(env_user.WEBEX_TEAMS_ACCESS_TOKEN) me = teams.people.me() except webexteamssdk.ApiError as e: print( red(f"\nFAILED: The API call to Webex Teams returned the following " "error:\n{e}\n")) return False else: print( green(f"\nYou are connected to Webex Teams as: {me.emails[0]}\n")) # Check to ensure the user has provided a WebEx TEAMS Room ID if not env_user.WEBEX_TEAMS_ROOM_ID: print( red("\nFAILED: You must provide the WEBEX_TEAMS_ROOM_ID of the room you " "want to work with in the env_user.py file.\n")) return False # Verify the Spark Room exists and is accessible via the access token try: room = teams.rooms.get(env_user.WEBEX_TEAMS_ROOM_ID) except webexteamssdk.ApiError as e: print( red(f"\nFAILED: There was an error accessing the Spark Room using the WEBEX_TEAMS_ROOM_ID you provided; error details:\n{e}\n" )) return False else: print( green( f"You will be posting messages to the following room: {room.title}\n" )) return True
def __init__(self, access_token: str, device_name: Optional[str] = None, default_action: Optional[str] = '/help', executor: Optional[Executor] = None) -> None: self._token = access_token self._device_name = device_name or os.path.basename( os.path.splitext(__file__)[0]) self._session: Optional[aiohttp.ClientSession] = None self._api = webexteamssdk.WebexTeamsAPI(access_token=access_token) self._commands = { "/echo": { "help": "Display help text.", "callback": self.send_echo, }, "/help": { "help": "Get help.", "callback": self.send_help }, } self._default_action = default_action self._executor = executor or ThreadPoolExecutor(max_workers=4)
def __init__(self, config): super().__init__(config) bot_identity = config.BOT_IDENTITY self.md = rendering.md() # Do we have the basic mandatory config needed to operate the bot self._bot_token = bot_identity.get("TOKEN", None) if not self._bot_token: log.fatal( "You need to define the Cisco Webex Teams Bot TOKEN in the BOT_IDENTITY of config.py." ) sys.exit(1) # Adjust message size limit to cater for the non-standard size limit if config.MESSAGE_SIZE_LIMIT > CISCO_WEBEX_TEAMS_MESSAGE_SIZE_LIMIT: log.info( "Capping MESSAGE_SIZE_LIMIT to {} which is the maximum length allowed by CiscoWebexTeams".format( CISCO_WEBEX_TEAMS_MESSAGE_SIZE_LIMIT ) ) config.MESSAGE_SIZE_LIMIT = CISCO_WEBEX_TEAMS_MESSAGE_SIZE_LIMIT log.debug("Setting up SparkAPI") self.webex_teams_api = webexteamssdk.WebexTeamsAPI(access_token=self._bot_token) log.debug("Setting up device on Webex Teams") self.device_info = self._get_device_info() log.debug("Fetching and building identifier for the bot itself.") self.bot_identifier = CiscoWebexTeamsPerson( self, self.webex_teams_api.people.me() ) log.debug("Done! I'm connected as {}".format(self.bot_identifier.email)) self._register_identifiers_pickling()
def test_default_single_request_timeout(): connection_object = webexteamssdk.WebexTeamsAPI() assert connection_object.single_request_timeout == \ DEFAULT_SINGLE_REQUEST_TIMEOUT
# -*- coding: utf-8 -*- """IPython Project Console. Used to interactively work with the main package contents in IPython. """ from __future__ import ( absolute_import, division, print_function, unicode_literals, ) from builtins import * import webexteamssdk __copyright__ = "Copyright (c) 2016-2020 Cisco and/or its affiliates." __license__ = "MIT" api = webexteamssdk.WebexTeamsAPI()
def test_default_base_url(): connection_object = webexteamssdk.WebexTeamsAPI() assert connection_object.base_url == DEFAULT_BASE_URL
def test_create_with_access_token_environment_variable(): connection_object = webexteamssdk.WebexTeamsAPI() assert isinstance(connection_object, webexteamssdk.WebexTeamsAPI)
def api(): return webexteamssdk.WebexTeamsAPI()
def abseto_handler(): global GRANT_URLS payload = request.get_json() pprint(payload) # When using DialogFlow, POST payload is embedded in a slightly different # JSON structure. Check if key originalDetectIntentRequest is present to know if # payload is from DialogFlow or Webex if "originalDetectIntentRequest" in payload: payload = payload["originalDetectIntentRequest"]["payload"]["data"] session = requests.Session() teams_api = webexteamssdk.WebexTeamsAPI(access_token=BOT_TOKEN) # If message came from DialogFlow this check is redundant, but in # order to keep the logic simpler and the code more versatile we check that # the resource value is messages if payload["resource"] == "messages": # filter bot self triggered message if payload["data"]["personEmail"] == "*****@*****.**": return "OK" message = get_message(session, payload) pprint(f"Message received: {message}") if message.strip().lower() == "wifi": with open('templates/message.json') as fp: text = fp.read() converted = pystache.render(text) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] teams_api.messages.create(roomId=payload["data"]["roomId"], text="Intro card", attachments=data) else: teams_api.messages.create(roomId=payload["data"]["roomId"], text="Unrecognized command") elif payload["resource"] == "attachmentActions": card_data = get_card_data(session, payload) pprint(card_data) person_info = get_person_info(session, card_data) pprint(person_info) #ensure that the user selects both fields in the Card - User Type and location. #Returns error if only one field is selected if "user_type" not in card_data[ "inputs"] or "location" not in card_data["inputs"]: with open('templates/card_selection_error.json') as fp: text = fp.read() converted = pystache.render( text, { "display_name": person_info["displayName"], "user_email": person_info["emails"][0] }) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] teams_api.messages.create(roomId=payload["data"]["roomId"], text="select both fields", attachments=data) return "OK" is_partner = is_partner_meraki(person_info["emails"][0], get_meraki_users("CiscoEdgeKZN1")) if card_data["inputs"]["user_type"] == "partner": if len(person_info["emails"]) and is_partner: with open("templates/welcome.json") as fp: text = fp.read() #generate random password for each partner #this uses an uppercase character, lowercase character and digit #each password is 8 characters long. password = "".join( random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=8)) #save the password in mongodb save_password_in_db({ "user_email": person_info["emails"][0], "password": password }) converted = pystache.render( text, { "user_name": person_info["displayName"], "location": card_data["inputs"]["location"], "user_link": CAPTIVE_PORTAL_URL, "password": password }) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] teams_api.messages.create(roomId=payload["data"]["roomId"], text="Welcome card", attachments=data) else: with open('templates/no_partner.json') as fp: text = fp.read() converted = pystache.render( text, { "display_name": person_info["displayName"], "location": card_data["inputs"]["location"], "user_email": person_info["emails"][0] }) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] teams_api.messages.create( toPersonEmail="*****@*****.**", text="New partner registration Request", attachments=data) teams_api.messages.create( roomId=payload["data"]["roomId"], text= "Thank you. The ambassador has been informed. We shall get back to you shortly" ) elif card_data["inputs"]["user_type"] == "guest": if is_partner: with open('templates/partner_error.json') as fp: text = fp.read() converted = pystache.render( text, { "display_name": person_info["displayName"], "location": card_data["inputs"]["location"], "user_email": person_info["emails"][0] }) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] teams_api.messages.create(roomId=payload["data"]["roomId"], text="Redirect partner", attachments=data) else: with open('templates/guest_link.json') as fp: text = fp.read() password = "".join( random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=8)) save_password_in_db({ "user_email": person_info["emails"][0], "password": password }) converted = pystache.render( text, { "user_name": person_info["displayName"], "location": card_data["inputs"]["location"], "user_link": CAPTIVE_PORTAL_URL, "password": password }) card = json.loads(converted) data = [{ 'contentType': 'application/vnd.microsoft.card.adaptive', 'content': card }] guest = { "user_name": person_info["displayName"], "user_email": person_info["emails"][0] } save_guest_db(guest) teams_api.messages.create(roomId=payload["data"]["roomId"], text="Welcome card", attachments=data) return "OK"
if CONFIG_DATA['WEBEX_ACCESS_TOKEN'] == '' or CONFIG_DATA['WEBEX_ROOM_ID'] == '': # user feed back sys.stdout.write("Webex Teams not set.\n") sys.stdout.write("\n") else: # adjust the Webex message based on the config if CONFIG_DATA['AUTO_DEPLOY']: message_text = f"Microsoft Office 365 objects have been successfully updated for the {CONFIG_DATA['O365_PLAN']} plan and {CONFIG_DATA['SERVICE_AREAS']} apps! Firepower policy deployment was initiated..." else: message_text = f"Microsoft Office 365 objects have been successfully updated for the {CONFIG_DATA['O365_PLAN']} plan and {CONFIG_DATA['SERVICE_AREAS']} apps! Firepower policy deployment is required." # instantiate the Webex handler with the access token #webex = ciscosparkapi.CiscoSparkAPI(CONFIG_DATA['WEBEX_ACCESS_TOKEN']) teams = webexteamssdk.WebexTeamsAPI(CONFIG_DATA['WEBEX_ACCESS_TOKEN']) # post a message to the specified Webex room message = teams.messages.create(CONFIG_DATA['WEBEX_ROOM_ID'], text=message_text) elif bool_new_version == False: # no new version, do nothing pass ##############END PARSE FUNCTION##############START EXECUTION SCRIPT############## if __name__ == "__main__": # Load config data from file loadConfig()
def WebServiceParser(): bool_new_version = check_for_new_version() if bool_new_version == True: # Instantiate a Firepower object fmc = Firepower(CONFIG_DATA) # If there's no defined Network Object, make one, then store the UUID - else, get the current object if CONFIG_DATA['IP_BYPASS_UUID'] is '': # Create the JSON to submit object_json = { 'name': OBJECT_PREFIX + "ZOOM_IPs_BYPASS", 'type': 'NetworkGroup', 'overridable': True, } # Create the Network Group object in the FMC ip_group_object = fmc.createObject('networkgroups', object_json) # Save the UUID of the object CONFIG_DATA['IP_BYPASS_UUID'] = ip_group_object['id'] saveConfig() else: # Get the Network Group object of the specified UUID ip_group_object = fmc.getObject('networkgroups', CONFIG_DATA['IP_BYPASS_UUID']) # If there's no defined URL Object, make one, then store the UUID if CONFIG_DATA['URL_BYPASS_UUID'] is '': # Create the JSON to submit object_json = { 'name': OBJECT_PREFIX + "ZOOM_URLs_BYPASS", 'type': 'UrlGroup', 'overridable': True, } # Create the Network Group object in the FMC url_group_object = fmc.createObject('urlgroups', object_json) # Save the UUID of the object CONFIG_DATA['URL_BYPASS_UUID'] = url_group_object['id'] saveConfig() else: # Get the Network Group object of the specified UUID url_group_object = fmc.getObject('urlgroups', CONFIG_DATA['URL_BYPASS_UUID']) # initiate lists to be filled with addresses IP_List = [] URL_List = [] # reading the json local file with open('json/zoom.json') as z: zoom = json.load(z) with open('json/zoom_meetings.json') as m: meetings = json.load(m) with open('json/zoom_crc.json') as c: crc = json.load(c) with open('json/zoom_phone.json') as p: phone = json.load(p) # iterate through each 'item' in the JSON data for zoom_key, zoom_subdict in zoom.items(): for zoom_subkey, zoom_value in zoom_subdict.items(): # iterate through all IPs in each item IP_List.append(zoom_value) for meetings_key, meetings_subdict in meetings.items(): for meetings_subkey, meetings_value in meetings_subdict.items(): # iterate through all IPs in each item IP_List.append(meetings_value) for crc_key, crc_subdict in crc.items(): for crc_subkey, crc_value in crc_subdict.items(): # iterate through all IPs in each item IP_List.append(crc_value) for phone_key, phone_subdict in phone.items(): for phone_subkey, phone_value in phone_subdict.items(): # iterate through all IPs in each item IP_List.append(phone_value) # Reset the fetched Network Group object to clear the 'literals' ip_group_object['literals'] = [] ip_group_object.pop('links', None) # check whether list not empty (microsoft sometimes doesn't return IP's for default IP addresses for example) if not IP_List: IP_List.append("240.0.0.0/4") # user feed back sys.stdout.write("\n") sys.stdout.write("IP_BYPASS list returned no IP's, empty list with dummy IP range (240.0.0.0/4) created (to avoid policy deploy failure)...\n") # Add all the fetched IPs to the 'literals'of the Network Group object for ip_address in IP_List: ip_group_object['literals'].append({'type': 'Network', 'value': ip_address}) #ip_group_object = list(dict.fromkeys(ip_group_object)) #print(ip_group_object) # Update the NetworkGroup object fmc.updateObject('networkgroups', CONFIG_DATA['IP_BYPASS_UUID'], ip_group_object) # Reset the fetched URL Group object to clear the 'literals' url_group_object['literals'] = [] url_group_object.pop('links', None) URL_List.append("zoom.us") URL_List.append("*.zoom.us") if not URL_List: URL_List.append("example.com") # user feed back sys.stdout.write("\n") sys.stdout.write("URL_BYPASS list returned no URL's, empty list with dummy URL (example.com) created (to avoid policy deploy failure)...\n") # Add all the fetched URLs to the 'literals' of the URL Group object for url in URL_List: url_group_object['literals'].append({'type': 'Url', 'url': url}) # Update the UrlGroup object fmc.updateObject('urlgroups', CONFIG_DATA['URL_BYPASS_UUID'], url_group_object) # user feed back sys.stdout.write("\n") sys.stdout.write(f"A lista de Web Service do Zoom foi atualizada com sucesso!\n") sys.stdout.write("\n") saveConfig() # If the user wants us to deploy policies, then do it if CONFIG_DATA['AUTO_DEPLOY']: DeployPolicies(fmc) # if Webex Teams tokens set, then send message to Webex room if CONFIG_DATA['WEBEX_ACCESS_TOKEN'] == '' or CONFIG_DATA['WEBEX_ROOM_ID'] == '': # user feed back sys.stdout.write("Webex Teams not set.\n") sys.stdout.write("\n") else: # adjust the Webex message based on the config if CONFIG_DATA['AUTO_DEPLOY']: message_text = f"Objetos Zoom foram atualizados com sucesso! Deployment inicado..." else: message_text = f"Objetos Zoom foram atualizados com sucesso! É necessario um deploy na policy do Firepower." # instantiate the Webex handler with the access token #webex = ciscosparkapi.CiscoSparkAPI(CONFIG_DATA['WEBEX_ACCESS_TOKEN']) teams = webexteamssdk.WebexTeamsAPI(CONFIG_DATA['WEBEX_ACCESS_TOKEN']) # post a message to the specified Webex room message = teams.messages.create(CONFIG_DATA['WEBEX_ROOM_ID'], text=message_text) elif bool_new_version == False: # no new version, do nothing pass
def test_custom_single_request_timeout(): custom_timeout = 10 connection_object = webexteamssdk.WebexTeamsAPI( single_request_timeout=custom_timeout ) assert connection_object.single_request_timeout == custom_timeout
def test_non_default_wait_on_rate_limit(): connection_object = webexteamssdk.WebexTeamsAPI( wait_on_rate_limit=not DEFAULT_WAIT_ON_RATE_LIMIT ) assert connection_object.wait_on_rate_limit != \ DEFAULT_WAIT_ON_RATE_LIMIT
verify=False, headers=headers) if (response.status_code == 204): print( "Done!..Applied Quarantine policy to the rogue endpoint...MAC: {0} Threat is now contained...." .format(items)) else: print("An error has ocurred with the following code %(error)s" % {'error': response.status_code}) if __name__ == "__main__": maclist_path = repository_root / "mission-data/mac-addresses.json" maclist = readmacaddr_file(maclist_path) #TODO Call the function for getting ANC policy and store it in the policylist variable env_lab.print_missing_mission_warn(env_lab.get_line()) #TODO call the function for applying policy to the endpoints env_lab.print_missing_mission_warn(env_lab.get_line()) # # Finally, post a message to the Webex Teams Room to brag!!! print(blue("\n==> Posting message to Webex Teams")) teams = webexteamssdk.WebexTeamsAPI(env_user.WEBEX_TEAMS_ACCESS_TOKEN) teams.messages.create( roomId=env_user.WEBEX_TEAMS_ROOM_ID, markdown=f"**ISE Mission completed!!!** \n\n" f"I have applied quarantine policy to the rogue endpoints! \n\n") print(green("ISE Mission Completed!!!"))
def test_create_without_an_access_token(): with pytest.raises(webexteamssdk.AccessTokenError): webexteamssdk.WebexTeamsAPI()
def new_casebook(feed_name, returned_observables_json, returned_sightings, entry_title, entry_link): ''' this function post list of observables to new casebook ''' # create headers for API request bearer_token = 'Bearer ' + get_CTR_access_token() headers = { 'Authorization': bearer_token, 'Content-Type': 'application/json', 'Accept': 'application/json' } # create title and description for SOC researcher to have more context, if there are sightings, add high priority if returned_sightings['total_sighting_count'] == 0: casebook_title = feed_name + ": " + entry_title if returned_sightings['total_sighting_count'] != 0: casebook_title = "*HIGH PRIORITY* " + feed_name + ": " + entry_title casebook_description = "Python generated casebook from: " + feed_name + ". Link to blogpost: " + entry_link casebook_datetime = datetime.now().isoformat() + "Z" # create right json format to create casebook casebook_json = json.dumps({ "title": casebook_title, "description": casebook_description, "observables": json.loads(returned_observables_json), "type": "casebook", "timestamp": casebook_datetime }) # post request to create casebook response = requests.post( 'https://private.intel.amp.cisco.com/ctia/casebook', headers=headers, data=casebook_json) if response.status_code == 201: print( f"[201] Success, case added to Casebook added from {feed_name}: {entry_title}\n" ) # if Webex Teams tokens set, then send message to Webex room if config_file['webex_access_token'] is '' or config_file[ 'webex_room_id'] is '': # user feed back print("Webex Teams not set.\n\n") else: # instantiate the Webex handler with the access token teams = webexteamssdk.WebexTeamsAPI( config_file['webex_access_token']) # post a message to the specified Webex room try: if returned_sightings['total_sighting_count'] == 0: webex_text = feed_name + " New case has been added to casebook from RSS Feed: " + entry_title message = teams.messages.create( config_file['webex_room_id'], text=webex_text) if returned_sightings['total_sighting_count'] != 0: webex_text = feed_name + " New case has been added to casebook from RSS Feed: " + entry_title + ". 🚨🚨🚨 HIGH PRIORITY, Target Sightings have been identified! AMP targets: " + str( returned_sightings['total_amp_sighting_count'] ) + ", Umbrella targets: " + str( returned_sightings['total_umbrella_sighting_count'] ) + ", Email targets: " + str( returned_sightings['total_email_sighting_count'] ) + ". 🚨🚨🚨" message = teams.messages.create( config_file['webex_room_id'], text=webex_text) # error handling, if for example the Webex API key expired except Exception: print( "Webex authentication failed... Please make sure Webex Teams API key has not expired. Please review developer.webex.com for more info.\n" ) else: print( f"Something went wrong while posting the casebook to CTR, status code: {response.status_code}\n" ) return response.text
def test_create_with_access_token_argument(access_token): connection_object = webexteamssdk.WebexTeamsAPI( access_token=access_token ) assert isinstance(connection_object, webexteamssdk.WebexTeamsAPI)
def api(access_token): return webexteamssdk.WebexTeamsAPI(access_token=access_token)
def test_custom_base_url(): custom_url = "https://custom.domain.com/v1/" connection_object = webexteamssdk.WebexTeamsAPI(base_url=custom_url) assert connection_object.base_url == custom_url
def send_webex_message(message): teams = webexteamssdk.WebexTeamsAPI(env_user.WEBEX_TEAMS_ACCESS_TOKEN) teams.messages.create( roomId=env_user.WEBEX_TEAMS_ROOM_ID, markdown=message )