Skip to content

Commit

Permalink
Give IRC users power according to modePowerMap. Fixes #385
Browse files Browse the repository at this point in the history
And is required to fix #453, which is now working.
  • Loading branch information
kegsay committed Jun 28, 2017
1 parent 1b55548 commit 9a813a3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 35 deletions.
67 changes: 33 additions & 34 deletions lib/bridge/IrcHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -654,8 +654,6 @@ IrcHandler.prototype.onPart = Promise.coroutine(function*(req, server, leavingUs
yield Promise.all(promises);
});

// TODO: Pass in the prefix letter along with the special char letter so we don't need to
// look up an unsafeClient constantly and therefore can make this work for IRC users.
IrcHandler.prototype.onMode = Promise.coroutine(function*(req, server, channel, by,
mode, enabled, arg) {
req.log.info(
Expand All @@ -675,54 +673,58 @@ IrcHandler.prototype.onMode = Promise.coroutine(function*(req, server, channel,
return;
}

// Bridge operator modes to power levels
// Bridge usermodes to power levels
let modeToPower = server.getModePowerMap();

if (Object.keys(modeToPower).indexOf(mode) === -1) {
// Not an operator power mode
return;
}

const nick = arg;

const matrixRooms = yield this.ircBridge.getStore().getMatrixRoomsForChannel(server, channel);

if (matrixRooms.length === 0) {
req.log.info("No mapped matrix rooms for IRC channel %s", channel);
return;
}

// Work out what power levels to give
const userPowers = [];
if (modeToPower[mode] && enabled) { // only give this power if it's +, not -
userPowers.push(modeToPower[mode]);
}

// Try to also add in other modes for this client connection
const bridgedClient = this.ircBridge.getClientPool().getBridgedClientByNick(
server, nick
);
let userId = null;
if (bridgedClient) {
userId = bridgedClient.userId;
if (!bridgedClient.unsafeClient) {
req.log.info(`Bridged client for ${nick} has no IRC client.`);
return;
}
const chanData = bridgedClient.unsafeClient.chanData(channel);
if (!(chanData && chanData.users)) {
req.log.error(`No channel data for ${channel}`);
return;
}
const userPrefixes = chanData.users[nick];

if (!bridgedClient) {
req.log.info("No bridged client for %s", nick);
return;
}

if (!bridgedClient.unsafeClient) {
req.log.info(`Bridged client for ${nick} has no IRC client.`);
return;
userPrefixes.split('').forEach(
prefix => {
const m = bridgedClient.unsafeClient.modeForPrefix[prefix];
if (modeToPower[m] !== undefined) {
userPowers.push(modeToPower[m]);
}
}
);
}
const chanData = bridgedClient.unsafeClient.chanData(channel);

if (!(chanData && chanData.users)) {
req.log.error(`No channel data for ${channel}`);
return;
else {
// real IRC user, work out their user ID
userId = server.getUserIdFromNick(nick);
}

const userPrefixes = chanData.users[nick];
const userPowers = [];
userPrefixes.split('').forEach(
prefix => {
const m = bridgedClient.unsafeClient.modeForPrefix[prefix];
if (modeToPower[m] !== undefined) {
userPowers.push(modeToPower[m]);
}
}
);

// By default, unset the user's power level. This will be treated
// as the users_default defined in the power levels (or 0 otherwise).
let level = undefined;
Expand All @@ -731,12 +733,9 @@ IrcHandler.prototype.onMode = Promise.coroutine(function*(req, server, channel,
if (userPowers.length > 0) {
level = userPowers.sort((a, b) => b - a)[0];
}
const userId = bridgedClient.userId;

req.log.info(
`Mode ${mode} received for ${nick}, prefixes now = ${userPrefixes} ` +
`and powers are now = ${userPowers}, bridging power level of ${userId} ` +
`at ${level}.`
`onMode: Mode ${mode} received for ${nick} - granting level of ${level} to ${userId}`
);

const promises = matrixRooms.map((room) => {
Expand Down
5 changes: 4 additions & 1 deletion lib/irc/IrcEventBroker.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,16 @@ IrcEventBroker.prototype.addHooks = function(client, connInst) {
req.log.error("No client exists to set onMode for " + name.nick);
return null;
}
req.log.info(
"Calculating +mode for " + name.nick + " in " + name.chan + " with opLevel=" + name.opLevel
);
// send onMode for the most powerful prefix only.
let prefixLetter = null;
for (let i = 0; i < name.opLevel.length; i++) {
const prefix = name.opLevel[i];
if (!prefixLetter) {
prefixLetter = prefix;
return null;
continue;
}
if (client.unsafeClient.isUserPrefixMorePowerfulThan(prefixLetter, prefix)) {
prefixLetter = prefix;
Expand Down

0 comments on commit 9a813a3

Please sign in to comment.