Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Digest and Bearer Auth modes to http request node #2061

Merged
merged 11 commits into from Feb 27, 2019
Merged

Add Digest and Bearer Auth modes to http request node #2061

merged 11 commits into from Feb 27, 2019

Conversation

bartbutenaers
Copy link
Contributor

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Proposed changes

As discussed on the forum, this PR introduces Digest and Bearer authentication for the HttpRequest node.

Following flow can be used to test the 3 authentication methods:

image

[{"id":"4b680d8d.3dce74","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":320,"wires":[["f97dcb19.a8faf8"]]},{"id":"4f3f587b.9fb988","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":320,"wires":[]},{"id":"a6c3b589.da0e48","type":"comment","z":"dc82a538.a81ba8","name":"Digest authentication without credentials => 401 (Unauthorised)","info":"","x":550,"y":280,"wires":[]},{"id":"8c9ec024.38585","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":420,"wires":[["881fe2e2.7ece7"]]},{"id":"3e0812f7.a99f2e","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":420,"wires":[]},{"id":"7d22c59f.eb794c","type":"comment","z":"dc82a538.a81ba8","name":"Digest authentication with credentials => 200 (Success)","info":"","x":520,"y":380,"wires":[]},{"id":"5406fbb0.bb9ad4","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":80,"wires":[["72aa922d.2a18ec"]]},{"id":"4c1678ed.1b7fd8","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":80,"wires":[]},{"id":"3169ca53.c12056","type":"comment","z":"dc82a538.a81ba8","name":"Basic authentication without credentials => 401 (Unauthorised)","info":"","x":540,"y":40,"wires":[]},{"id":"f8475555.ddd588","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":180,"wires":[["4e9922b0.a168dc"]]},{"id":"5b2bd581.f7be4c","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":180,"wires":[]},{"id":"74a30db0.2b16a4","type":"comment","z":"dc82a538.a81ba8","name":"Basic authentication with credentials => 200 (Success)","info":"","x":520,"y":140,"wires":[]},{"id":"e7e6355a.9fcef8","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":560,"wires":[["2c956c46.61fa44"]]},{"id":"3697ab96.bc85f4","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":560,"wires":[]},{"id":"3670c9ce.cc0e96","type":"comment","z":"dc82a538.a81ba8","name":"Bearer authentication without credentials => 401 (Unauthorised)","info":"","x":550,"y":520,"wires":[]},{"id":"992b6a57.21c7a8","type":"inject","z":"dc82a538.a81ba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":660,"wires":[["5332b98c.86f338"]]},{"id":"e413a9f2.988888","type":"debug","z":"dc82a538.a81ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":660,"wires":[]},{"id":"9e267fc6.9edf","type":"comment","z":"dc82a538.a81ba8","name":"Bearer authentication with credentials => 200 (Success)","info":"","x":520,"y":620,"wires":[]},{"id":"72aa922d.2a18ec","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/basic-auth/myuser/mypasswd","tls":"","proxy":"","authType":"basic","x":570,"y":80,"wires":[["4c1678ed.1b7fd8"]]},{"id":"4e9922b0.a168dc","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/basic-auth/myuser/mypasswd","tls":"","proxy":"","authType":"basic","x":570,"y":180,"wires":[["5b2bd581.f7be4c"]]},{"id":"f97dcb19.a8faf8","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/digest-auth/auth/myuser/mypasswd","tls":"","proxy":"","authType":"digest","x":570,"y":320,"wires":[["4f3f587b.9fb988"]]},{"id":"881fe2e2.7ece7","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/digest-auth/auth/myuser/mypasswd","tls":"","proxy":"","authType":"digest","x":570,"y":420,"wires":[["3e0812f7.a99f2e"]]},{"id":"2c956c46.61fa44","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/bearer","tls":"","proxy":"","authType":"bearer","x":570,"y":560,"wires":[["3697ab96.bc85f4"]]},{"id":"5332b98c.86f338","type":"http request","z":"dc82a538.a81ba8","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://httpbin.org/bearer","tls":"","proxy":"","authType":"bearer","x":570,"y":660,"wires":[["e413a9f2.988888"]]}]

All 6 tests in this flow make use of httpbin.org, which offers endpoints for all 3 authentication methods.

  1. Test basic authentication without credentials, which results in 401 (Unauthorised).
  2. Test basic authentication with credentials, which results in 200. Don't forget to specify username 'myuser' and password 'mypasswd'.
  3. Test digest authentication without credentials, which results in 401 (Unauthorised).
  4. Test digest authentication with credentials, which results in 200. Don't forget to specify username 'myuser' and password 'mypasswd'.
  5. Test bearer authentication without credentials, which results in 401 (Unauthorised).
  6. Test bearer authentication with credentials, which results in 200. Don't forget to specify some (random) token.

I have tried to have no impact on existing http-request nodes, i.e. nodes that have been created with a previous version. I have tested this by adding a few http-request nodes to my flow (with the previous version), and afterwards I have installed this new version:

  • When the config screen is opened, then basic authentication will be displayed automatically (when credentials are available and authType is undefined):
    image
  • When the config screen hasn't been opened, and an input message arrives (but no credentials are available):
    image
    No credentials will be set (i.e. we won't arrive at line 183), since there is no username. This is the same logic as in the previous version.
  • When the config screen hasn't been opened, and an input message arrives (and credentials are available):
    image
    The credentials will be set (i.e. we will arrive at line 183): indeed I treat empty authType (in case credentials are available) as 'basic' authentication.

Thanks for reviewing this PR !!!!
Bart

Checklist

  • I have read the contribution guidelines
  • For non-bugfix PRs, I have discussed this change on the mailing list/slack team.
  • I have run grunt to verify the unit tests pass
  • I have added suitable unit tests to cover the new/changed functionality

@dceejay dceejay changed the title Dev Add DIgest and Bearer Auth modes to http request node Feb 19, 2019
Copy link
Member

@dceejay dceejay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Bart , couple of thoughts... the way you have it works just some small style points :-)

<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="common.label.password"></span></label>
<input type="password" id="node-input-password">
</div>
<div class="form-row node-input-bearer-row hide">
<label for="node-input-bearerToken"><i class="fa fa-lock"></i> <span data-i18n="httpin.label.bearerToken"></span></label>
Copy link
Member

@dceejay dceejay Feb 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Bart - any reason not to re-use the password field as it is effectively the same - and you can't have both :-) It makes some of the following logic slightly easier as you don't then need to re-merge either this or that, test for both, etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Dave (@dceejay),
I have been thinking the same, but I introduced a new token field because I thought you guys wouldn't like me to use the same field for two different purposes. I can indeed re-use the password field if you like. But is it allowed to change the 'password' label to 'token' (as soon as bearer authentication is selected)? Or do you always want the label to be 'password'??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the field can be the same as it's serving effectively the same purpose - the label can be different as the word token is more appropriate in that context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Dave (@dceejay),
I have changed and tested everything, except from the dynamically changed label.
Do you have any advice on how that can be done easily?

<label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="common.label.password"></span></label>
<input type="password" id="node-input-password">

So it should become "common.label.bearerToken" ...
Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you use the same .show() .hide() technique as before ?
hmm - not sure bearerToken is that "common" so it probably ought to be in "httpin.label.bearerToken"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dceejay,
Do you mean two label tags pointing to the same input element? Or two span tags into a single label?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dave,
my time is up for this evening ...

Seems that an input tag is allowed to have multiple labels.
I added a last code snippet to switch between two labels, but the layout is not what I expected:

token_label

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of two labels - have one label tag with two more span tags inside - give each span the id you want to show/hide. (they then each have the <i... icon> and inside.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evening Dave (@dceejay),

With the two span elements it indeed looks better now:

bearer_token

I think all your feedback is implemented.
Is it ok, or does the House of Commons need to vote now?

Bart

@@ -33,6 +33,7 @@ module.exports = function(RED) {
var tlsNode = RED.nodes.getNode(n.tls);
}
this.ret = n.ret || "txt";
this.authType = n.authType;
Copy link
Member

@dceejay dceejay Feb 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally we usually force the default here (as per line 35 above) - again making the following logic then just need to handle the new paths

this.authType = n.authType || "basic";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Dave (@dceejay),
I had it like you say in my first version, but I rewrote it since I had to know (further in the code) whether it was undefined (i.e. version < 0.20.x). But in the current implementation that isn't required anymore. So I will change and test it this evening ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks - look forward to merging it tomorrow !

@bartbutenaers bartbutenaers changed the title Add DIgest and Bearer Auth modes to http request node Add Digest and Bearer Auth modes to http request node Feb 19, 2019
@coveralls
Copy link

coveralls commented Feb 19, 2019

Coverage Status

Coverage decreased (-0.07%) to 76.367% when pulling 44b7478 on bartbutenaers:dev into 9d673a2 on node-red:dev.

@dceejay
Copy link
Member

dceejay commented Feb 21, 2019

@knolleary - Looks all good to me. Can you give the once over and merge ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants