# 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