def fetch_samples(client, mapper_in, report_url): """ This function returns a list of (at most) five sample events (used for classification and mapping only). Args: client: Workday client mapper_in: Incoming mapper's name report_url: The report full URL Returns: events: Incidents/events that will be used as samples for classification and mapping. """ events = [] num_of_samples = 5 try: report_data = client.get_full_report(report_url) report_entries = report_data.get('Report_Entry') num_of_samples = min(num_of_samples, len(report_entries)) report_entries = report_entries[:num_of_samples] for entry in report_entries: workday_user = demisto.mapObject(entry, mapper_in, INCIDENT_TYPE) workday_user = convert_incident_fields_to_cli_names(workday_user) entry['UserProfile'] = workday_user event = { "name": workday_user.get('email'), "rawJSON": json.dumps(entry), "details": 'This is a sample event.' } events.append(event) except Exception as e: demisto.error('Failed to fetch events. Reason: ' + str(e)) raise e return events
def main(): try: args = demisto.args() pwd_generation_script = args.get("pwdGenerationScript") user_profile = args.get("userProfile") to_email = args.get("email") mapper_in = args.get("mapperIn", DEFAULT_OUTGOING_MAPPER) if not user_profile: # no user was created return # Generate a random password outputs = demisto.executeCommand(pwd_generation_script, {}) password_dict = demisto.get(outputs[0], 'Contents') password = password_dict.get("NEW_PASSWORD") user = demisto.mapObject(json.loads(user_profile), mapper_in, MAPPING_TYPE) user_email = user.get("email") username = user_email.split("@")[0] display_name = user.get("displayname") # setting a new password ad_create_user_arguments = { 'username': username, 'password': password, 'attribute-name': 'pwdLastSet', 'attribute-value': -1 } flow_worked = True password_outputs = demisto.executeCommand("ad-set-new-password", ad_create_user_arguments) if is_error(password_outputs): flow_worked = False return_results(password_outputs) enable_outputs = demisto.executeCommand("ad-enable-account", ad_create_user_arguments) if is_error(enable_outputs): flow_worked = False return_results(enable_outputs) update_outputs = demisto.executeCommand("ad-update-user", ad_create_user_arguments) if is_error(update_outputs): flow_worked = False return_results(update_outputs) if flow_worked: send_email(display_name, username, user_email, password, to_email) return_results("User was enabled and a password was set.") else: return_results("Some commands failed, please check the errors.") except Exception as e: demisto.log(traceback.format_exc()) return_error(str(e))
def get_workday_user_from_entry(entry, mapper_in, workday_date_format, source_priority): workday_user = demisto.mapObject(entry, mapper_in, DEFAULT_INCIDENT_TYPE) workday_user = convert_incident_fields_to_cli_names(workday_user) reformat_date_fields(workday_user, workday_date_format) workday_user[SOURCE_PRIORITY_FIELD] = source_priority workday_user[SOURCE_OF_TRUTH_FIELD] = 'Workday IAM' return workday_user
def map_object(self, mapper_name, incident_type, map_old_data: bool = False): """ Returns the user data, in an application data format. :type mapper_name: ``str`` :param mapper_name: The outgoing mapper from XSOAR to the application. :type incident_type: ``str`` :param incident_type: The incident type used. :type map_old_data ``bool`` :param map_old_data: Whether to map old data as well. :return: the user data, in the app data format. :rtype: ``dict`` """ if self.mapped_user_profile: if not map_old_data: return { k: v for k, v in self.mapped_user_profile.items() if k != 'olduserdata' } return self.mapped_user_profile if incident_type not in [ IAMUserProfile.CREATE_INCIDENT_TYPE, IAMUserProfile.UPDATE_INCIDENT_TYPE, IAMUserProfile.DISABLE_INCIDENT_TYPE ]: raise DemistoException( 'You must provide a valid incident type to the map_object function.' ) if not self._user_profile: raise DemistoException('You must provide the user profile data.') app_data = demisto.mapObject(self._user_profile, mapper_name, incident_type) if map_old_data and 'olduserdata' in self._user_profile: app_data['olduserdata'] = demisto.mapObject( self._user_profile.get('olduserdata', {}), mapper_name, incident_type) return app_data
def fetch_incidents(client, mapper_in, report_url): """ This function will execute each interval (default is 1 minute). Args: client: Workday client mapper_in: Incoming mapper's name report_url: The report full URL. Returns: events: Incidents/Events that will be created in Cortex XSOAR """ events = [] try: employee_id_to_user_profile, email_to_user_profile = get_all_user_profiles( ) report_data = client.get_full_report(report_url) report_entries = report_data.get('Report_Entry') for entry in report_entries: workday_user = demisto.mapObject(entry, mapper_in, INCIDENT_TYPE) workday_user = convert_incident_fields_to_cli_names(workday_user) demisto_user = get_demisto_user(employee_id_to_user_profile, workday_user) user_profile_unchanged, changed_fields = is_user_profile_unchanged( demisto_user, workday_user) found_potential_termination = detect_potential_termination( demisto_user, workday_user) does_email_exist = does_user_email_exist_in_xsoar( email_to_user_profile, workday_user) if user_profile_unchanged or (not demisto_user and does_email_exist) \ and not found_potential_termination: # either no change in user profile or user profile doesn't exist but the email is already used # in both cases, don't create the incident continue entry['UserProfile'] = workday_user event = { "name": f'{workday_user.get("givenname")} {workday_user.get("surname")}', "rawJSON": json.dumps(entry), "details": 'Profile changed. Changed fields: ' + str(changed_fields) } events.append(event) except Exception as e: demisto.error('Failed to fetch events. Reason: ' + str(e)) raise e return events
def update_with_app_data(self, app_data, mapper_name, incident_type=None): """ updates the user_profile attribute according to the given app_data :type app_data: ``dict`` :param app_data: The user data in app :type mapper_name: ``str`` :param mapper_name: Incoming mapper name :type incident_type: ``str`` :param incident_type: Optional - incident type """ if not incident_type: incident_type = IAMUserProfile.DEFAULT_INCIDENT_TYPE if not isinstance(app_data, dict): app_data = safe_load_json(app_data) self._user_profile = demisto.mapObject(app_data, mapper_name, incident_type)
def map_object(self, mapper_name, mapping_type=None): """ Returns the user data, in an application data format. :type mapper_name: ``str`` :param mapper_name: The outgoing mapper from XSOAR to the application. :type mapping_type: ``str`` :param mapping_type: The mapping type of the mapper (optional). :return: the user data, in the app data format. :rtype: ``dict`` """ if not mapping_type: mapping_type = IAMUserProfile.INDICATOR_TYPE if not self._user_profile: raise DemistoException('You must provide the user profile data.') app_data = demisto.mapObject(self._user_profile, mapper_name, mapping_type) return app_data
def map_object(self, mapper_name, incident_type): """ Returns the user data, in an application data format. :type mapper_name: ``str`` :param mapper_name: The outgoing mapper from XSOAR to the application. :type incident_type: ``str`` :param incident_type: The incident type used. :return: the user data, in the app data format. :rtype: ``dict`` """ if incident_type not in [ IAMUserProfile.CREATE_INCIDENT_TYPE, IAMUserProfile.UPDATE_INCIDENT_TYPE ]: raise DemistoException( 'You must provide a valid incident type to the map_object function.' ) if not self._user_profile: raise DemistoException('You must provide the user profile data.') app_data = demisto.mapObject(self._user_profile, mapper_name, incident_type) return app_data
def get_workday_user_from_entry(entry, mapper_in, workday_date_format): workday_user = demisto.mapObject(entry, mapper_in, DEFAULT_INCIDENT_TYPE) workday_user = convert_incident_fields_to_cli_names(workday_user) reformat_date_fields(workday_user, workday_date_format) return workday_user
def entry_to_user_profile(entry, mapper_in): user_profile = demisto.mapObject(entry, mapper_in, INCIDENT_TYPE) user_profile = convert_incident_fields_to_cli_names(user_profile) return user_profile
def entry_to_user_profile(entry, mapper_in, workday_date_format): user_profile = demisto.mapObject(entry, mapper_in, INCIDENT_TYPE) user_profile = convert_incident_fields_to_cli_names(user_profile) reformat_date_fields(user_profile, workday_date_format) return user_profile
def fetch_incidents(client, mapper_in, report_url, workday_date_format): """ This function will execute each interval (default is 1 minute). Args: client: Workday client mapper_in: Incoming mapper's name report_url: The report full URL. workday_date_format: Date format in Workday report. Returns: events: Incidents/Events that will be created in Cortex XSOAR """ events = [] try: employee_id_to_user_profile, email_to_user_profile = get_all_user_profiles( ) report_data = client.get_full_report(report_url) report_entries = report_data.get('Report_Entry') for entry in report_entries: workday_user = demisto.mapObject(entry, mapper_in, INCIDENT_TYPE) workday_user = convert_incident_fields_to_cli_names(workday_user) reformat_date_fields(workday_user, workday_date_format) demisto_user = get_demisto_user(employee_id_to_user_profile, workday_user) demisto.debug( f'{workday_user.get("email")} - demisto_user={demisto_user}') user_exists_in_xsoar = demisto_user is not None email_exists_in_xsoar = does_user_email_exist_in_xsoar( email_to_user_profile, workday_user) if not user_exists_in_xsoar and email_exists_in_xsoar: demisto.debug( f'Skipped creating an incident for the following user profile:\n{workday_user}\n\n' f'The user profile doesn\'t exist but its email is already being used by another user.' ) continue user_profile_changed, changed_fields = has_user_profile_changed( demisto_user, workday_user) found_potential_termination = detect_potential_termination( demisto_user, workday_user) if user_exists_in_xsoar and not user_profile_changed and not found_potential_termination: demisto.debug( f'Skipped creating an incident for the following user profile:\n{workday_user}\n\n' f'No change was detected in an active user profile.') continue entry['UserProfile'] = workday_user event = { "name": workday_user.get('email'), "rawJSON": json.dumps(entry), "details": 'Profile changed. Changed fields: ' + str(changed_fields) } events.append(event) except Exception as e: demisto.error('Failed to fetch events. Reason: ' + str(e)) raise e return events