Beispiel #1
0
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
Beispiel #2
0
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))
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #6
0
    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)
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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