Skip to content

Commit 419ad9e

Browse files
committed
add impersonation part 2
1 parent 4cb45a9 commit 419ad9e

10 files changed

Lines changed: 75 additions & 101 deletions

File tree

OpenFlow/src/LoginProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export class LoginProvider {
114114
res.setHeader("Content-Type", "application/json");
115115
if (req.user) {
116116
var user: TokenUser = new TokenUser(req.user);
117-
res.end(JSON.stringify({ jwt: Crypt.createToken(user, "1h") }));
117+
res.end(JSON.stringify({ jwt: Crypt.createToken(user, "5m") }));
118118
} else {
119119
res.end(JSON.stringify({ jwt: "" }));
120120
}
@@ -126,7 +126,7 @@ export class LoginProvider {
126126
var user: User = await LoginProvider.validateToken(rawAssertion);
127127
var tuser: TokenUser = new TokenUser(user);
128128
res.setHeader("Content-Type", "application/json");
129-
res.end(JSON.stringify({ jwt: Crypt.createToken(tuser, "1h") }));
129+
res.end(JSON.stringify({ jwt: Crypt.createToken(tuser, "5m") }));
130130
} catch (error) {
131131
res.end(error);
132132
console.error(error);

OpenFlow/src/Messages/Message.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ export class Message {
427427
private async Signin(cli: WebSocketClient): Promise<void> {
428428
this.Reply();
429429
var msg: SigninMessage
430+
var impostor: string = "";
430431
try {
431432
msg = SigninMessage.assign(this.data);
432433
var tuser: TokenUser = null;
@@ -435,6 +436,9 @@ export class Message {
435436
if (msg.jwt !== null && msg.jwt !== undefined) {
436437
type = "jwtsignin";
437438
tuser = Crypt.verityToken(msg.jwt);
439+
if (tuser.impostor !== null && tuser.impostor !== undefined && tuser.impostor !== "") {
440+
impostor = tuser.impostor;
441+
}
438442
user = await User.FindByUsername(tuser.username);
439443
if (user !== null && user !== undefined) {
440444
// refresh, for roles and stuff
@@ -448,6 +452,9 @@ export class Message {
448452
msg.error = "Unknown username or password";
449453
}
450454
}
455+
if (impostor !== "") {
456+
tuser.impostor = msg.impersonate;
457+
}
451458
// } else if (tuser.username.startsWith("nodered")) {
452459
// user = new User(); user.name = tuser.name; user.username = tuser.username;
453460
// await user.Save(TokenUser.rootToken());
@@ -485,8 +492,20 @@ export class Message {
485492
user.device = msg.device;
486493
}
487494
Audit.LoginSuccess(tuser, type, "websocket", cli.remoteip);
488-
msg.jwt = Crypt.createToken(user, "1h");
495+
var userid: string = user._id;
496+
msg.jwt = Crypt.createToken(tuser, "5m");
489497
msg.user = tuser;
498+
if (msg.impersonate !== undefined && msg.impersonate !== null && msg.impersonate !== "") {
499+
var items = await Config.db.query({ _id: msg.impersonate }, null, 1, 0, null, "users", msg.jwt);
500+
if (items.length == 0) throw new Error("Permission denied, impersonating " + msg.impersonate);
501+
user = User.assign(items[0] as User);
502+
// Check we have update rights
503+
await user.Save(msg.jwt);
504+
tuser = new TokenUser(user);
505+
tuser.impostor = userid;
506+
msg.jwt = Crypt.createToken(tuser, "5m");
507+
msg.user = tuser;
508+
}
490509
if (msg.validate_only !== true) {
491510
cli._logger.debug(tuser.username + " signed in using " + type);
492511
cli.jwt = msg.jwt;
@@ -525,7 +544,7 @@ export class Message {
525544
user = await User.ensureUser(jwt, msg.name, msg.username, null, msg.password);
526545
msg.user = new TokenUser(user);
527546

528-
jwt = Crypt.createToken(msg.user, "1h");
547+
jwt = Crypt.createToken(msg.user, "5m");
529548
var name = user.username;
530549
name = name.split("@").join("").split(".").join("");
531550
name = name.toLowerCase();

OpenFlow/src/TokenUser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export class TokenUser {
1414
if (user === null || user === undefined) { return; }
1515
this._type = user._type;
1616
this._id = user._id;
17+
this.impostor = (user as TokenUser).impostor;
1718
this.name = user.name;
1819
this.username = user.username;
1920
this.roles = user.roles;
@@ -29,7 +30,7 @@ export class TokenUser {
2930
return result;
3031
}
3132
static rootToken(): string {
32-
return Crypt.createToken(TokenUser.rootUser(), "1h");
33+
return Crypt.createToken(TokenUser.rootUser(), "5m");
3334
}
3435
hasrolename(name: string): Boolean {
3536
var hits: Rolemember[] = this.roles.filter(member => member.name === name);

OpenFlow/src/WebSocketServer.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ export class WebSocketServer {
4242
var tuser = Crypt.verityToken(cli.jwt);
4343
var payload = Crypt.decryptToken(cli.jwt);
4444
var clockTimestamp = Math.floor(Date.now() / 1000);
45-
if ((clockTimestamp - payload.iat) > 180) {
46-
WebSocketServer._logger.silly("Send new jwt to client");
45+
// WebSocketServer._logger.silly((payload.exp - clockTimestamp))
46+
if ((payload.exp - clockTimestamp) < 60) {
47+
WebSocketServer._logger.debug("Token for " + tuser.username + " expires in less than 1 minute, send new jwt to client");
4748
var l: SigninMessage = new SigninMessage();
48-
cli.jwt = Crypt.createToken(tuser, "1h");
49+
cli.jwt = Crypt.createToken(tuser, "5m");
4950
l.jwt = cli.jwt;
5051
l.user = tuser;
5152
var m: Message = new Message(); m.command = "refreshtoken";

OpenFlow/src/public/CommonControllers.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module openflow {
4242

4343

4444
['log', 'warn', 'debug', 'error'].forEach((methodName) => {
45-
//['error'].forEach((methodName) => {
45+
//['error2'].forEach((methodName) => {
4646
const originalMethod = console[methodName];
4747
console[methodName] = (...args) => {
4848
let initiator = 'unknown place';
@@ -149,7 +149,7 @@ module openflow {
149149
}
150150
return;
151151
}
152-
this.SigninWithToken(data.jwt, data.rawAssertion, null);
152+
await this.SigninWithToken(data.jwt, data.rawAssertion, null);
153153
} catch (error) {
154154
this.WebSocketClient.user = null;
155155
console.error(error);
@@ -158,7 +158,7 @@ module openflow {
158158
}
159159
});
160160
}
161-
async SigninWithToken(jwt: string, rawAssertion: string, impersonate: string): Promise<void> {
161+
async SigninWithToken(jwt: string, rawAssertion: string, impersonate: string): Promise<SigninMessage> {
162162
var q: SigninMessage = new SigninMessage();
163163
q.jwt = jwt;
164164
q.rawAssertion = rawAssertion;
@@ -173,9 +173,11 @@ module openflow {
173173
var msg: Message = new Message(); msg.command = "signin"; msg.data = JSON.stringify(q);
174174
q = await this.WebSocketClient.Send<SigninMessage>(msg);
175175
this.WebSocketClient.user = q.user;
176+
this.WebSocketClient.jwt = q.jwt;
176177
this.$rootScope.$broadcast("signin", q);
178+
return q;
177179
}
178-
async SigninWithUsername(username: string, password: string, impersonate: string): Promise<void> {
180+
async SigninWithUsername(username: string, password: string, impersonate: string): Promise<SigninMessage> {
179181
var q: SigninMessage = new SigninMessage();
180182
q.username = username;
181183
q.password = password;
@@ -190,7 +192,9 @@ module openflow {
190192
var msg: Message = new Message(); msg.command = "signin"; msg.data = JSON.stringify(q);
191193
q = await this.WebSocketClient.Send<SigninMessage>(msg);
192194
this.WebSocketClient.user = q.user;
195+
this.WebSocketClient.jwt = q.jwt;
193196
this.$rootScope.$broadcast("signin", q);
197+
return q;
194198
}
195199
async Query(collection: string, query: any, projection: any = null, orderby: any = { _created: -1 }, top: number = 500, skip: number = 0): Promise<any[]> {
196200
var q: QueryMessage = new QueryMessage();

0 commit comments

Comments
 (0)