UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

477 lines (476 loc) 18 kB
<!doctype html> <html lang="en"> <head> <title>Code coverage report for src/middleware/requestMatching.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/middleware</a> requestMatching.coffee </h1> <div class='clearfix'> <div class='fl pad1y space-right2'> <span class="strong">42.35% </span> <span class="quiet">Statements</span> <span class='fraction'>36/85</span> </div> <div class='fl pad1y space-right2'> <span class="strong">6.25% </span> <span class="quiet">Branches</span> <span class='fraction'>1/16</span> </div> <div class='fl pad1y space-right2'> <span class="strong">0% </span> <span class="quiet">Functions</span> <span class='fraction'>0/16</span> </div> <div class='fl pad1y space-right2'> <span class="strong">41.67% </span> <span class="quiet">Lines</span> <span class='fraction'>35/84</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</td><td class="line-coverage quiet"><span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-no">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-neutral">&nbsp;</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-yes">2x</span> <span class="cline-any cline-neutral">&nbsp;</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" >Q = require "q"</span></span> xpath = require "xpath" dom = require("xmldom").DOMParser logger = require "winston" config = require '../config/config' utils = require '../utils' auditing = require '../auditing' Channels = require('../model/channels') Channel = Channels.Channel &nbsp; statsdServer = config.get 'statsd' application = config.get 'application' himSourceID = config.get('auditing').auditEvents.auditSourceID SDC = require 'statsd-client' os = require 'os' &nbsp; domain = "#{os.hostname()}.#{application.name}.appMetrics" sdc = new SDC statsdServer &nbsp; matchContent = <span class="fstat-no" title="function not covered" >(</span>channel, ctx) -&gt; if channel.matchContentRegex <span class="cstat-no" title="statement not covered" > return matchRegex channel.matchContentRegex, ctx.body</span> else if channel.matchContentXpath and channel.matchContentValue <span class="cstat-no" title="statement not covered" > return matchXpath channel.matchContentXpath, channel.matchContentValue, ctx.body</span> else if channel.matchContentJson and channel.matchContentValue <span class="cstat-no" title="statement not covered" > return matchJsonPath channel.matchContentJson, channel.matchContentValue, ctx.body</span> else if channel.matchContentXpath or channel.matchContentJson # if only the match expression is given, deny access # this is an invalid channel <span class="cstat-no" title="statement not covered" > logger.error "Channel with name '#{channel.name}' is invalid as it has a content match expression but no value to match"</span> <span class="cstat-no" title="statement not covered" > return false</span> else <span class="cstat-no" title="statement not covered" > return true</span> &nbsp; matchRegex = <span class="fstat-no" title="function not covered" >(</span>regexPat, body) -&gt; <span class="cstat-no" title="statement not covered" > regex = new R</span>egExp regexPat <span class="cstat-no" title="statement not covered" > return r</span>egex.test body.toString() &nbsp; matchXpath = <span class="fstat-no" title="function not covered" >(</span>xpathStr, val, xml) -&gt; <span class="cstat-no" title="statement not covered" > doc = new d</span>om().parseFromString(xml.toString()) <span class="cstat-no" title="statement not covered" > xpathVal = x</span>path.select(xpathStr, doc).toString() <span class="cstat-no" title="statement not covered" > return val == x</span>pathVal &nbsp; matchJsonPath = <span class="fstat-no" title="function not covered" >(</span>jsonPath, val, json) -&gt; <span class="cstat-no" title="statement not covered" > jsonObj = J</span>SON.parse json.toString() <span class="cstat-no" title="statement not covered" > jsonVal = g</span>etJSONValByString jsonObj, jsonPath <span class="cstat-no" title="statement not covered" > return val == j</span>sonVal.toString() &nbsp; # taken from http://stackoverflow.com/a/6491621/588776 # readbility improved from the stackoverflow answer getJSONValByString = <span class="fstat-no" title="function not covered" >(</span>jsonObj, jsonPath) -&gt; <span class="cstat-no" title="statement not covered" > jsonPath = j</span>sonPath.replace(/\[(\w+)\]/g, '.$1') # convert indexes to properties <span class="cstat-no" title="statement not covered" > jsonPath = j</span>sonPath.replace(/^\./, '') # strip a leading dot <span class="cstat-no" title="statement not covered" > parts = j</span>sonPath.split('.') <span class="cstat-no" title="statement not covered" > while parts.length</span> <span class="cstat-no" title="statement not covered" > part = p</span>arts.shift() if part of jsonObj <span class="cstat-no" title="statement not covered" > jsonObj = jsonObj[part]</span> else <span class="cstat-no" title="statement not covered" > return</span> <span class="cstat-no" title="statement not covered" > return j</span>sonObj &nbsp; extractContentType = <span class="fstat-no" title="function not covered" >(</span>ctHeader) -&gt; <span class="cstat-no" title="statement not covered" > index = c</span>tHeader.indexOf ';' if index isnt -1 <span class="cstat-no" title="statement not covered" > return ctHeader.substring(0, index).trim()</span> else <span class="cstat-no" title="statement not covered" > return ctHeader.trim()</span> &nbsp; matchUrlPattern = <span class="fstat-no" title="function not covered" >(</span>channel, ctx) -&gt; <span class="cstat-no" title="statement not covered" > pat = new R</span>egExp channel.urlPattern <span class="cstat-no" title="statement not covered" > return p</span>at.test ctx.request.path &nbsp; matchContentTypes = <span class="fstat-no" title="function not covered" >(</span>channel, ctx) -&gt; if channel.matchContentTypes?.length &gt; 0 <span class="cstat-no" title="statement not covered" > if ctx.request.header and ctx.request.header['content-type']</span> <span class="cstat-no" title="statement not covered" > ct = e</span>xtractContentType ctx.request.header['content-type'] <span class="cstat-no" title="statement not covered" > if ct in channel.matchContentTypes</span> <span class="cstat-no" title="statement not covered" > return true</span> else # deny access to channel if the content type doesnt match <span class="cstat-no" title="statement not covered" > return false</span> else # deny access to channel if the content type isnt set <span class="cstat-no" title="statement not covered" > return false</span> else <span class="cstat-no" title="statement not covered" > return true # don't match on content type if this channel doesn't require it</span> &nbsp; matchFunctions = [ matchUrlPattern, matchContent, matchContentTypes ] &nbsp; matchChannel = <span class="fstat-no" title="function not covered" >(</span>channel, ctx) -&gt; matchFunctions.every <span class="fstat-no" title="function not covered" >(</span>matchFunc) -&gt; <span class="cstat-no" title="statement not covered" > return m</span>atchFunc channel, ctx &nbsp; findMatchingChannel = <span class="fstat-no" title="function not covered" >(</span>channels, ctx) -&gt; <span class="cstat-no" title="statement not covered" > return c</span>hannels.find <span class="fstat-no" title="function not covered" >(</span>channel) -&gt; <span class="cstat-no" title="statement not covered" > return m</span>atchChannel channel, ctx &nbsp; matchRequest = <span class="fstat-no" title="function not covered" >(</span>ctx, done) -&gt; utils.getAllChannelsInPriorityOrder <span class="fstat-no" title="function not covered" >(</span>err, channels) -&gt; if err <span class="cstat-no" title="statement not covered" > ctx.response.status = 5</span>00 <span class="cstat-no" title="statement not covered" > logger.error 'Could not fetch OpenHIM channels', err</span> <span class="cstat-no" title="statement not covered" > return done()</span> &nbsp; <span class="cstat-no" title="statement not covered" > channels = c</span>hannels.filter Channels.isChannelEnabled &nbsp; <span class="cstat-no" title="statement not covered" > match = f</span>indMatchingChannel channels, ctx done null, match &nbsp; exports.koaMiddleware = <span class="fstat-no" title="function not covered" >(</span>next) -&gt; <span class="cstat-no" title="statement not covered" ></span> startTime = new Date() if statsdServer.enabled <span class="cstat-no" title="statement not covered" > matchReq = Q</span>.denodeify matchRequest <span class="cstat-no" title="statement not covered" > match = y</span>ield matchReq this &nbsp; if match? <span class="cstat-no" title="statement not covered" > logger.info "The channel that matches the request #{this.request.path} is: #{match.name}"</span> <span class="cstat-no" title="statement not covered" > this.matchingChannel = match</span> else <span class="cstat-no" title="statement not covered" > logger.info "No channel matched the request #{this.request.path}"</span> &nbsp; <span class="cstat-no" title="statement not covered" ></span> sdc.timing "#{domain}.authorisationMiddleware", startTime if statsdServer.enabled yield next &nbsp; # export private functions for unit testing # note: you cant spy on these method because of this :( if process.env.NODE_ENV == "test" exports.matchContent = matchContent exports.matchRegex = matchRegex exports.matchXpath = matchXpath exports.matchJsonPath = matchJsonPath exports.extractContentType = extractContentType exports.matchRequest = matchRequest &nbsp;</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>