Skip to content

Commit 0d432dd

Browse files
committed
bump
1 parent 2efc870 commit 0d432dd

12 files changed

Lines changed: 197 additions & 110 deletions

File tree

OpenFlow/src/Config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class Config {
3030
Config.openflow_amqp_expiration = parseInt(Config.getEnv("openflow_amqp_expiration", (60 * 1000 * 25).toString())); // 25 min
3131
Config.amqp_prefetch = parseInt(Config.getEnv("amqp_prefetch", "50"));
3232
Config.amqp_web_default_priority = parseInt(Config.getEnv("amqp_web_default_priority", "2"));
33+
Config.trace_dashboardauth = Config.parseBoolean(Config.getEnv("trace_dashboardauth", "true"));
3334

3435

3536
Config.getting_started_url = Config.getEnv("getting_started_url", "");
@@ -159,6 +160,7 @@ export class Config {
159160
public static openflow_amqp_expiration: number = parseInt(Config.getEnv("openflow_amqp_expiration", (60 * 1000 * 25).toString())); // 25 min
160161
public static amqp_prefetch: number = parseInt(Config.getEnv("amqp_prefetch", "50"));
161162
public static amqp_web_default_priority: number = parseInt(Config.getEnv("amqp_web_default_priority", "2"));
163+
public static trace_dashboardauth: boolean = Config.parseBoolean(Config.getEnv("trace_dashboardauth", "true"));
162164

163165
public static getting_started_url: string = Config.getEnv("getting_started_url", "");
164166

OpenFlow/src/DBHelper.ts

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -74,48 +74,66 @@ export class DBHelper {
7474
Logger.otel.endSpan(span);
7575
}
7676
}
77-
public static async GetRoles(_id: string, ident: number, parent: Span): Promise<Role[]> {
78-
const span: Span = Logger.otel.startSubSpan("dbhelper.GetRoles", parent);
79-
span.setAttribute("_id", _id);
80-
span.setAttribute("ident", ident);
81-
try {
82-
if (ident > Config.max_recursive_group_depth) return [];
83-
const result: Role[] = [];
84-
const query: any = { "members": { "$elemMatch": { _id: _id } } };
85-
const ids: string[] = [];
86-
const _roles: Role[] = await Config.db.query<Role>(query, null, Config.expected_max_roles, 0, null, "users", Crypt.rootToken(), undefined, undefined, span);
87-
for (let role of _roles) {
88-
if (ids.indexOf(role._id) == -1) {
89-
ids.push(role._id);
90-
result.push(role);
91-
const _subroles: Role[] = await this.GetRoles(role._id, ident + 1, span);
92-
for (let subrole of _subroles) {
93-
if (ids.indexOf(subrole._id) == -1) {
94-
ids.push(subrole._id);
95-
result.push(subrole);
96-
}
97-
}
98-
}
99-
}
100-
return result;
101-
} catch (error) {
102-
span.recordException(error);
103-
throw error;
104-
} finally {
105-
Logger.otel.endSpan(span);
106-
}
107-
}
77+
// public static async GetRoles(_id: string, ident: number, parent: Span): Promise<Role[]> {
78+
// const span: Span = Logger.otel.startSubSpan("dbhelper.GetRoles", parent);
79+
// span.setAttribute("_id", _id);
80+
// span.setAttribute("ident", ident);
81+
// try {
82+
// if (ident > Config.max_recursive_group_depth) return [];
83+
// const result: Role[] = [];
84+
// const query: any = { "members": { "$elemMatch": { _id: _id } } };
85+
// const ids: string[] = [];
86+
// const _roles: Role[] = await Config.db.query<Role>(query, null, Config.expected_max_roles, 0, null, "users", Crypt.rootToken(), undefined, undefined, span);
87+
// for (let role of _roles) {
88+
// if (ids.indexOf(role._id) == -1) {
89+
// ids.push(role._id);
90+
// result.push(role);
91+
// const _subroles: Role[] = await this.GetRoles(role._id, ident + 1, span);
92+
// for (let subrole of _subroles) {
93+
// if (ids.indexOf(subrole._id) == -1) {
94+
// ids.push(subrole._id);
95+
// result.push(subrole);
96+
// }
97+
// }
98+
// }
99+
// }
100+
// return result;
101+
// } catch (error) {
102+
// span.recordException(error);
103+
// throw error;
104+
// } finally {
105+
// Logger.otel.endSpan(span);
106+
// }
107+
// }
108108
public static cached_roles: Role[] = [];
109109
public static cached_at: Date = new Date();
110110
public static async DecorateWithRoles(user: User, parent: Span): Promise<void> {
111111
const span: Span = Logger.otel.startSubSpan("dbhelper.DecorateWithRoles", parent);
112112
try {
113113
if (!Config.decorate_roles_fetching_all_roles) {
114-
const roles: Role[] = await this.GetRoles(user._id, 0, span);
115-
user.roles = [];
116-
roles.forEach(role => {
117-
user.roles.push(new Rolemember(role.name, role._id));
118-
});
114+
// const roles: Role[] = await this.GetRoles(user._id, 0, span);
115+
// user.roles = [];
116+
// roles.forEach(role => {
117+
// user.roles.push(new Rolemember(role.name, role._id));
118+
// });
119+
const pipe: any = [{ "$match": { "_id": user._id } },
120+
{
121+
"$graphLookup": {
122+
from: "users",
123+
startWith: "$_id",
124+
connectFromField: "_id",
125+
connectToField: "members._id",
126+
as: "roles",
127+
maxDepth: Config.max_recursive_group_depth,
128+
restrictSearchWithMatch: { "_type": "role" }
129+
}
130+
}]
131+
const results = await Config.db.aggregate<User>(pipe, "users", Crypt.rootToken(), null, span);
132+
if (results.length > 0) {
133+
user = results[0];
134+
user.roles = user.roles.map(x => ({ "_id": x._id, "name": x.name })) as any;
135+
user.roles = user.roles;
136+
}
119137
} else {
120138
var end: number = new Date().getTime();
121139
var seconds = Math.round((end - this.cached_at.getTime()) / 1000);

OpenFlow/src/DatabaseConnection.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,37 @@ export class DatabaseConnection {
182182
WellknownIds.personal_nodered_users,
183183
WellknownIds.robot_agent_users
184184
]
185+
WellknownNamesArray: string[] = [
186+
"root",
187+
"admins",
188+
"users",
189+
"user",
190+
"admin",
191+
"nodered",
192+
"administrator",
193+
"robots",
194+
"robot",
195+
"nodered_users",
196+
"nodered_admins",
197+
"nodered_api_users",
198+
"filestore_users",
199+
"filestore_admins",
200+
"robot_users",
201+
"robot_admins",
202+
"personal_nodered_users",
203+
"robot_agent_users",
204+
205+
"nodered users",
206+
"nodered admins",
207+
"nodered api_users",
208+
"filestore users",
209+
"filestore admins",
210+
"robot users",
211+
"robot admins",
212+
"personal nodered users",
213+
"robot agent users"
214+
215+
]
185216

186217
async CleanACL<T extends Base>(item: T, user: TokenUser, parent: Span): Promise<T> {
187218
const span: Span = Logger.otel.startSubSpan("db.CleanACL", parent);
@@ -817,6 +848,12 @@ export class DatabaseConnection {
817848
(item as any).passwordhash = await Crypt.hash((item as any).newpassword);
818849
delete (item as any).newpassword;
819850
}
851+
if (collectionname === "users" && !NoderedUtil.IsNullEmpty(item._type) && !NoderedUtil.IsNullEmpty(item.name)) {
852+
if ((item._type === "user" || item._type === "role") &&
853+
(this.WellknownNamesArray.indexOf(item.name) > -1 || this.WellknownNamesArray.indexOf((item as any).username) > -1)) {
854+
throw new Error("Access denied");
855+
}
856+
}
820857
j = ((j as any) === 'true' || j === true);
821858
w = parseInt((w as any));
822859
item._version = 0;
@@ -1009,6 +1046,15 @@ export class DatabaseConnection {
10091046
const again = this.hasAuthorization(user, original, Rights.update);
10101047
throw new Error("Access denied, no authorization to UpdateOne " + q.item._type + " " + name + " to database");
10111048
}
1049+
if (q.collectionname === "users" && !NoderedUtil.IsNullEmpty(q.item._type) && !NoderedUtil.IsNullEmpty(q.item.name)) {
1050+
if ((q.item._type === "user" || q.item._type === "role") &&
1051+
(this.WellknownNamesArray.indexOf(q.item.name) > -1 || this.WellknownNamesArray.indexOf((q.item as any).username) > -1)) {
1052+
if (this.WellknownIdsArray.indexOf(q.item._id) == -1) {
1053+
throw new Error("Access denied");
1054+
}
1055+
}
1056+
}
1057+
10121058
if (q.collectionname != "fs.files") {
10131059
q.item._modifiedby = user.name;
10141060
q.item._modifiedbyid = user._id;

OpenFlow/src/LoginProvider.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,12 @@ export class LoginProvider {
177177
}
178178
});
179179
app.get("/dashboardauth", async (req: any, res: any, next: any) => {
180-
const span: Span = Logger.otel.startSpan("LoginProvider.dashboardauth");
180+
const span: Span = (Config.trace_dashboardauth ? Logger.otel.startSpan("LoginProvider.dashboardauth") : null);
181181
try {
182-
span.setAttribute("remoteip", WebServer.remoteip(req));
182+
span?.setAttribute("remoteip", WebServer.remoteip(req));
183183
if (req.user) {
184184
const user: TokenUser = TokenUser.From(req.user);
185-
span.setAttribute("username", user.username);
185+
span?.setAttribute("username", user.username);
186186
if (user != null) {
187187
const allowed = user.roles.filter(x => x.name == "dashboardusers" || x.name == "admins");
188188
if (allowed.length > 0) {
@@ -241,7 +241,7 @@ export class LoginProvider {
241241
// const [login, password] = new Buffer(b64auth, 'base64').toString().split(':')
242242
const [login, password] = Buffer.from(b64auth, "base64").toString().split(':')
243243
if (login && password) {
244-
span.setAttribute("username", login);
244+
span?.setAttribute("username", login);
245245
let user: User = Auth.getUser(b64auth, "dashboard");
246246
if (user == null) user = await Auth.ValidateByPassword(login, password, span);
247247
if (user != null) {
@@ -265,7 +265,7 @@ export class LoginProvider {
265265
res.setHeader('WWW-Authenticate', 'Basic realm="OpenFlow"');
266266
res.end('Unauthorized');
267267
} catch (error) {
268-
span.recordException(error);
268+
span?.recordException(error);
269269
throw error;
270270
} finally {
271271
Logger.otel.endSpan(span);
@@ -467,12 +467,12 @@ export class LoginProvider {
467467
console.error(error.message ? error.message : error);
468468
return res.status(500).send({ message: error.message ? error.message : error });
469469
}
470-
try {
471-
span.addEvent("RegisterProviders");
472-
LoginProvider.RegisterProviders(app, baseurl);
473-
} catch (error) {
474-
span.recordException(error);
475-
}
470+
// try {
471+
// span.addEvent("RegisterProviders");
472+
// LoginProvider.RegisterProviders(app, baseurl);
473+
// } catch (error) {
474+
// span.recordException(error);
475+
// }
476476
Logger.otel.endSpan(span);
477477
});
478478
app.get("/validateuserform", async (req: any, res: any, next: any): Promise<void> => {
@@ -571,15 +571,17 @@ export class LoginProvider {
571571
console.error(error.message ? error.message : error);
572572
Logger.otel.endSpan(span);
573573
return res.status(500).send({ message: error.message ? error.message : error });
574-
}
575-
try {
576-
LoginProvider.RegisterProviders(app, baseurl);
577-
} catch (error) {
578-
span.recordException(error);
579-
return res.status(500).send({ message: error.message ? error.message : error });
580574
} finally {
581575
Logger.otel.endSpan(span);
582576
}
577+
// try {
578+
// LoginProvider.RegisterProviders(app, baseurl);
579+
// } catch (error) {
580+
// span.recordException(error);
581+
// return res.status(500).send({ message: error.message ? error.message : error });
582+
// } finally {
583+
// Logger.otel.endSpan(span);
584+
// }
583585

584586
});
585587
app.get("/download/:id", async (req, res) => {

OpenFlow/src/Messages/Message.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export class Message {
308308
case "insertone":
309309
this.EnsureJWT(cli);
310310
if (Config.enable_openflow_amqp) {
311-
cli.Send(await QueueClient.SendForProcessing(this, (cli.clientagent == "webapp" ? Config.amqp_web_default_priority : 1)));
311+
cli.Send(await QueueClient.SendForProcessing(this, this.priority));
312312
} else {
313313
await this.InsertOne(span);
314314
cli.Send(this);
@@ -503,10 +503,10 @@ export class Message {
503503
this.Reply();
504504
let msg: RegisterQueueMessage;
505505
try {
506+
msg = RegisterQueueMessage.assign(this.data);
506507
if (!NoderedUtil.IsNullEmpty(msg.queuename) && msg.queuename.toLowerCase() == "openflow") {
507508
throw new Error("Access denied");
508509
}
509-
msg = RegisterQueueMessage.assign(this.data);
510510
msg.queuename = await cli.CreateConsumer(msg.queuename, parent);
511511
} catch (error) {
512512
await handleError(cli, error);
@@ -921,7 +921,7 @@ export class Message {
921921
insert.collectionname = msg.collectionname; insert.item = msg.items[i];
922922
insert.w = msg.w; insert.j = msg.j; insert.jwt = msg.jwt;
923923
tmpmsg.command = "insertone"; tmpmsg.data = JSON.stringify(insert);
924-
Promises.push(QueueClient.SendForProcessing(tmpmsg, 1));
924+
Promises.push(QueueClient.SendForProcessing(tmpmsg, this.priority));
925925
}
926926
var results = await Promise.all(Promises.map(p => p.catch(e => e)));
927927
if (msg.skipresults) {

OpenFlow/src/SocketMessage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class SocketMessage {
1212
public data: string;
1313
public count: number;
1414
public index: number;
15+
public priority: number = 1;
1516
public static fromjson(json: string): SocketMessage {
1617
let result: SocketMessage = new SocketMessage();
1718
let obj: any = JSON.parse(json);
@@ -20,6 +21,7 @@ export class SocketMessage {
2021
result.replyto = obj.replyto;
2122
result.count = 1;
2223
result.index = 0;
24+
if (!NoderedUtil.IsNullEmpty(obj.priority)) result.priority = obj.priority;
2325
result.data = obj.data;
2426
if (isNumber(obj.count)) { result.count = obj.count; }
2527
if (isNumber(obj.index)) { result.index = obj.index; }

OpenFlow/src/WebSocketServerClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ export class WebSocketServerClient {
407407
if (msgs.length === 1) {
408408
this._receiveQueue = this._receiveQueue.filter(function (msg: SocketMessage): boolean { return msg.id !== id; });
409409
const singleresult: Message = Message.frommessage(first, first.data);
410+
singleresult.priority = first.priority;
410411
singleresult.Process(this);
411412
} else {
412413
let buffer: string = "";
@@ -415,6 +416,7 @@ export class WebSocketServerClient {
415416
});
416417
this._receiveQueue = this._receiveQueue.filter(function (msg: SocketMessage): boolean { return msg.id !== id; });
417418
const result: Message = Message.frommessage(first, buffer);
419+
result.priority = first.priority;
418420
result.Process(this);
419421
}
420422
} else {

OpenFlow/src/public/CommonControllers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ export class entitiesCtrl<T> {
434434
await NoderedUtil.DeleteOne(this.collection, model._id, null, 2);
435435
this.models = this.models.filter(function (m: any): boolean { return m._id !== model._id; });
436436
} catch (error) {
437-
this.errormessage = error;
437+
this.errormessage = error.message ? error.message : error;
438438
}
439439
this.loading = false;
440440
if (!this.$scope.$$phase) { this.$scope.$apply(); }

0 commit comments

Comments
 (0)