Skip to content

Commit a711071

Browse files
committed
Add fixed oauth node (disabled)
1 parent b337e12 commit a711071

6 files changed

Lines changed: 338 additions & 1 deletion

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"oauth2": {
3+
"oauth2": "oauth2",
4+
"label": {
5+
"grant_type": "Grant Type",
6+
"name": "Name",
7+
"container": "Container",
8+
"access_token_url": "Access Token URL",
9+
"username": "Username",
10+
"password": "Password",
11+
"client_id": "Client ID",
12+
"client_secret": "Client Secret",
13+
"scope": "Scope"
14+
},
15+
"placeholder": {
16+
"name": "oauth2",
17+
"access_token_url": "http://exemplo.com/oauth/token",
18+
"username": "admin",
19+
"password": "admin",
20+
"client_id": "012493af6282be51660dbc8e21a8462e",
21+
"client_secret": "5621bd4b5a8b09ed31817efb8d54fda2c72bfc1c6968cd4563d83f7cc26f68f6",
22+
"scope": "scope"
23+
},
24+
"opts": {
25+
"client_credentials": "Client Credentials",
26+
"password_credentials": "Password",
27+
"set_by_credentials": "- Set by msg.oauth2Request -"
28+
}
29+
}
30+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<script type="text/javascript">
2+
RED.nodes.registerType("oauth2", {
3+
category: 'security',
4+
color: "#a6bbcf",
5+
defaults: {
6+
name: {
7+
value: ""
8+
},
9+
container: { value: "payload" },
10+
access_token_url: { value: "" },
11+
grant_type: { value: "set_by_credentials" },
12+
username: { value: "" },
13+
password: { value: "" },
14+
client_id: { value: "" },
15+
client_secret: { value: "" },
16+
scope: { value: "" }
17+
},
18+
inputs: 1,
19+
outputs: 1,
20+
icon: "oauth2.png",
21+
align: "right",
22+
label: function () {
23+
return this.name || this._("oauth2");
24+
},
25+
labelStyle: function () {
26+
return this.name ? "node_label_italic" : "";
27+
},
28+
oneditprepare: function () {
29+
if (this.container === undefined) {
30+
$("#node-input-container").val("payload");
31+
}
32+
$("#node-input-container").typedInput({ default: 'msg', types: ['msg'] });
33+
$("#node-input-grant_type").on("change", function () {
34+
if ($("#node-input-grant_type").val() === "set_by_credentials") {
35+
$("#node-password_credentials").hide();
36+
$("#node-access_token_url").hide();
37+
$("#node-client_id").hide();
38+
$("#node-client_secret").hide();
39+
$("#node-scope").hide();
40+
} else if ($("#node-input-grant_type").val() === "client_credentials") {
41+
$("#node-password_credentials").hide();
42+
$("#node-access_token_url").show();
43+
$("#node-client_id").show();
44+
$("#node-client_secret").show();
45+
$("#node-scope").show();
46+
} else if ($("#node-input-grant_type").val() === "password") {
47+
$("#node-password_credentials").show();
48+
$("#node-access_token_url").show();
49+
$("#node-client_id").show();
50+
$("#node-client_secret").show();
51+
$("#node-scope").show();
52+
}
53+
});
54+
}
55+
});
56+
</script>
57+
<script type="text/html" data-template-name="oauth2">
58+
<div class="form-row">
59+
<label for="node-input-name"><i class="fa fa-tag"></i> Name<span data-i18n="oauth2.label.name"></span></label>
60+
<input type="text" id="node-input-name" data-i18n="[placeholder]oauth2.placeholder.name" placeholder="oauth2">
61+
</div>
62+
<div class="form-row">
63+
<label for="node-input-container"><i class="fa fa-ellipsis-h"></i> <span data-i18n="oauth2.label.container">Container</span></label>
64+
<input type="text" id="node-input-container" data-i18n="[placeholder]oauth2.placeholder.container" placeholder="Container" />
65+
</div>
66+
<div class="form-row">
67+
<label for="node-input-grant_type"><i class="fa fa-wrench"></i> <span data-i18n="oauth2.label.grant_type">Grant Type</span></label>
68+
<select type="text" id="node-input-grant_type">
69+
<option value="client_credentials" data-i18n="oauth2.opts.client_credentials">Client Credentials</option>
70+
<option value="password" data-i18n="oauth2.opts.password_credentials">Password</option>
71+
<option value="set_by_credentials" data-i18n="oauth2.opts.set_by_credentials">- Set by msg.oauth2Request -</option>
72+
</select>
73+
</div>
74+
<div class="form-row" id="node-access_token_url">
75+
<label for="node-input-access_token_url"><i class="fa fa-link"></i> <span data-i18n="oauth2.label.access_token_url">Access Token URL</span></label>
76+
<input type="text" id="node-input-access_token_url" data-i18n="[placeholder]oauth2.placeholder.access_token_url" placeholder="http://exemplo.com/oauth/token">
77+
</div>
78+
<div class="form-row" id="node-password_credentials">
79+
<div class="form-row">
80+
<label for="node-input-username"><i class="fa fa-user"></i><span data-i18n="oauth2.label.username">Username</span></label>
81+
<input type="text" id="node-input-username" data-i18n="[placeholder]oauth2.placeholder.username" placeholder="admin">
82+
</div>
83+
<div class="form-row">
84+
<label for="node-input-password"><i class="fa fa-lock"> </i><span data-i18n="oauth2.label.password">Password</span></label>
85+
<input type="password" id="node-input-password" data-i18n="[placeholder]oauth2.placeholder.password" placeholder="admin">
86+
</div>
87+
</div>
88+
<div class="form-row" id="node-client_id">
89+
<label for="node-input-client_id"><i class="fa fa-user"></i> <span data-i18n="oauth2.label.client_id">Client ID</span></label>
90+
<input type="text" id="node-input-client_id" data-i18n="[placeholder]oauth2.placeholder.client_id" placeholder="012493af6282be51660dbc8e21a8462e">
91+
</div>
92+
<div class="form-row" id="node-client_secret">
93+
<label for="node-input-client_secret"><i class="fa fa-lock"></i> <span data-i18n="oauth2.label.client_secret">Client Secret</span></label>
94+
<input type="password" id="node-input-client_secret" data-i18n="[placeholder]oauth2.placeholder.client_secret" placeholder="5621bd4b5a8b09ed31817efb8d54fda2c72bfc1c6968cd4563d83f7cc26f68f6">
95+
</div>
96+
<div class="form-row" id="node-scope">
97+
<label for="node-input-scope"><i class="fa fa-code"></i> <span data-i18n="oauth2.label.scope">Scope</span></label>
98+
<input type="text" id="node-input-scope" data-i18n="[placeholder]oauth2.placeholder.scope" placeholder="scope">
99+
</div>
100+
</script>
101+
<script type="text/html" data-help-name="oauth2"><p></p></script>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Red } from "node-red";
2+
import * as oauth2 from "./oauth2_nodes";
3+
4+
// export = function (RED: Red) {
5+
// RED.nodes.registerType("oauth2", oauth2.oauth2);
6+
7+
// }
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2019 Marcos Caputo <caputo.marcos@gmail.com> https://github.com/caputomarcos/node-red-contrib-oauth2
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
**/
25+
26+
import * as request from 'request';
27+
import * as querystring from 'querystring';
28+
import * as RED from "node-red";
29+
import { Red } from "node-red";
30+
import { Logger } from "../../Logger";
31+
import { NoderedUtil } from "openflow-api";
32+
33+
export interface Ioauth2 {
34+
name: string;
35+
container: string;
36+
access_token_url: string;
37+
grant_type: string;
38+
username: string;
39+
password: string;
40+
client_id: string;
41+
client_secret: string;
42+
scope: string;
43+
}
44+
export class oauth2 {
45+
public node: Red = null;
46+
public name: string = "";
47+
public restKey: string;
48+
public appID: string;
49+
constructor(public config: Ioauth2) {
50+
RED.nodes.createNode(this, config);
51+
try {
52+
this.node = this;
53+
this.node.status({});
54+
55+
config.name = config.name || "";
56+
config.container = config.container || "oauth2Response";
57+
config.access_token_url = config.access_token_url || "";
58+
config.grant_type = config.grant_type || "password";
59+
config.username = config.username || "";
60+
config.password = config.password || "";
61+
config.client_id = config.client_id || "";
62+
config.client_secret = config.client_secret || "";
63+
config.scope = config.scope || "";
64+
65+
this.node.on("input", this.oninput);
66+
this.node.on("close", this.onclose);
67+
} catch (error) {
68+
NoderedUtil.HandleError(this, error);
69+
}
70+
}
71+
async oninput(msg: any) {
72+
// set an empty form
73+
let Form = {};
74+
75+
// TODO - ??? =)
76+
let Method = "Post";
77+
let Authorization = '';
78+
// Choice a grant_type
79+
if ((this.node.grant_type === "set_by_credentials" || this.node.grant_type == null) && msg.oauth2Request) {
80+
this.node.access_token_url = msg.oauth2Request.access_token_url;
81+
this.node.client_id = msg.oauth2Request.credentials.client_id;
82+
this.node.client_secret = msg.oauth2Request.credentials.client_secret;
83+
Form = msg.oauth2Request.credentials;
84+
if (msg.oauth2Request.username && msg.oauth2Request.password) {
85+
// TODO - ??? =)
86+
Authorization = 'Basic ' + Buffer.from(`${msg.oauth2Request.username}:${msg.oauth2Request.password}`).toString('base64');
87+
} else {
88+
// TODO - ??? =)
89+
Authorization = 'Basic ' + Buffer.from(`${this.node.client_id}:${this.node.client_secret}`).toString('base64');
90+
}
91+
} else if (this.node.grant_type === "password") {
92+
Form = {
93+
'username': this.node.username,
94+
'password': this.node.password,
95+
'grant_type': this.node.grant_type,
96+
'client_id': this.node.client_id,
97+
'client_secret': this.node.client_secret
98+
};
99+
// TODO - ??? =)
100+
Authorization = 'Basic ' + Buffer.from(`${this.node.client_id}:${this.node.client_secret}`).toString('base64');
101+
} else if (this.node.grant_type === "client_credentials") {
102+
Form = {
103+
'grant_type': this.node.grant_type,
104+
'client_id': this.node.client_id,
105+
'client_secret': this.node.client_secret,
106+
'scope': this.node.scope
107+
};
108+
// TODO - ??? =)
109+
Authorization = 'Basic ' + Buffer.from(`${this.node.client_id}:${this.node.client_secret}`).toString('base64');
110+
}
111+
112+
let Body = querystring.stringify(Form);
113+
114+
// set Headers
115+
// TODO - improve 'Authorization': 'Basic ' ??? =)
116+
let Headers = {
117+
// 'Accept': 'application/json',
118+
'Content-Type': 'application/x-www-form-urlencoded',
119+
'Content-Length': Buffer.byteLength(Body),
120+
'Authorization': Authorization
121+
};
122+
123+
// Put all together
124+
let Options = {
125+
method: Method,
126+
url: this.node.access_token_url,
127+
headers: Headers,
128+
body: Body,
129+
json: false
130+
};
131+
132+
// make a post request
133+
request.post(Options, (err, response, body) => {
134+
if (msg.oauth2Request) delete msg.oauth2Request;
135+
let oauth2Body: any = null;
136+
try {
137+
oauth2Body = JSON.parse(body ? body : JSON.stringify("{}"));
138+
if (response && response.statusCode && response.statusCode === 200) {
139+
msg[this.node.container] = {
140+
authorization: `${oauth2Body.token_type} ${oauth2Body.access_token}`,
141+
oauth2Response: {
142+
statusCode: response.statusCode,
143+
statusMessage: response.statusMessage,
144+
body: oauth2Body
145+
}
146+
};
147+
148+
this.node.status({
149+
fill: "green",
150+
shape: "dot",
151+
text: `HTTP ${response.statusCode}, has token!`
152+
});
153+
} else if (response && response.statusCode && response.statusCode !== 200) {
154+
msg[this.node.container] = {
155+
oauth2Response: {
156+
statusCode: response.statusCode,
157+
statusMessage: response.statusMessage,
158+
body: oauth2Body
159+
}
160+
};
161+
this.node.status({
162+
fill: "red",
163+
shape: "dot",
164+
text: `HTTP ${response.statusCode}, hasn't token!`
165+
});
166+
}
167+
} catch (error) {
168+
var errormessage = error.message ? error.message : error;
169+
msg[this.node.container] = {
170+
oauth2Response: {
171+
statusCode: response.statusCode,
172+
statusMessage: errormessage,
173+
body: oauth2Body
174+
}
175+
};
176+
this.node.status({
177+
fill: "red",
178+
shape: "dot",
179+
text: `HTTP ${response.statusCode}, hasn't token!`
180+
});
181+
182+
}
183+
if (err && err.code) {
184+
this.node.status({ fill: "red", shape: "dot", text: `ERR ${err.code}` });
185+
msg.err = JSON.parse(JSON.stringify(err));
186+
} else if (err && err.message && err.stack) {
187+
this.node.status({ fill: "red", shape: "dot", text: `ERR ${err.message}` });
188+
msg.err = { message: err.message, stack: err.stack };
189+
}
190+
this.node.send(msg);
191+
});
192+
}
193+
async onclose(removed: boolean, done: any) {
194+
done();
195+
}
196+
}

OpenFlowNodeRED/src/nodered/nodes/rpa.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
defaults: {
9898
queue: { value: "" },
9999
workflow: { value: "" },
100-
localqueue: { value: "" },
100+
localqueue: { value: Math.random().toString(36).substr(2, 9) },
101101
name: { value: "" }
102102
},
103103
inputs: 1,

OpenFlowNodeRED/src/nodered/nodes/rpa_nodes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,14 @@ export class rpa_workflow_node {
110110
this.host = Config.amqp_url;
111111
this._onsignedin = this.onsignedin.bind(this);
112112
this._onsocketclose = this.onsocketclose.bind(this);
113+
if (NoderedUtil.IsNullEmpty(this.config.localqueue)) this.config.localqueue = Math.random().toString(36).substr(2, 9);
113114

114115
WebSocketClient.instance.events.on("onsignedin", this._onsignedin);
115116
WebSocketClient.instance.events.on("onclose", this._onsocketclose);
116117
if (!NoderedUtil.IsNullEmpty(this.originallocalqueue) || this.originallocalqueue != this.config.localqueue) {
117118
this.connect();
119+
} else if (WebSocketClient.instance.isConnected && WebSocketClient.instance.user != null) {
120+
this.connect();
118121
}
119122
} catch (error) {
120123
NoderedUtil.HandleError(this, error);

0 commit comments

Comments
 (0)