From d8f2f24b44863cefaefc0475132c5051450fccee Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 19 Feb 2014 20:31:42 +0000 Subject: [PATCH] Add optional basic-auth to HTTP Request node Closes #160 --- nodes/core/io/21-httpin.html | 83 +++++++++++++++++++++++++++++++++++- nodes/core/io/21-httpin.js | 49 +++++++++++++++++++++ public/red/ui/editor.js | 5 ++- 3 files changed, 135 insertions(+), 2 deletions(-) diff --git a/nodes/core/io/21-httpin.html b/nodes/core/io/21-httpin.html index 9be7d5a60..4756aed23 100644 --- a/nodes/core/io/21-httpin.html +++ b/nodes/core/io/21-httpin.html @@ -160,6 +160,19 @@ +
+ + + +
+
+ + +
+
+ + +
@@ -193,7 +206,9 @@ defaults: { name: {value:""}, method:{value:"GET"}, - url:{value:""} + url:{value:""}, + //user -> credentials + //pass -> credentials }, inputs:1, outputs:1, @@ -204,6 +219,72 @@ }, labelStyle: function() { return this.name?"node_label_italic":""; + }, + oneditprepare: function() { + $.getJSON('http-request/'+this.id,function(data) { + if (data.user) { + $('#node-input-useAuth').prop('checked', true); + $(".node-input-useAuth-row").show(); + $('#node-config-input-user').data("v",data.user); + $('#node-config-input-user').val(data.user); + } else { + $('#node-input-useAuth').prop('checked', false); + $(".node-input-useAuth-row").hide(); + $('#node-config-input-user').data("v",''); + } + if (data.hasPassword) { + $('#node-input-useAuth').prop('checked', true); + $(".node-input-useAuth-row").show(); + $('#node-config-input-pass').data("v",'__PWRD__'); + $('#node-config-input-pass').val('__PWRD__'); + } else { + $('#node-config-input-pass').data("v",''); + $('#node-config-input-pass').val(''); + } + + }); + + $("#node-input-useAuth").change(function() { + if ($(this).is(":checked")) { + $(".node-input-useAuth-row").show(); + } else { + $(".node-input-useAuth-row").hide(); + } + }); + }, + oneditsave: function() { + var oldUser = $('#node-config-input-user').data("v"); + var oldPass = $('#node-config-input-pass').data("v"); + var newUser = $('#node-config-input-user').val(); + var newPass = $('#node-config-input-pass').val(); + + if (!$("#node-input-useAuth").is(":checked")) { + newUser = ""; + newPass = ""; + } + + if (oldUser != newUser || oldPass != newPass) { + if (newUser == "" && newPass == "") { + $.ajax({ + url: 'http-request/'+this.id, + type: 'DELETE', + success: function(result) {} + }); + } else { + var credentials = {}; + credentials.user = newUser; + if (newPass != '__PWRD__') { + credentials.password = newPass; + } + $.ajax({ + url: 'http-request/'+this.id, + type: 'POST', + data: credentials, + success:function(result){} + }); + } + return true; + } } }); diff --git a/nodes/core/io/21-httpin.js b/nodes/core/io/21-httpin.js index 557d30b96..1c213003f 100644 --- a/nodes/core/io/21-httpin.js +++ b/nodes/core/io/21-httpin.js @@ -130,6 +130,11 @@ function HTTPRequest(n) { var nodeUrl = n.url; var nodeMethod = n.method || "GET"; var node = this; + var credentials = RED.nodes.getCredentials(n.id); + if (credentials) { + this.username = credentials.user; + this.password = credentials.password; + } this.on("input",function(msg) { var url = msg.url||nodeUrl; @@ -139,6 +144,9 @@ function HTTPRequest(n) { if (msg.headers) { opts.headers = msg.headers; } + if (credentials) { + opts.auth = credentials.user+":"+credentials.password; + } var req = ((/^https/.test(url))?https:http).request(opts,function(res) { res.setEncoding('utf8'); msg.statusCode = res.statusCode; @@ -172,3 +180,44 @@ function HTTPRequest(n) { } RED.nodes.registerType("http request",HTTPRequest); + +var querystring = require('querystring'); + +RED.httpAdmin.get('/http-request/:id',function(req,res) { + var credentials = RED.nodes.getCredentials(req.params.id); + if (credentials) { + res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")})); + } else { + res.send(JSON.stringify({})); + } +}); + +RED.httpAdmin.delete('/http-request/:id',function(req,res) { + RED.nodes.deleteCredentials(req.params.id); + res.send(200); +}); + +RED.httpAdmin.post('/http-request/:id',function(req,res) { + var body = ""; + req.on('data', function(chunk) { + body+=chunk; + }); + req.on('end', function(){ + var newCreds = querystring.parse(body); + var credentials = RED.nodes.getCredentials(req.params.id)||{}; + if (newCreds.user == null || newCreds.user == "") { + delete credentials.user; + } else { + credentials.user = newCreds.user; + } + if (newCreds.password == "") { + delete credentials.password; + } else { + credentials.password = newCreds.password||credentials.password; + } + RED.nodes.addCredentials(req.params.id,credentials); + res.send(200); + }); +}); + + diff --git a/public/red/ui/editor.js b/public/red/ui/editor.js index 0117ad755..73ce15f8c 100644 --- a/public/red/ui/editor.js +++ b/public/red/ui/editor.js @@ -160,7 +160,10 @@ RED.editor = function() { oldValues[d] = $.extend(true,{},{v:editing_node[d]}).v; } } - editing_node._def.oneditsave.call(editing_node); + var rc = editing_node._def.oneditsave.call(editing_node); + if (rc === true) { + changed = true; + } for (var d in editing_node._def.defaults) { if (oldValues[d] === null || typeof oldValues[d] === "string" || typeof oldValues[d] === "number") {