---
description: Pipeline for parsing Salesforce Login (Object) logs.
processors:
  - date:
      field: json.EventDate
      target_field: "@timestamp"
      formats:
        - ISO8601
      on_failure:
        - append:
            field: error.message
            value: "Failed to parse EventDate field: {{{_ingest.on_failure_message}}}"
  - rename:
      field: json.AuthServiceId
      target_field: salesforce.login.auth.service_id
      ignore_missing: true
      ignore_failure: true
  - convert:
      field: json.EvaluationTime
      type: double
      target_field: salesforce.login.evaluation_time
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.ClientVersion
      target_field: salesforce.login.client_version
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.LoginGeoId
      target_field: salesforce.login.geo_id
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.LoginHistoryId
      target_field: salesforce.login.history_id
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.ApiType
      target_field: salesforce.login.api.type
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.AuthMethodReference
      target_field: salesforce.login.auth.method_reference
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.LoginType
      target_field: salesforce.login.type
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.PolicyOutcome
      target_field: salesforce.login.policy_outcome
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.ApiVersion
      target_field: salesforce.login.api.version
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.EventIdentifier
      target_field: event.id
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.RelatedEventIdentifier
      target_field: salesforce.login.related_event_identifier
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.LoginKey
      target_field: salesforce.login.key
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Application
      target_field: salesforce.login.application
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.PolicyId
      target_field: salesforce.login.policy_id
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.SessionLevel
      target_field: salesforce.login.session.level
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.SessionKey
      target_field: salesforce.login.session.key
      ignore_missing: true
      ignore_failure: true
  - set:
      field: event.outcome
      value: success
      if: 'ctx.json?.Status == "Success"'
      ignore_empty_value: true
      ignore_failure: true
  - set:
      field: event.outcome
      value: failure
      if: 'ctx.json?.Status != "Success" && ctx.json?.Status != null'
      ignore_empty_value: true
      ignore_failure: true
  - date:
      field: json.CreatedDate
      target_field: event.created
      formats:
        - ISO8601
      on_failure:
        - append:
            field: error.message
            value: "Failed to parse CreatedDate field: {{{_ingest.on_failure_message}}}"
  - rename:
      field: json.LoginUrl
      target_field: event.url
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Username
      target_field: user.email
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.UserId
      target_field: user.id
      ignore_missing: true
      ignore_failure: true
  - set:
      field: user.roles
      value: "{{{json.UserType}}}"
      if: ctx.json?.UserType != null
      ignore_empty_value: true
      ignore_failure: true
  - remove:
      field: json.UserType
      ignore_missing: true
      ignore_failure: true
  - convert:
      field: json.SourceIp
      target_field: source.ip
      type: ip
      ignore_failure: true
      on_failure:
        - append:
            field: error.message
            value: "Failed to convert SourceIp to IP: {{{_ingest.on_failure_message}}}"
  - rename:
      field: json.LoginLatitude
      target_field: source.geo.location.lat
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.LoginLongitude
      target_field: source.geo.location.lon
      ignore_missing: true
      ignore_failure: true
  - geoip:
      field: source.ip
      target_field: source.geo
      ignore_missing: true
      ignore_failure: true
      if: '!ctx.source?.geo?.location?.containsKey("lat") && !ctx.source?.geo?.location?.containsKey("lon")'
  - rename:
      field: json.CountryIso
      target_field: source.geo.country_iso_code
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.PostalCode
      target_field: source.geo.postal_code
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.City
      target_field: source.geo.city_name
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Subdivision
      target_field: source.geo.region_name
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Country
      target_field: source.geo.country_name
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Browser
      target_field: user_agent.name
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.Platform
      target_field: user_agent.os.platform
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.HttpMethod
      target_field: http.request.method
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.AdditionalInfo
      target_field: salesforce.login.additional_info
      ignore_missing: true
      ignore_failure: true
  - rename:
      field: json.CipherSuite
      target_field: tls.cipher
      ignore_missing: true
      ignore_failure: true
  - dissect:
      field: json.TlsProtocol
      pattern: "%{tls.version_protocol} %{tls.version}"
      ignore_missing: true
      on_failure:
        - append:
            field: error.message
            value: "Failed to dissect TlsProtocol: {{{_ingest.on_failure_message}}}"

on_failure:
  - set:
      field: event.kind
      value: pipeline_error
  - append:
      field: error.message
      value: "{{{ _ingest.on_failure_message }}}"
