Commit daf470e3 authored by JC Brand's avatar JC Brand

Check permissions before attempting to execute action on behalf of user

parent 3564c874
...@@ -789,13 +789,31 @@ ...@@ -789,13 +789,31 @@
} }
}, },
modifyRole(groupchat, nick, role, reason, onSuccess, onError) { modifyRole (groupchat, nick, role, reason, onSuccess, onError) {
const item = $build("item", {nick, role}); const item = $build("item", {nick, role});
const iq = $iq({to: groupchat, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_ADMIN}).cnode(item.node); const iq = $iq({to: groupchat, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_ADMIN}).cnode(item.node);
if (reason !== null) { iq.c("reason", reason); } if (reason !== null) { iq.c("reason", reason); }
return _converse.connection.sendIQ(iq, onSuccess, onError); return _converse.connection.sendIQ(iq, onSuccess, onError);
}, },
verifyRoles (roles) {
const me = this.model.occupants.findWhere({'jid': _converse.bare_jid});
if (!_.includes(roles, me.get('role'))) {
this.showErrorMessage(__(`Forbidden: you do not have the necessary role in order to do that.`))
return false;
}
return true;
},
verifyAffiliations (affiliations) {
const me = this.model.occupants.findWhere({'jid': _converse.bare_jid});
if (!_.includes(affiliations, me.get('affiliation'))) {
this.showErrorMessage(__(`Forbidden: you do not have the necessary affiliation in order to do that.`))
return false;
}
return true;
},
validateRoleChangeCommand (command, args) { validateRoleChangeCommand (command, args) {
/* Check that a command to change a groupchat user's role or /* Check that a command to change a groupchat user's role or
* affiliation has anough arguments. * affiliation has anough arguments.
...@@ -803,9 +821,7 @@ ...@@ -803,9 +821,7 @@
// TODO check if first argument is valid // TODO check if first argument is valid
if (args.length < 1 || args.length > 2) { if (args.length < 1 || args.length > 2) {
this.showErrorMessage( this.showErrorMessage(
__('Error: the "%1$s" command takes two arguments, the user\'s nickname and optionally a reason.', __('Error: the "%1$s" command takes two arguments, the user\'s nickname and optionally a reason.', command)
command),
true
); );
return false; return false;
} }
...@@ -814,10 +830,7 @@ ...@@ -814,10 +830,7 @@
onCommandError (err) { onCommandError (err) {
_converse.log(err, Strophe.LogLevel.FATAL); _converse.log(err, Strophe.LogLevel.FATAL);
this.showErrorMessage( this.showErrorMessage(__("Sorry, an error happened while running the command. Check your browser's developer console for details."));
__("Sorry, an error happened while running the command. Check your browser's developer console for details."),
true
);
}, },
parseMessageForCommands (text) { parseMessageForCommands (text) {
...@@ -833,7 +846,9 @@ ...@@ -833,7 +846,9 @@
command = match[1].toLowerCase(); command = match[1].toLowerCase();
switch (command) { switch (command) {
case 'admin': case 'admin':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.model.setAffiliation('admin', this.model.setAffiliation('admin',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
...@@ -843,7 +858,9 @@ ...@@ -843,7 +858,9 @@
); );
break; break;
case 'ban': case 'ban':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['owner', 'admin']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.model.setAffiliation('outcast', this.model.setAffiliation('outcast',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
...@@ -853,7 +870,9 @@ ...@@ -853,7 +870,9 @@
); );
break; break;
case 'deop': case 'deop':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.modifyRole( this.modifyRole(
this.model.get('jid'), args[0], 'participant', args[1], this.model.get('jid'), args[0], 'participant', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
...@@ -879,28 +898,42 @@ ...@@ -879,28 +898,42 @@
]); ]);
break; break;
case 'kick': case 'kick':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyRoles(['moderator']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.modifyRole( this.modifyRole(
this.model.get('jid'), args[0], 'none', args[1], this.model.get('jid'), args[0], 'none', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
break; break;
case 'mute': case 'mute':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyRoles(['moderator']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.modifyRole( this.modifyRole(
this.model.get('jid'), args[0], 'visitor', args[1], this.model.get('jid'), args[0], 'visitor', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
break; break;
case 'member': case 'member': {
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
const occupant = this.model.occupants.findWhere({'nick': args[0]});
if (!occupant) {
this.showErrorMessage(__(`Error: Can't find a groupchat participant with the nickname "${args[0]}"`));
break;
}
this.model.setAffiliation('member', this.model.setAffiliation('member',
[{ 'jid': args[0], [{ 'jid': occupant.get('jid'),
'reason': args[1] 'reason': args[1]
}]).then( }]).then(
() => this.model.occupants.fetchMembers(), () => this.model.occupants.fetchMembers(),
(err) => this.onCommandError(err) (err) => this.onCommandError(err)
); );
break; break;
case 'nick': } case 'nick':
if (!this.verifyRoles(['visitor', 'participant', 'moderator'])) {
break;
}
_converse.connection.send($pres({ _converse.connection.send($pres({
from: _converse.connection.jid, from: _converse.connection.jid,
to: this.model.getRoomJIDAndNick(match[2]), to: this.model.getRoomJIDAndNick(match[2]),
...@@ -908,7 +941,9 @@ ...@@ -908,7 +941,9 @@
}).tree()); }).tree());
break; break;
case 'owner': case 'owner':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.model.setAffiliation('owner', this.model.setAffiliation('owner',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
...@@ -918,13 +953,17 @@ ...@@ -918,13 +953,17 @@
); );
break; break;
case 'op': case 'op':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.modifyRole( this.modifyRole(
this.model.get('jid'), args[0], 'moderator', args[1], this.model.get('jid'), args[0], 'moderator', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
break; break;
case 'revoke': case 'revoke':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyAffiliations(['admin', 'owner']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.model.setAffiliation('none', this.model.setAffiliation('none',
[{ 'jid': args[0], [{ 'jid': args[0],
'reason': args[1] 'reason': args[1]
...@@ -944,7 +983,9 @@ ...@@ -944,7 +983,9 @@
); );
break; break;
case 'voice': case 'voice':
if (!this.validateRoleChangeCommand(command, args)) { break; } if (!this.verifyRoles(['moderator']) || !this.validateRoleChangeCommand(command, args)) {
break;
}
this.modifyRole( this.modifyRole(
this.model.get('jid'), args[0], 'participant', args[1], this.model.get('jid'), args[0], 'participant', args[1],
undefined, this.onCommandError.bind(this)); undefined, this.onCommandError.bind(this));
......
...@@ -172,7 +172,7 @@ ...@@ -172,7 +172,7 @@
id: 'DC352437-C019-40EC-B590-AF29E879AF97' id: 'DC352437-C019-40EC-B590-AF29E879AF97'
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'}) }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
.c('item').attrs({ .c('item').attrs({
affiliation: 'member', affiliation: 'owner',
jid: _converse.bare_jid, jid: _converse.bare_jid,
role: 'participant' role: 'participant'
}).up() }).up()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment