feat(xo-server-audit): add active setting (default false) (#5151)

This commit is contained in:
Julien Fontanet 2020-07-10 14:29:30 +02:00 committed by GitHub
parent e1bf68ab38
commit f51bcfa05a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 23 deletions

View File

@ -7,6 +7,8 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [Audit] Logging user actions is now opt-in (PR [#5151](https://github.com/vatesfr/xen-orchestra/pull/5151))
### Bug fixes
> Users must be able to say: “I had this issue, happy to know it's fixed”
@ -33,5 +35,6 @@
>
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- xo-server-audit minor
- xo-web patch
- xo-server patch

View File

@ -115,6 +115,16 @@ class Db extends Storage {
}
}
export const configurationSchema = {
type: 'object',
properties: {
active: {
description: 'Whether to save user actions in the audit log',
type: 'boolean',
},
},
}
const NAMESPACE = 'audit'
class AuditXoPlugin {
constructor({ staticConfig, xo }) {
@ -127,6 +137,19 @@ class AuditXoPlugin {
this._auditCore = undefined
this._storage = undefined
this._listeners = {
'xo:audit': this._handleEvent.bind(this),
'xo:postCall': this._handleEvent.bind(this, 'apiCall'),
}
}
configure({ active = false }, { loaded }) {
this._active = active
if (loaded) {
this._addListeners()
}
}
async load() {
@ -139,8 +162,7 @@ class AuditXoPlugin {
this._storage = undefined
})
this._addListener('xo:postCall', this._handleEvent.bind(this, 'apiCall'))
this._addListener('xo:audit', this._handleEvent.bind(this))
this._addListeners()
const exportRecords = this._exportRecords.bind(this)
exportRecords.permission = 'admin'
@ -184,34 +206,44 @@ class AuditXoPlugin {
}
unload() {
this._removeListeners()
this._cleaners.forEach(cleaner => cleaner())
this._cleaners.length = 0
}
_addListener(event, listener_) {
const listener = async (...args) => {
try {
await listener_(...args)
} catch (error) {
log.error(error)
}
_addListeners(event, listener_) {
this._removeListeners()
if (this._active) {
const listeners = this._listeners
Object.keys(listeners).forEach(event => {
this._xo.addListener(event, listeners[event])
})
}
const xo = this._xo
xo.on(event, listener)
this._cleaners.push(() => xo.removeListener(event, listener))
}
_handleEvent(event, { userId, userIp, userName, ...data }) {
if (event !== 'apiCall' || !this._blockedList[data.method]) {
return this._auditCore.add(
{
userId,
userIp,
userName,
},
event,
data
)
_removeListeners() {
const listeners = this._listeners
Object.keys(listeners).forEach(event => {
this._xo.removeListener(event, listeners[event])
})
}
async _handleEvent(event, { userId, userIp, userName, ...data }) {
try {
if (event !== 'apiCall' || !this._blockedList[data.method]) {
return await this._auditCore.add(
{
userId,
userIp,
userName,
},
event,
data
)
}
} catch (error) {
log.error(error)
}
}