openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
543 lines (542 loc) • 22.5 kB
HTML
<html lang="en">
<head>
<title>Code coverage report for src/auditing.coffee</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../prettify.css" />
<link rel="stylesheet" href="../base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="../index.html">All files</a> / <a href="index.html">src</a> auditing.coffee
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">26.58% </span>
<span class="quiet">Statements</span>
<span class='fraction'>21/79</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">2.7% </span>
<span class="quiet">Branches</span>
<span class='fraction'>1/37</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/28</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">27.78% </span>
<span class="quiet">Lines</span>
<span class='fraction'>20/72</span>
</div>
</div>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160</td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js"><span class="fstat-no" title="function not covered" ><span class="branch-1 cbranch-no" title="branch not covered" >logger = require 'winston'</span></span>
syslogParser = require('glossy').Parse
parseString = require('xml2js').parseString
firstCharLowerCase = require('xml2js').processors.firstCharLowerCase
Audit = require('./model/audits').Audit
AuditMeta = require('./model/audits').AuditMeta
tlsAuthentication = require "./middleware/tlsAuthentication"
dgram = require 'dgram'
tls = require 'tls'
net = require 'net'
config = require "./config/config"
config.auditing = config.get('auditing')
parseAuditRecordFromXML = <span class="fstat-no" title="function not covered" >(</span>xml, callback) ->
# DICOM mappers
<span class="cstat-no" title="statement not covered" > csdCodeToCode = <span class="fstat-no" title="function not covered" >(</span></span>name) -> if name is 'csd-code' then 'code' else name
<span class="cstat-no" title="statement not covered" > originalTextToDisplayName = <span class="fstat-no" title="function not covered" >(</span></span>name) -> if name is 'originalText' then 'displayName' else name
options =
mergeAttrs: true,
explicitArray: false
tagNameProcessors: [firstCharLowerCase]
attrNameProcessors: [firstCharLowerCase, csdCodeToCode, originalTextToDisplayName]
parseString xml, options, <span class="fstat-no" title="function not covered" >(</span>err, result) ->
<span class="cstat-no" title="statement not covered" ></span> return callback err if err
if not result?.auditMessage
<span class="cstat-no" title="statement not covered" > return callback new Error 'Document is not a valid AuditMessage'</span>
<span class="cstat-no" title="statement not covered" > audit = {</span>}
if result.auditMessage.eventIdentification
<span class="cstat-no" title="statement not covered" > audit.eventIdentification = result.auditMessage.eventIdentification</span>
<span class="cstat-no" title="statement not covered" > audit.activeParticipant = [</span>]
if result.auditMessage.activeParticipant
# xml2js will only use an array if multiple items exist (explicitArray: false), else it's an object
<span class="cstat-no" title="statement not covered" > if result.auditMessage.activeParticipant instanceof Array</span>
<span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" > for ap in result.auditMessage.activeParticipant</span></span>
<span class="cstat-no" title="statement not covered" > audit.activeParticipant.push ap</span>
else
<span class="cstat-no" title="statement not covered" > audit.activeParticipant.push result.auditMessage.activeParticipant</span>
if result.auditMessage.auditSourceIdentification
<span class="cstat-no" title="statement not covered" > audit.auditSourceIdentification = result.auditMessage.auditSourceIdentification</span>
<span class="cstat-no" title="statement not covered" > audit.participantObjectIdentification = [</span>]
if result.auditMessage.participantObjectIdentification
# xml2js will only use an array if multiple items exist (explicitArray: false), else it's an object
<span class="cstat-no" title="statement not covered" > if result.auditMessage.participantObjectIdentification instanceof Array</span>
<span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" > for poi in result.auditMessage.participantObjectIdentification</span></span>
<span class="cstat-no" title="statement not covered" > audit.participantObjectIdentification.push poi</span>
else
<span class="cstat-no" title="statement not covered" > audit.participantObjectIdentification.push result.auditMessage.participantObjectIdentification</span>
callback null, audit
codeInArray = <span class="fstat-no" title="function not covered" >(</span>code, arr) -> (code in arr.map <span class="fstat-no" title="function not covered" >(</span>a) -> a.code)
exports.processAuditMeta = processAuditMeta = <span class="fstat-no" title="function not covered" >(</span>audit, callback) ->
AuditMeta.findOne {}, <span class="fstat-no" title="function not covered" >(</span>err, auditMeta) ->
if err
<span class="cstat-no" title="statement not covered" > logger.error err</span>
<span class="cstat-no" title="statement not covered" > return callback()</span>
i</span>f not auditMeta then <span class="cstat-no" title="statement not covered" >auditMeta = new AuditMeta()
if audit.eventIdentification?.eventTypeCode?.code and not codeInArray audit.eventIdentification.eventTypeCode.code, auditMeta.eventType
<span class="cstat-no" title="statement not covered" > auditMeta.eventType.push audit.eventIdentification.eventTypeCode</span>
if audit.eventIdentification?.eventID?.code and not codeInArray audit.eventIdentification.eventID.code, auditMeta.eventID
<span class="cstat-no" title="statement not covered" > auditMeta.eventID.push audit.eventIdentification.eventID</span>
if audit.activeParticipant
<span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" > for activeParticipant in audit.activeParticipant</span></span>
if activeParticipant.roleIDCode?.code and not codeInArray activeParticipant.roleIDCode.code, auditMeta.activeParticipantRoleID
<span class="cstat-no" title="statement not covered" > auditMeta.activeParticipantRoleID.push activeParticipant.roleIDCode</span>
if audit.participantObjectIdentification
<span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" > for participantObject in audit.participantObjectIdentification</span></span>
if participantObject.participantObjectIDTypeCode?.code and not codeInArray participantObject.participantObjectIDTypeCode.code, auditMeta.participantObjectIDTypeCode
<span class="cstat-no" title="statement not covered" > auditMeta.participantObjectIDTypeCode.push participantObject.participantObjectIDTypeCode</span>
if audit.auditSourceIdentification?.auditSourceID and audit.auditSourceIdentification.auditSourceID not in auditMeta.auditSourceID
<span class="cstat-no" title="statement not covered" > auditMeta.auditSourceID.push audit.auditSourceIdentification.auditSourceID</span>
auditMeta.save <span class="fstat-no" title="function not covered" >(</span>err) ->
i</span>f err then <span class="cstat-no" title="statement not covered" >logger.error err
callback()
exports.processAudit = processAudit = <span class="fstat-no" title="function not covered" >(</span>msg, <span class="cstat-no" title="statement not covered" >callback=(<span class="fstat-no" title="function not covered" ></span></span>->)) ->
<span class="cstat-no" title="statement not covered" > parsedMsg = s</span>yslogParser.parse(msg)
if not parsedMsg or not parsedMsg.message
<span class="cstat-no" title="statement not covered" > logger.info 'Invalid message received'</span>
<span class="cstat-no" title="statement not covered" > return callback()</span>
parseAuditRecordFromXML parsedMsg.message, <span class="fstat-no" title="function not covered" >(</span>xmlErr, result) ->
<span class="cstat-no" title="statement not covered" > audit = new A</span>udit result
<span class="cstat-no" title="statement not covered" > audit.rawMessage = m</span>sg
<span class="cstat-no" title="statement not covered" > audit.syslog = p</span>arsedMsg
<span class="cstat-no" title="statement not covered" > delete audit.syslog.o</span>riginalMessage
<span class="cstat-no" title="statement not covered" > delete audit.syslog.m</span>essage
audit.save <span class="fstat-no" title="function not covered" >(</span>saveErr) ->
i</span>f saveErr then <span class="cstat-no" title="statement not covered" >logger.error "An error occurred while processing the audit entry: #{saveErr}"
i</span>f xmlErr then <span class="cstat-no" title="statement not covered" >logger.info "Failed to parse message as an AuditMessage XML document: #{xmlErr}"
processAuditMeta audit, callback
sendUDPAudit = <span class="fstat-no" title="function not covered" >(</span>msg, callback) ->
<span class="cstat-no" title="statement not covered" > client = d</span>gram.createSocket('udp4')
client.send msg, 0, msg.length, config.auditing.auditEvents.port, config.auditing.auditEvents.host, <span class="fstat-no" title="function not covered" >(</span>err) ->
<span class="cstat-no" title="statement not covered" > client.close()</span>
callback err
sendTLSAudit = <span class="fstat-no" title="function not covered" >(</span>msg, callback) ->
tlsAuthentication.getServerOptions true, <span class="fstat-no" title="function not covered" >(</span>err, options) ->
<span class="cstat-no" title="statement not covered" ></span> return callback err if err
<span class="cstat-no" title="statement not covered" > client = t</span>ls.connect config.auditing.auditEvents.port, config.auditing.auditEvents.host, options, <span class="fstat-no" title="function not covered" ></span>->
i</span>f not client.authorized then <span class="cstat-no" title="statement not covered" >return callback client.authorizationError
<span class="cstat-no" title="statement not covered" > client.write "#{msg.length} #{msg}"</span>
client.end()
<span class="cstat-no" title="statement not covered" > client.on 'error', <span class="fstat-no" title="function not covered" >(</span>err) -> logger.error err</span>
client.on 'close', <span class="fstat-no" title="function not covered" ></span>-> callback()
sendTCPAudit = <span class="fstat-no" title="function not covered" >(</span>msg, callback) ->
<span class="cstat-no" title="statement not covered" > client = n</span>et.connect config.auditing.auditEvents.port, config.auditing.auditEvents.host, <span class="fstat-no" title="function not covered" ></span>->
<span class="cstat-no" title="statement not covered" > client.write "#{msg.length} #{msg}"</span>
client.end()
<span class="cstat-no" title="statement not covered" > client.on 'error', <span class="fstat-no" title="function not covered" >(</span>err) -> logger.error</span>
client.on 'close', <span class="fstat-no" title="function not covered" ></span>-> callback()
# Send an audit event
exports.sendAuditEvent = <span class="fstat-no" title="function not covered" >(</span>msg, <span class="cstat-no" title="statement not covered" >callback=(<span class="fstat-no" title="function not covered" ></span></span>->)) ->
<span class="cstat-no" title="statement not covered" > done = <span class="fstat-no" title="function not covered" >(</span></span>err) ->
i</span>f err then <span class="cstat-no" title="statement not covered" >logger.error err
callback()
if not config.auditing?.auditEvents?
<span class="cstat-no" title="statement not covered" > return done new Error 'Unable to record audit event: Missing config.auditing.auditEvents'</span>
<span class="cstat-no" title="statement not covered" > switch config.auditing.auditEvents.interface</span>
when 'internal' then processAudit msg, done
when 'udp' then sendUDPAudit msg, done
when 'tls' then sendTLSAudit msg, done
when 'tcp' then sendTCPAudit msg, done
else done new Error "Invalid audit event interface '#{config.auditing.auditEvents.interface}'"
</pre></td></tr>
</table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="http://istanbul-js.org/" target="_blank">istanbul</a> at Mon Oct 10 2016 13:39:22 GMT+0200 (SAST)
</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>