Skip to content

Commit cdec9b1

Browse files
[o365] Fixed parsing and indexing errors (#15699)
Fixes flattening error in Actions list when the list is encoded json string instead of json objects. Adds fields ActorInfoString, OperationCount, TokenObjectId, TokenTenantId. Added fields Messages and Folders as ExchangeAggregatedMessages and ExchangeAggregatedFolder for record type 50: ExchangeItemAggregated and explicitly convert the SizeInBytes values to long. There are other schemas for fields called Messages and Folders so explicit naming is defensive. Fixes error messages: field "o365.audit.ActorInfoString" is undefined field "o365.audit.Folders" is used as array of objects, expected explicit definition with type group or nested field "o365.audit.OperationCount" is undefined field "o365.audit.TokenObjectId" is undefined field "o365.audit.TokenTenantId" is undefined failed to parse field [o365.audit.Actions] of type [flattened] in document with id [o365.audit.Folders.FolderItems.SizeInBytes] cannot be changed from type [long] to [float] [o365.audit.Messages.MessageItems.SizeInBytes] cannot be changed from type [long] to [float]
1 parent 87d8dbd commit cdec9b1

File tree

7 files changed

+1183
-5
lines changed

7 files changed

+1183
-5
lines changed

packages/o365/changelog.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
# newer versions go on top
2+
- version: "2.33.0"
3+
changes:
4+
- description: >-
5+
Fix flattening errors in `Action` List items due to duplicate `QueryTime` fields by removing duplicate field.
6+
type: enhancement
7+
link: https://github.com/elastic/integrations/pull/15699
8+
- description: >-
9+
Fixes undefined errors by adding fields `ActorInfoString`, `OperationCount`, `TokenObjectId`, `TokenTenantId`
10+
type: bugfix
11+
link: https://github.com/elastic/integrations/pull/15699
12+
- description: >-
13+
Fixes errors due to SizeInBytes fields in `Messages` and `Folders` structures previously imported as long
14+
and then being sent as floats. Moves the fields to explicitly defined fields `ExchangeAggregatedMessages` and
15+
`ExchangeAggregatedFolders`and explicitly converts SizeInBytes to long for record type 50: `ExchangeItemAggregated`.
16+
type: bugfix
17+
link: https://github.com/elastic/integrations/pull/15699
218
- version: "2.32.0"
319
changes:
420
- description: Add device.id and user_agent fields from ExtendedProperties.additionalDetails.
@@ -8,7 +24,7 @@
824
changes:
925
- description: Improve documentation.
1026
type: enhancement
11-
link: https://github.com/elastic/integrations/pull/15660
27+
link: https://github.com/elastic/integrations/pull/1
1228
- version: "2.30.0"
1329
changes:
1430
- description: >-

packages/o365/data_stream/audit/_dev/test/pipeline/test-exchange-access-event.json

Lines changed: 222 additions & 0 deletions
Large diffs are not rendered by default.

packages/o365/data_stream/audit/_dev/test/pipeline/test-exchange-access-event.json-expected.json

Lines changed: 787 additions & 0 deletions
Large diffs are not rendered by default.

packages/o365/data_stream/audit/elasticsearch/ingest_pipeline/default.yml

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,15 @@ processors:
132132
if (!(ctx.o365audit.Actions instanceof List)) {
133133
ctx.o365audit.Actions = [ctx.o365audit.Actions];
134134
}
135+
136+
// Actions contains both a human readable `QueryTime` using AM/PM and an ISO8601 format `QueryTime`
137+
// We remove the AM/PM containing `QueryTime` to avoid duplicate field errors on flattening.
138+
def queryTimePattern = /,"QueryTime":"[0-9\/]+\s[0-9]+:[0-9]+:[0-9]+\s[AP]M"|"QueryTime":"[0-9\/]+\s[0-9]+:[0-9]+:[0-9]+\s[AP]M",/;
135139
for (def e: ctx.o365audit.Actions) {
136140
if (e instanceof Map) {
137141
actions.add(e);
138142
} else if (e instanceof String) {
139-
ctx._tmp.action_strings.add(e);
143+
ctx._tmp.action_strings.add(queryTimePattern.matcher(e).replaceAll(''));
140144
}
141145
}
142146
if (actions.length == ctx.o365audit.Actions.length) {
@@ -672,11 +676,11 @@ processors:
672676
target_field: file.extension
673677
ignore_missing: true
674678
if: ctx.event?.code != null && ["SharePointFileOperation", "SharePointSharingOperation"].contains(ctx.event.code)
675-
- append:
679+
- append:
676680
field: event.category
677681
value: file
678682
if: 'ctx.event?.action != null && ["FileAccessed", "FileDeleted", "FileDownloaded", "FileModified", "FileMoved", "FileRenamed", "FileRestored", "FileUploaded", "FolderCopied", "FolderCreated", "FolderDeleted", "FolderModified", "FolderMoved", "FolderRenamed", "FolderRestored"].contains(ctx.event?.action)'
679-
- append:
683+
- append:
680684
field: event.category
681685
value: configuration
682686
if: ctx.event?.action == "ComplianceSettingChanged"
@@ -1398,6 +1402,26 @@ processors:
13981402
} else {
13991403
ctx.o365audit.YammerNetworkId = ctx.o365audit.YammerNetworkId.toString();
14001404
}
1405+
- script:
1406+
tag: convert_runningtime
1407+
description: Ensure that RunningTime is not rendered with e-notation or other numeric
1408+
if: ctx.o365audit?.RunningTime != null
1409+
source: |-
1410+
if (ctx.o365audit.RunningTime instanceof double) {
1411+
ctx.o365audit.RunningTime = ((long)ctx.o365audit.RunningTime).toString();
1412+
} else {
1413+
ctx.o365audit.RunningTime = ctx.o365audit.RunningTime.toString();
1414+
}
1415+
- script:
1416+
tag: convert_operationcount
1417+
description: Ensure that OperationCount is not rendered with e-notation or other numeric
1418+
if: ctx.o365audit?.OperationCount != null
1419+
source: |-
1420+
if (ctx.o365audit.OperationCount instanceof Number) {
1421+
ctx.o365audit.OperationCount = ((long)ctx.o365audit.OperationCount).toString();
1422+
} else {
1423+
ctx.o365audit.OperationCount = ctx.o365audit.OperationCount.toString();
1424+
}
14011425
- append:
14021426
field: email.message_id
14031427
value: "{{{o365audit.InternetMessageId}}}"
@@ -1446,6 +1470,7 @@ processors:
14461470
field: o365audit.EndTimeUtc
14471471
target_field: o365audit.EndTimeUtc
14481472
tag: date_EndTimeUtc
1473+
timezone: "UTC"
14491474
formats:
14501475
- ISO8601
14511476
if: ctx.o365audit?.EndTimeUtc != null
@@ -1789,6 +1814,66 @@ processors:
17891814
copy_from: o365audit.ApplicationDisplayName
17901815
tag: set_application_name
17911816
ignore_empty_value: true
1817+
1818+
# ExchangeItemAggregated Schema
1819+
- append:
1820+
field: event.type
1821+
value: access
1822+
if: ctx.o365audit?.RecordType == "50"
1823+
- append:
1824+
field: event.category
1825+
value: email
1826+
if: ctx.o365audit?.RecordType == "50"
1827+
- rename:
1828+
field: o365audit.Messages
1829+
target_field: o365audit.ExchangeAggregatedMessages
1830+
tag: rename_messages_exchange
1831+
description: 'move generic Messages field to the ExchangeAggregatedMessages field type'
1832+
if: ctx.o365audit?.Messages != null && ctx.o365audit.RecordType == "50"
1833+
- script:
1834+
tag: convert_exchange_message_size_to_long
1835+
if: ctx.o365audit?.ExchangeAggregatedMessages != null
1836+
lang: painless
1837+
source: |
1838+
for (def i = 0; i < ctx.o365audit.ExchangeAggregatedMessages.length; i++) {
1839+
if (ctx.o365audit.ExchangeAggregatedMessages[i].MessageItems == null) {
1840+
continue;
1841+
}
1842+
for (def j = 0; j < ctx.o365audit.ExchangeAggregatedMessages[i].MessageItems.length; j++) {
1843+
def size = ctx.o365audit.ExchangeAggregatedMessages[i].MessageItems[j].SizeInBytes;
1844+
if (size instanceof String) {
1845+
ctx.o365audit.ExchangeAggregatedMessages[i].MessageItems[j].SizeInBytes = Long.parseLong(size);
1846+
} else {
1847+
ctx.o365audit.ExchangeAggregatedMessages[i].MessageItems[j].SizeInBytes = (long)size;
1848+
}
1849+
}
1850+
}
1851+
1852+
- rename:
1853+
field: o365audit.Folders
1854+
target_field: o365audit.ExchangeAggregatedFolders
1855+
tag: rename_folders_exchange
1856+
description: 'move generic Folders field to the O365 ExchangeAggregatedFolders field type'
1857+
if: ctx.o365audit?.Folders != null && ctx.o365audit.RecordType == "50"
1858+
- script:
1859+
tag: convert_exchange_folder_size_to_long
1860+
if: ctx.o365audit?.ExchangeAggregatedFolders != null
1861+
lang: painless
1862+
source: |
1863+
for (def i = 0; i < ctx.o365audit.ExchangeAggregatedFolders.length; i++) {
1864+
if (ctx.o365audit.ExchangeAggregatedFolders[i].FolderItems == null) {
1865+
continue;
1866+
}
1867+
for (def j = 0; j < ctx.o365audit.ExchangeAggregatedFolders[i].FolderItems.length; j++) {
1868+
def size = ctx.o365audit.ExchangeAggregatedFolders[i].FolderItems[j].SizeInBytes;
1869+
if (size instanceof String) {
1870+
ctx.o365audit.ExchangeAggregatedFolders[i].FolderItems[j].SizeInBytes = Long.parseLong(size);
1871+
} else {
1872+
ctx.o365audit.ExchangeAggregatedFolders[i].FolderItems[j].SizeInBytes = (long)size;
1873+
}
1874+
}
1875+
}
1876+
17921877
- script:
17931878
description: Handle _tmp.entities.ThreatDetectionMethods containing list of lists.
17941879
lang: painless

packages/o365/data_stream/audit/fields/fields.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
type: keyword
1717
- name: ActorContextId
1818
type: keyword
19+
- name: ActorInfoString
20+
type: keyword
1921
- name: ActorIpAddress
2022
type: keyword
2123
- name: ActorUserId
@@ -275,6 +277,52 @@
275277
# not expressible here; object_type_mapping_type cannot be 'boolean'.
276278
object_type: keyword
277279
object_type_mapping_type: '*'
280+
- name: ExchangeAggregatedFolders
281+
type: nested
282+
description: List of folders
283+
fields:
284+
- name: Path
285+
type: keyword
286+
description: Path of the folder
287+
- name: Id
288+
type: keyword
289+
description: Folder ID
290+
- name: FolderItems
291+
type: nested
292+
description: Items in the folder
293+
fields:
294+
- name: SizeInBytes
295+
type: long
296+
description: Size of the item in bytes
297+
- name: Id
298+
type: keyword
299+
description: Item ID
300+
- name: ImmutableId
301+
type: keyword
302+
description: Immutable ID of the item
303+
- name: InternetMessageId
304+
type: keyword
305+
description: Internet message ID
306+
- name: ExchangeAggregatedMessages
307+
type: nested
308+
description: List of messages
309+
fields:
310+
- name: Path
311+
type: keyword
312+
description: Path of the message
313+
- name: Id
314+
type: keyword
315+
description: Message ID
316+
- name: MessageItems
317+
type: nested
318+
description: Items in the message
319+
fields:
320+
- name: SizeInBytes
321+
type: long
322+
description: Size of the message item in bytes
323+
- name: Id
324+
type: keyword
325+
description: Message item ID
278326
- name: ExchangeMetaData
279327
type: group
280328
fields:
@@ -415,6 +463,8 @@
415463
type: keyword
416464
- name: Operation
417465
type: keyword
466+
- name: OperationCount
467+
type: keyword
418468
- name: OperationId
419469
type: keyword
420470
- name: OperationProperties
@@ -604,6 +654,10 @@
604654
type: keyword
605655
- name: ThreatDetectionMethods
606656
type: keyword
657+
- name: TokenObjectId
658+
type: keyword
659+
- name: TokenTenantId
660+
type: keyword
607661
- name: Timestamp
608662
type: keyword
609663
- name: UniqueSharingId

packages/o365/docs/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ An example event for `audit` looks as following:
237237
| o365.audit.Actor.ID | | keyword |
238238
| o365.audit.Actor.Type | | keyword |
239239
| o365.audit.ActorContextId | | keyword |
240+
| o365.audit.ActorInfoString | | keyword |
240241
| o365.audit.ActorIpAddress | | keyword |
241242
| o365.audit.ActorUserId | | keyword |
242243
| o365.audit.ActorYammerUserId | | keyword |
@@ -356,6 +357,16 @@ An example event for `audit` looks as following:
356357
| o365.audit.EventDeepLink | | keyword |
357358
| o365.audit.EventSource | | keyword |
358359
| o365.audit.ExceptionInfo.\* | | object |
360+
| o365.audit.ExchangeAggregatedFolders.FolderItems.Id | Item ID | keyword |
361+
| o365.audit.ExchangeAggregatedFolders.FolderItems.ImmutableId | Immutable ID of the item | keyword |
362+
| o365.audit.ExchangeAggregatedFolders.FolderItems.InternetMessageId | Internet message ID | keyword |
363+
| o365.audit.ExchangeAggregatedFolders.FolderItems.SizeInBytes | Size of the item in bytes | long |
364+
| o365.audit.ExchangeAggregatedFolders.Id | Folder ID | keyword |
365+
| o365.audit.ExchangeAggregatedFolders.Path | Path of the folder | keyword |
366+
| o365.audit.ExchangeAggregatedMessages.Id | Message ID | keyword |
367+
| o365.audit.ExchangeAggregatedMessages.MessageItems.Id | Message item ID | keyword |
368+
| o365.audit.ExchangeAggregatedMessages.MessageItems.SizeInBytes | Size of the message item in bytes | long |
369+
| o365.audit.ExchangeAggregatedMessages.Path | Path of the message | keyword |
359370
| o365.audit.ExchangeMetaData.\* | | long |
360371
| o365.audit.ExchangeMetaData.CC | | keyword |
361372
| o365.audit.ExchangeMetaData.MessageID | | keyword |
@@ -417,6 +428,7 @@ An example event for `audit` looks as following:
417428
| o365.audit.ObjectId | | keyword |
418429
| o365.audit.ObjectType | | keyword |
419430
| o365.audit.Operation | | keyword |
431+
| o365.audit.OperationCount | | keyword |
420432
| o365.audit.OperationId | | keyword |
421433
| o365.audit.OperationProperties | | object |
422434
| o365.audit.OrganizationId | | keyword |
@@ -501,6 +513,8 @@ An example event for `audit` looks as following:
501513
| o365.audit.TeamName | | keyword |
502514
| o365.audit.ThreatDetectionMethods | | keyword |
503515
| o365.audit.Timestamp | | keyword |
516+
| o365.audit.TokenObjectId | | keyword |
517+
| o365.audit.TokenTenantId | | keyword |
504518
| o365.audit.UniqueSharingId | | keyword |
505519
| o365.audit.UserAgent | | keyword |
506520
| o365.audit.UserId | | keyword |

packages/o365/manifest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: o365
22
title: Microsoft Office 365
3-
version: "2.32.0"
3+
version: "2.33.0"
44
description: Collect logs from Microsoft Office 365 with Elastic Agent.
55
type: integration
66
format_version: "3.2.3"

0 commit comments

Comments
 (0)