Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8f54b18

Browse filesBrowse files
author
Bogdan Tsechoev
committed
Merge branch 'siem_audit_settings' into 'master'
feat(ui): Integration of audit logs with SIEM systems See merge request postgres-ai/database-lab!947
2 parents dc881a6 + 77c3404 commit 8f54b18
Copy full SHA for 8f54b18

File tree

11 files changed

+974
-18
lines changed
Filter options

11 files changed

+974
-18
lines changed

‎ui/cspell.json

Copy file name to clipboardExpand all lines: ui/cspell.json
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
"sparql",
202202
"SPARQL",
203203
"subtransactions",
204-
"mbox"
204+
"mbox",
205+
"SIEM"
205206
]
206207
}

‎ui/packages/platform/src/actions/actions.js

Copy file name to clipboardExpand all lines: ui/packages/platform/src/actions/actions.js
+113-1Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const Actions = Reflux.createActions([{
5454
updateOrg: ASYNC_ACTION,
5555
createOrg: ASYNC_ACTION,
5656
updateAiBotSettings: ASYNC_ACTION,
57+
updateAuditSettings: ASYNC_ACTION,
5758
inviteUser: ASYNC_ACTION,
5859
useDemoData: ASYNC_ACTION,
5960
setReportsProject: {},
@@ -114,7 +115,9 @@ const Actions = Reflux.createActions([{
114115
downloadDblabSessionArtifact: ASYNC_ACTION,
115116
sendUserCode: ASYNC_ACTION,
116117
confirmUserEmail: ASYNC_ACTION,
117-
confirmTosAgreement: ASYNC_ACTION
118+
confirmTosAgreement: ASYNC_ACTION,
119+
testSiemServiceConnection: ASYNC_ACTION,
120+
getAuditEvents: ASYNC_ACTION
118121
}]);
119122

120123
function timeoutPromise(ms, promise) {
@@ -654,6 +657,42 @@ Actions.updateAiBotSettings.listen(function (token, orgId, orgData) {
654657
});
655658
});
656659

660+
Actions.updateAuditSettings.listen(function (token, orgId, orgData) {
661+
let action = this;
662+
663+
if (!api) {
664+
settings.init(function () {
665+
api = new Api(settings);
666+
});
667+
}
668+
669+
action.progressed({ orgId } + orgData);
670+
timeoutPromise(REQUEST_TIMEOUT, api.updateAuditSettings(token, orgId, orgData))
671+
672+
.then(result => {
673+
result.json()
674+
.then(json => {
675+
if (json) {
676+
action.completed(json);
677+
} else {
678+
action.failed(new Error('wrong_reply'));
679+
}
680+
})
681+
.catch(err => {
682+
console.error(err);
683+
action.failed(new Error('wrong_reply'));
684+
});
685+
})
686+
.catch(err => {
687+
console.error(err);
688+
if (err && err.message && err.message === 'timeout') {
689+
action.failed(new Error('failed_fetch'));
690+
} else {
691+
action.failed(new Error('wrong_reply'));
692+
}
693+
});
694+
});
695+
657696
Actions.createOrg.listen(function (token, orgData) {
658697
let action = this;
659698

@@ -1571,4 +1610,77 @@ Actions.confirmTosAgreement.listen(function (token) {
15711610
);
15721611
});
15731612

1613+
1614+
Actions.testSiemServiceConnection.listen(function (token, data) {
1615+
let action = this;
1616+
1617+
if (!api) {
1618+
settings.init(function () {
1619+
api = new Api(settings);
1620+
});
1621+
}
1622+
1623+
action.progressed(data);
1624+
timeoutPromise(REQUEST_TIMEOUT, api.testSiemServiceConnection(token, data))
1625+
1626+
.then(result => {
1627+
result.json()
1628+
.then(json => {
1629+
if (json) {
1630+
action.completed(json);
1631+
} else {
1632+
action.failed(new Error('wrong_reply'));
1633+
}
1634+
})
1635+
.catch(err => {
1636+
console.error(err);
1637+
action.failed(new Error('wrong_reply'));
1638+
});
1639+
})
1640+
.catch(err => {
1641+
console.error(err);
1642+
if (err && err.message && err.message === 'timeout') {
1643+
action.failed(new Error('failed_fetch'));
1644+
} else {
1645+
action.failed(new Error('wrong_reply'));
1646+
}
1647+
});
1648+
});
1649+
1650+
Actions.getAuditEvents.listen(function (token) {
1651+
let action = this;
1652+
1653+
if (!api) {
1654+
settings.init(function () {
1655+
api = new Api(settings);
1656+
});
1657+
}
1658+
1659+
action.progressed();
1660+
1661+
timeoutPromise(REQUEST_TIMEOUT, api.getAuditEvents(token))
1662+
.then(result => {
1663+
result.json()
1664+
.then(json => {
1665+
if (json) {
1666+
action.completed({ data: json });
1667+
} else {
1668+
action.failed(new Error('wrong_reply'));
1669+
}
1670+
})
1671+
.catch(err => {
1672+
console.error(err);
1673+
action.failed(new Error('wrong_reply'));
1674+
});
1675+
})
1676+
.catch(err => {
1677+
console.error(err);
1678+
if (err && err.message && err.message === 'timeout') {
1679+
action.failed(new Error('failed_fetch'));
1680+
} else {
1681+
action.failed(new Error('wrong_reply'));
1682+
}
1683+
});
1684+
});
1685+
15741686
export default Actions;

‎ui/packages/platform/src/api/api.js

Copy file name to clipboardExpand all lines: ui/packages/platform/src/api/api.js
+76Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,71 @@ class Api {
467467
});
468468
}
469469

470+
updateAuditSettings(token, orgId, orgData) {
471+
let params = {};
472+
let headers = {
473+
Authorization: 'Bearer ' + token,
474+
prefer: 'return=representation'
475+
};
476+
477+
if (typeof orgData.enableSiemIntegration !== 'undefined') {
478+
params.siem_integration_enabled = orgData.enableSiemIntegration;
479+
}
480+
481+
if (typeof orgData.urlSchema !== 'undefined') {
482+
params.siem_integration_url = orgData.urlSchema;
483+
}
484+
485+
if (typeof orgData.auditEvents !== "undefined") {
486+
params.audit_events_to_log = orgData.auditEvents.map((item) => item.event_name)
487+
}
488+
489+
if (typeof orgData.headers !== 'undefined' && Array.isArray(orgData.headers)) {
490+
orgData.headers = orgData.headers.filter(item => item.key && item.value);
491+
if (Object.keys(orgData.headers).length > 0) {
492+
params.siem_integration_request_headers = orgData.headers.reduce((acc, item) => {
493+
acc[item.key] = item.value;
494+
return acc;
495+
}, {});
496+
} else {
497+
params.siem_integration_request_headers = null
498+
}
499+
}
500+
501+
return this.patch(`${this.apiServer}/orgs?id=eq.` + orgId, params, {
502+
headers: headers
503+
});
504+
}
505+
506+
testSiemServiceConnection(token, data) {
507+
let params = {};
508+
let headers = {
509+
Accept: 'application/vnd.pgrst.object+json',
510+
Authorization: 'Bearer ' + token,
511+
prefer: 'return=representation'
512+
};
513+
514+
if (typeof data.urlSchema !== 'undefined') {
515+
params.api_url = data.urlSchema;
516+
}
517+
518+
if (typeof data.headers !== 'undefined' && Array.isArray(data.headers)) {
519+
data.headers = data.headers.filter(item => item.key && item.value);
520+
if (Object.keys(data.headers).length > 0) {
521+
params.http_headers_extra = data.headers.reduce((acc, item) => {
522+
acc[item.key] = item.value;
523+
return acc;
524+
}, {});
525+
} else {
526+
params.http_headers_extra = null
527+
}
528+
}
529+
530+
return this.post(`${this.apiServer}/rpc/test_siem_connection`, params, {
531+
headers: headers
532+
});
533+
}
534+
470535
inviteUser(token, orgId, email) {
471536
let headers = {
472537
Authorization: 'Bearer ' + token
@@ -992,6 +1057,17 @@ class Api {
9921057
{ headers }
9931058
);
9941059
}
1060+
1061+
getAuditEvents(token) {
1062+
let params = {};
1063+
let headers = {
1064+
Authorization: 'Bearer ' + token
1065+
};
1066+
1067+
return this.get(`${this.apiServer}/audit_events`, params, {
1068+
headers: headers
1069+
});
1070+
}
9951071
}
9961072

9971073
export default Api;

‎ui/packages/platform/src/components/Audit/Audit.tsx

Copy file name to clipboardExpand all lines: ui/packages/platform/src/components/Audit/Audit.tsx
+6-6Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export interface AuditLogData {
5050
action: string
5151
actor: string
5252
action_data: {
53-
processed_rows_count: number
53+
processed_row_count: number
5454
}
5555
created_at: string
5656
table_name: string
@@ -155,11 +155,11 @@ class Audit extends Component<AuditWithStylesProps, AuditState> {
155155
actorSrc = ' (changed directly in database) '
156156
}
157157

158-
if (r.action_data && r.action_data.processed_rows_count) {
158+
if (r.action_data && r.action_data.processed_row_count) {
159159
rows =
160-
r.action_data.processed_rows_count +
160+
r.action_data.processed_row_count +
161161
' ' +
162-
(r.action_data.processed_rows_count > 1 ? 'rows' : 'row')
162+
(r.action_data.processed_row_count > 1 ? 'rows' : 'row')
163163
}
164164

165165
switch (r.action) {
@@ -197,8 +197,8 @@ class Audit extends Component<AuditWithStylesProps, AuditState> {
197197
? r.data_before?.length
198198
: r.data_after?.length
199199
const objCount =
200-
r.action_data && r.action_data.processed_rows_count
201-
? r.action_data.processed_rows_count
200+
r.action_data && r.action_data.processed_row_count
201+
? r.action_data.processed_row_count
202202
: null
203203

204204
if (displayedCount && (objCount as number) > displayedCount) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.