[MODEL: dataset="ping_identity_pingfederate_raw"]
// PingFederate writes its audit log as CEF key-value pairs.
// cs1..cs6 are CEF custom string fields whose meaning is given by the matching cs*Label field,
// therefore every custom string field is resolved through its label rather than by position.
alter
tmp_target_application_url = if(lowercase(cs1Label) = "target application url" and cs1 != "", cs1, null),
tmp_protocol = if(lowercase(cs3Label) = "protocol" and cs3 != "", cs3, null),
tmp_role = if(lowercase(cs4Label) = "role" and cs4 != "", cs4, null),
tmp_sp_local_user_id = if(lowercase(cs5Label) = "sp local user id" and cs5 != "", cs5, null),
tmp_attributes = if(lowercase(cs6Label) = "attributes" and cs6 != "", cs6, null),
tmp_status = lowercase(msg),
tmp_event_name = coalesce(cefName, cefDeviceEventClassId)
| alter
// duid holds the subject and is reported as a plain username, an email address or a full DN.
tmp_duid_upn = if(duid ~= "^[^,\s]+@[^,\s]+\.\w+$", duid, duid contains "CN=", arrayindex(regextract(duid, "CN=([^,]+@[^,]+\.\w+)"), 0), null),
tmp_duid_username = if(duid = "", null, duid contains "CN=", arrayindex(regextract(duid, "CN=([^,@]+?)(?:,|$)"), 0), duid),
// The attributes field is a comma separated list of <key>=<value> pairs whose keys differ per connection.
tmp_attr_saml_subject = arrayindex(regextract(tmp_attributes, "(?:^|,\s)SAML_SUBJECT=([^,]+)"), 0),
tmp_attr_upn = arrayindex(regextract(tmp_attributes, "(?:^|,\s)(?:UPN|upn|USER_KEY)=([^,]+)"), 0),
tmp_attr_mail = arrayindex(regextract(tmp_attributes, "(?:^|,\s)(?:mail|email|Email|e\-mail|emailAddress|emailaddress|email_address)=([^,]+)"), 0),
tmp_attr_uid = arrayindex(regextract(tmp_attributes, "(?:^|,\s)(?:uid|userid|UserID|UserId|userName|username|login|ssoId)=([^,]+)"), 0),
tmp_attr_first_name = arrayindex(regextract(tmp_attributes, "(?:^|,\s)(?:givenName|givenname|GivenName|firstName|firstname|FirstName|first_name|First)=([^,]+)"), 0),
tmp_attr_last_name = arrayindex(regextract(tmp_attributes, "(?:^|,\s)(?:sn|surname|lastName|lastname|LastName|last_name|Last)=([^,]+)"), 0),
tmp_attr_roles = regextract(tmp_attributes, "(?:^|,\s)(?:role|roles|userRole|userRoles|role_role|Claims_365_Pega_Role)=([^,\]]+)"),
// Group membership is either a list of DNs (memberOf=[CN=<group>,OU=...]) or a plain group name.
tmp_groups_from_dn = regextract(tmp_attributes, "CN=([^,]+),OU="),
tmp_groups_plain = regextract(tmp_attributes, "(?:^|,\s)(?:MemberOf|memberOf|groups|Group)=\[?([^,\]]+)")
| alter
tmp_username = coalesce(tmp_duid_username, tmp_attr_uid, tmp_attr_saml_subject, tmp_sp_local_user_id),
tmp_upn = coalesce(tmp_duid_upn, tmp_attr_upn, tmp_attr_mail),
tmp_groups = if(arrayindex(tmp_groups_from_dn, 0) != null, tmp_groups_from_dn, tmp_groups_plain),
tmp_src_ipv4 = if(is_ipv4(src), src, null),
tmp_src_ipv6 = if(is_ipv6(src), src, null)
| alter
xdm.observer.vendor = cefDeviceVendor,
xdm.observer.product = cefDeviceProduct,
xdm.observer.version = cefDeviceVersion,
xdm.observer.name = dvchost,
xdm.observer.type = tmp_role, // IdP (identity provider) or AS (OAuth authorization server).
xdm.event.type = tmp_event_name,
xdm.event.original_event_type = cefDeviceEventClassId,
xdm.event.format = if(cefVersion != "", "CEF", null),
xdm.event.tags = arraycreate(XDM_CONST.EVENT_TAG_AUTHENTICATION),
xdm.event.outcome = if(tmp_status = "success", XDM_CONST.OUTCOME_SUCCESS, tmp_status = "failure", XDM_CONST.OUTCOME_FAILED, XDM_CONST.OUTCOME_UNKNOWN),
xdm.event.outcome_reason = if(msg != "", msg, null),
xdm.event.is_completed = if(tmp_status = "inprogress", false, tmp_status = "", null, true),
xdm.event.description = if(
tmp_event_name = "AUTHN_ATTEMPT", "Authentication attempt",
tmp_event_name = "AUTHN_SESSION_CREATED", "Authentication session created",
tmp_event_name = "AUTHN_SESSION_USED", "Authentication session used",
tmp_event_name = "AUTHN_SESSIONS_DELETED", "Authentication sessions deleted",
tmp_event_name = "SSO", "Single sign-on",
tmp_event_name = "SLO", "Single logout",
tmp_event_name = "SRI_REVOKED", "Session revocation index revoked",
tmp_event_name = "OAuth", "OAuth",
tmp_event_name),
xdm.event.operation = if(
tmp_event_name in ("AUTHN_ATTEMPT", "AUTHN_SESSION_CREATED", "AUTHN_SESSION_USED", "SSO", "OAuth"), XDM_CONST.OPERATION_TYPE_AUTH_LOGIN,
tmp_event_name in ("AUTHN_SESSIONS_DELETED", "SRI_REVOKED"), XDM_CONST.OPERATION_TYPE_DELETE,
XDM_CONST.OPERATION_TYPE_AUTHENTICATION),
xdm.event.operation_sub_type = tmp_event_name,
xdm.auth.auth_method = tmp_protocol, // SAML20, WSFED or OAuth20.
xdm.source.ipv4 = tmp_src_ipv4,
xdm.source.ipv6 = tmp_src_ipv6,
xdm.source.user.username = tmp_username,
xdm.source.user.upn = tmp_upn,
xdm.source.user.identifier = coalesce(tmp_attr_saml_subject, if(duid != "", duid, null)),
xdm.source.user.first_name = tmp_attr_first_name,
xdm.source.user.last_name = tmp_attr_last_name,
xdm.source.user.groups = tmp_groups,
xdm.source.user.roles = tmp_attr_roles,
xdm.source.user.identity_type = if(tmp_username != null or tmp_upn != null, XDM_CONST.IDENTITY_TYPE_USER, XDM_CONST.IDENTITY_TYPE_UNKNOWN),
xdm.source.identity.username = tmp_username,
xdm.source.identity.upn = tmp_upn,
xdm.source.identity.identifier = coalesce(tmp_attr_saml_subject, if(duid != "", duid, null)),
xdm.source.identity.first_name = tmp_attr_first_name,
xdm.source.identity.last_name = tmp_attr_last_name,
xdm.source.identity.groups = tmp_groups,
xdm.source.identity.roles = tmp_attr_roles,
xdm.source.identity.identity_type = if(tmp_username != null or tmp_upn != null, XDM_CONST.IDENTITY_TYPE_USER, XDM_CONST.IDENTITY_TYPE_UNKNOWN),
xdm.target.url = tmp_target_application_url;