All files / src/middleware basicAuthentication.coffee

48.72% Statements 19/39
16.67% Branches 1/6
0% Functions 0/8
47.37% Lines 18/38
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 811x 1x 1x 1x 1x   1x   1x 1x 1x 1x 1x   1x 1x   1x   1x                 1x             1x                                                                   1x                      
auth = require 'basic-auth'
Q = require "q"
Client = require("../model/clients").Client
logger = require "winston"
crypto = require "crypto"
 
bcrypt = require 'bcryptjs'
 
config = require '../config/config'
statsdServer = config.get 'statsd'
application = config.get 'application'
SDC = require 'statsd-client'
os = require 'os'
 
domain = "#{os.hostname()}.#{application.name}.appMetrics"
sdc = new SDC statsdServer
 
bcryptCompare = (pass, client, callback) -> bcrypt.compare pass, client.passwordHash, callback
 
cryptoCompare = (pass, client, callback) ->
  hash = crypto.createHash client.passwordAlgorithm
  hash.update pass
  hash.update client.passwordSalt
  if hash.digest('hex') == client.passwordHash
    callback null, true
  else
    callback null, false
 
comparePasswordWithClientHash = (pass, client, callback) ->
  if client.passwordAlgorithm in crypto.getHashes()
    cryptoCompare pass, client, callback
  else
    bcryptCompare pass, client, callback
 
 
exports.authenticateUser = (ctx, done) ->
  user = auth ctx
 
  if user
    Client.findOne { clientID: user.name }, (err, client) ->
      return done err if err
 
      if client
        if not (client.passwordAlgorithm and client.passwordHash)
          logger.warn "#{user.name} does not have a basic auth password set"
          return done null, null
 
        comparePasswordWithClientHash user.pass, client, (err, res) ->
          return done err if err
 
          if res
            logger.info "#{user.name} is authenticated."
            ctx.authenticated = client
            ctx.authenticationType = 'basic'
            done null, client
          else
            logger.info "#{user.name} could NOT be authenticated, trying next auth mechanism if any..."
            done null, null
      else
        logger.info "#{user.name} not found, trying next auth mechanism if any..."
        done null, null
  else
    logger.info "No basic auth details supplied, trying next auth mechanism if any..."
    ctx.authenticated = null # Set to empty object rather than null
    done null, null
 
###
# Koa middleware for authentication by basic auth
###
exports.koaMiddleware = (next) ->
  startTime = new Date() if statsdServer.enabled
  if this.authenticated?
    yield next
  else
    authenticateUser = Q.denodeify exports.authenticateUser
    yield authenticateUser this
    if this.authenticated?.clientID?
      this.header['X-OpenHIM-ClientID'] = this.authenticated.clientID
    sdc.timing "#{domain}.basicAuthMiddleware", startTime if statsdServer.enabled
    yield next