Support using a callback in auth.js config file
This commit is contained in:
1 parent
340016813c
commit
8e34c6a2f6
1 file changed
+66
-53
+66
-53
@@ -49,6 +49,7 @@ util = require 'util'
|
|||||||
URL = require 'url'
|
URL = require 'url'
|
||||||
auth = require './auth'
|
auth = require './auth'
|
||||||
|
|
||||||
|
|
||||||
udpConReq = (address, un, key, callback) ->
|
udpConReq = (address, un, key, callback) ->
|
||||||
[host, port] = address.split(':', 2)
|
[host, port] = address.split(':', 2)
|
||||||
|
|
||||||
@@ -71,8 +72,9 @@ udpConReq = (address, un, key, callback) ->
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
connectionRequest = (deviceId, callback) ->
|
httpConReq = (url, username, password, timeout, callback) ->
|
||||||
# ensure socket is reused in case of digest authentication
|
options = URL.parse(url)
|
||||||
|
# Ensure socket is reused in case of digest authentication
|
||||||
agent = new http.Agent({maxSockets : 1})
|
agent = new http.Agent({maxSockets : 1})
|
||||||
|
|
||||||
statusToError = (statusCode) ->
|
statusToError = (statusCode) ->
|
||||||
@@ -86,34 +88,54 @@ connectionRequest = (deviceId, callback) ->
|
|||||||
else
|
else
|
||||||
new Error("Unexpected response code from device: #{statusCode}")
|
new Error("Unexpected response code from device: #{statusCode}")
|
||||||
|
|
||||||
conReq = (url, authString, callback) ->
|
request = http.get(options, (res) ->
|
||||||
options = URL.parse(url)
|
if res.statusCode == 401 and res.headers['www-authenticate']?
|
||||||
options.agent = agent
|
authHeader = auth.parseAuthHeader(res.headers['www-authenticate'])
|
||||||
|
if authHeader.method is 'Basic'
|
||||||
|
options.headers = {'Authorization' : auth.basic(username, password)}
|
||||||
|
else if authHeader.method is 'Digest'
|
||||||
|
options.headers = {
|
||||||
|
'Authorization' : auth.digest(username, password, options.path, 'GET', null, authHeader)
|
||||||
|
}
|
||||||
|
|
||||||
if authString
|
request = http.get(options, (res) ->
|
||||||
options.headers = {'Authorization' : authString}
|
if res.statusCode == 0
|
||||||
|
# Workaround for some devices unexpectedly closing the connection
|
||||||
request = http.get(options, (res) ->
|
request = http.get(options, (res) ->
|
||||||
if res.statusCode == 401 and res.headers['www-authenticate']?
|
callback(statusToError(res.statusCode))
|
||||||
authHeader = auth.parseAuthHeader(res.headers['www-authenticate'])
|
res.resume()
|
||||||
callback(res.statusCode, authHeader)
|
).on('error', (err) ->
|
||||||
# don't need body, go ahead and emit events to free up the socket for possible reuse
|
request.abort()
|
||||||
res.resume()
|
callback(statusToError(0))
|
||||||
)
|
).on('socket', (socket) ->
|
||||||
|
socket.setTimeout(timeout)
|
||||||
request.on('error', (err) ->
|
socket.on('timeout', () -> request.abort())
|
||||||
# error event when request is aborted
|
)
|
||||||
request.abort()
|
else
|
||||||
callback(0)
|
callback(statusToError(res.statusCode))
|
||||||
)
|
res.resume()
|
||||||
|
).on('error', (err) ->
|
||||||
request.on('socket', (socket) ->
|
|
||||||
socket.setTimeout(2000)
|
|
||||||
socket.on('timeout', () ->
|
|
||||||
request.abort()
|
request.abort()
|
||||||
|
callback(statusToError(0))
|
||||||
|
).on('socket', (socket) ->
|
||||||
|
socket.setTimeout(timeout)
|
||||||
|
socket.on('timeout', () -> request.abort())
|
||||||
)
|
)
|
||||||
)
|
else
|
||||||
|
callback(statusToError(res.statusCode))
|
||||||
|
|
||||||
|
# No listener for data so emit resume
|
||||||
|
res.resume()
|
||||||
|
).on('error', (err) ->
|
||||||
|
request.abort()
|
||||||
|
callback(statusToError(0))
|
||||||
|
).on('socket', (socket) ->
|
||||||
|
socket.setTimeout(timeout)
|
||||||
|
socket.on('timeout', () -> request.abort())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
connectionRequest = (deviceId, callback) ->
|
||||||
proj = {
|
proj = {
|
||||||
'Device.ManagementServer.ConnectionRequestURL._value' : 1,
|
'Device.ManagementServer.ConnectionRequestURL._value' : 1,
|
||||||
'Device.ManagementServer.UDPConnectionRequestAddress._value' : 1,
|
'Device.ManagementServer.UDPConnectionRequestAddress._value' : 1,
|
||||||
@@ -126,9 +148,7 @@ connectionRequest = (deviceId, callback) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
db.devicesCollection.findOne({_id : deviceId}, proj, (err, device)->
|
db.devicesCollection.findOne({_id : deviceId}, proj, (err, device)->
|
||||||
if err
|
return callback(err) if err
|
||||||
callback(err)
|
|
||||||
return
|
|
||||||
|
|
||||||
if device.Device? # TR-181 data model
|
if device.Device? # TR-181 data model
|
||||||
connectionRequestUrl = device.Device.ManagementServer.ConnectionRequestURL._value
|
connectionRequestUrl = device.Device.ManagementServer.ConnectionRequestURL._value
|
||||||
@@ -141,33 +161,26 @@ connectionRequest = (deviceId, callback) ->
|
|||||||
username = device.InternetGatewayDevice.ManagementServer.ConnectionRequestUsername?._value
|
username = device.InternetGatewayDevice.ManagementServer.ConnectionRequestUsername?._value
|
||||||
password = device.InternetGatewayDevice.ManagementServer.ConnectionRequestPassword?._value
|
password = device.InternetGatewayDevice.ManagementServer.ConnectionRequestPassword?._value
|
||||||
|
|
||||||
if not (username and password) and config.auth?.connectionRequest
|
conReq = () ->
|
||||||
[username, password] = config.auth.connectionRequest(deviceId)
|
if udpConnectionRequestAddress
|
||||||
|
udpConReq(udpConnectionRequestAddress, username, password, (err) -> throw err if err)
|
||||||
|
|
||||||
if udpConnectionRequestAddress
|
httpConReq(connectionRequestUrl, username, password, 2000, (err) ->
|
||||||
udpConReq(udpConnectionRequestAddress, username, password, (err) -> throw err if err)
|
if udpConnectionRequestAddress
|
||||||
|
return callback()
|
||||||
|
callback(err)
|
||||||
|
)
|
||||||
|
|
||||||
# for testing
|
if config.auth?.connectionRequest?
|
||||||
#connectionRequestUrl = connectionRequestUrl.replace(/^(http:\/\/)([0-9\.]+)(\:[0-9]+\/[a-zA-Z0-9]+\/?$)/, '$110.1.1.254$3')
|
# Callback is optional for backward compatibility
|
||||||
conReq(connectionRequestUrl, null, (statusCode, authHeader) ->
|
if config.auth.connectionRequest.length > 4
|
||||||
if statusCode == 401
|
return config.auth.connectionRequest(deviceId, connectionRequestUrl, username, password, (u, p) ->
|
||||||
if authHeader.method is 'Basic'
|
username = u
|
||||||
authString = auth.basic(username, password)
|
password = p
|
||||||
else if authHeader.method is 'Digest'
|
conReq()
|
||||||
uri = URL.parse(connectionRequestUrl)
|
|
||||||
authString = auth.digest(username, password, uri.path, 'GET', null, authHeader)
|
|
||||||
|
|
||||||
conReq(connectionRequestUrl, authString, (statusCode, authHeader) ->
|
|
||||||
if statusCode == 0
|
|
||||||
# Workaround for some devices unexpectedly closing the connection
|
|
||||||
return conReq(connectionRequestUrl, authString, (statusCode) -> callback(statusToError(statusCode)))
|
|
||||||
callback(statusToError(statusCode))
|
|
||||||
)
|
)
|
||||||
else if udpConnectionRequestAddress
|
[username, password] = config.auth.connectionRequest(deviceId, connectionRequestUrl, username, password)
|
||||||
return callback()
|
conReq()
|
||||||
else
|
|
||||||
callback(statusToError(statusCode))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user