Skip to content

Commit

Permalink
Dev/course channel fix 3 (#158)
Browse files Browse the repository at this point in the history
* course-chat-fix-2, make new roles where there arent any in /rolespermoverride and also remove individual permission overwrites, and also updates to /course join to catch when there doesn't exist a role for a course and also /course leave to attempt to remove individual permission overwrites along with removing course role PLEASE TEST THOROUGHLY AND INSPECT CODE THOROUGHLY. I wrote this ASAP and haven't got time to properly review it.

* Modified functions for course channel fixes

* Check for if user only has read perms for overwrite replacing and fix looping over members

* Fix to functionality of iteration and editing roles

* Fix to initial working state

* Fix linting

* Additional fixes to ordering and component operations to remove role and individual permissions correctly

* Appended filter for both view only perms and view + send messages perms

---------

Co-authored-by: AcdSoftCo <[email protected]>
Co-authored-by: Wolfdragon24 <[email protected]>
  • Loading branch information
3 people authored Oct 21, 2023
1 parent 9f7c78d commit 65f32ef
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 58 deletions.
63 changes: 53 additions & 10 deletions commands/course.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const { SlashCommandBuilder } = require("@discordjs/builders");
const { Permissions } = require("discord.js");

const MODERATION_REQUEST_CHANNEL = 824506830641561600;
const COMMAND_JOIN = "join";
const COMMAND_LEAVE = "leave";

Expand Down Expand Up @@ -54,6 +52,9 @@ const is_valid_course = (course) => {
);
};

const in_overwrites = (overwrites, id) =>
[1024n, 3072n].includes(overwrites.find((v, k) => k === id)?.allow?.bitfield);

module.exports = {
data: new SlashCommandBuilder()
.setName("course")
Expand Down Expand Up @@ -128,8 +129,9 @@ module.exports = {
});
}

// if there isn't a role that matches the name of the course
return await interaction.reply({
content: `✅ | End of command - ${course_with_alias}.`,
content: `There doesn't exist a role for \`${course_with_alias}\`. If you believe there should be, please inform a member of the Discord Bot team or staff.`,
ephemeral: true,
});
} else if (interaction.options.getSubcommand() === COMMAND_LEAVE) {
Expand All @@ -143,24 +145,65 @@ module.exports = {
});
}

// First, let's see if there's a role that matches the name of the course
// Check and fetch a channel corresponding to input
const channel = await interaction.guild.channels.cache.find(
(c) => c.name.toLowerCase() === course.toLowerCase(),
);

if (channel === undefined) {
return await interaction.reply({
content: `❌ | The course chat for \`${course}\` does not exist.`,
ephemeral: true,
});
} else if (channel.type !== "GUILD_TEXT") {
return await interaction.reply({
content: `❌ | The course chat for \`${course}\` is not a text channel.`,
ephemeral: true,
});
}

const permissions = channel.permissionOverwrites.cache;

// Then check if there's a role that matches the name of the course
const role = await interaction.guild.roles.cache.find(
(r) => r.name.toLowerCase() === course.toLowerCase(),
);

// If there is, let's see if the member already has that role
// Check if the role exists
if (role !== undefined) {
if (!interaction.member.roles.cache.has(role.id)) {
// Check if the member has access via individual perms
if (in_overwrites(permissions, interaction.member.id)) {
// Remove the member from the channel's permission overwrites if so
await channel.permissionOverwrites.delete(interaction.member);
}

// Check if the member has access via role
if (
interaction.member.roles.cache.has(role.id) &&
in_overwrites(permissions, role.id)
) {
// If they do remove the role
await interaction.member.roles.remove(role);
return await interaction.reply({
content: `✅ | Removed you from the role and chat for \`${course}\`.`,
ephemeral: true,
});
} else {
return await interaction.reply({
content: `❌ | You do not have the role for \`${course}\`.`,
ephemeral: true,
});
}

// If they do, let's remove the role from them
await interaction.member.roles.remove(role);
} else if (in_overwrites(permissions, interaction.member.id)) {
// Check if the user has individual perms and removes if so
await channel.permissionOverwrites.delete(interaction.member);
return await interaction.reply({
content: `✅ | Removed you from the chat for \`${course}\`.`,
ephemeral: true,
});
} else {
return await interaction.reply({
content: ` | Removed you from the role and chat for \`${course}\`.`,
content: ` | You do not have access to the chat for \`${course}\`.`,
ephemeral: true,
});
}
Expand Down
98 changes: 50 additions & 48 deletions commands/rolesPermOverride.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { SlashCommandBuilder } = require("@discordjs/builders");
const { Permissions } = require("discord.js");

const is_valid_course = (course) => {
const is_valid_course_name = (course) => {
const reg_comp_course = /^comp\d{4}$/;
const reg_math_course = /^math\d{4}$/;
const reg_binf_course = /^binf\d{4}$/;
Expand All @@ -18,47 +18,51 @@ const is_valid_course = (course) => {
);
};

function editChannels(interaction, channels, role) {
channels.forEach((channel) => {
if (
channel.type === "GUILD_TEXT" &&
channel.name.toLowerCase() === role.name.toLowerCase()
) {
// Remove all permissions from a role
role.setPermissions(0n)
.then((updated) =>
console.log(`Updated permissions to ${updated.permissions.bitfield}`),
)
.catch(console.error);
// Set the permissions of the role
// Add the member to the channel's permission overwrites
channel.permissionOverwrites.create(role, {
VIEW_CHANNEL: true,
SEND_MESSAGES: true,
const in_overwrites = (overwrites, id) =>
[1024n, 3072n].includes(overwrites.find((v, k) => k === id)?.allow?.bitfield);

async function editChannels(interaction, channels) {
for (const data of channels) {
const channel = data[1];
const is_valid = is_valid_course_name(channel.name);

if (!is_valid || channel.type !== "GUILD_TEXT") continue;

let role = interaction.guild.roles.cache.find(
(r) => r.name.toLowerCase() === channel.name.toLowerCase(),
);

if (!role) {
role = await interaction.guild.roles.create({
name: channel.name.toLowerCase(),
color: "BLUE",
});
console.log(channel.name, role.name);
}
});
}

function editRoles(interaction, roles) {
roles.forEach((role) => {
if (is_valid_course(role.name)) {
interaction.guild.channels
.fetch()
.then(
(channels) => (
editChannels(interaction, channels, role),
console.log(`There are ${channels.size} channels.`)
),
)
.catch(console.error);
const permissions = channel.permissionOverwrites.cache;

// clear every individual user permission overwrite for the channel
for (const user of channel.members) {
const userId = user[0];
const userObj = user[1];

if (userObj.user.bot) continue;

// Check if the member has access via individual perms
if (in_overwrites(permissions, userId)) {
// Remove the member from the channel's permission overwrites
await channel.permissionOverwrites.delete(userObj);
await userObj.roles.add(role);
}
}
});
interaction.reply({
content: `✅ | found course chats and matching roles, cleared and set permission overwrites for roles.`,
ephemeral: true,
});

// set the permissions for the new role on a channel
// const channel = interaction.guild.channels.cache.get('CHANNEL_ID');
await channel.permissionOverwrites.create(role, {
VIEW_CHANNEL: true,
SEND_MESSAGES: true,
});
}
}

module.exports = {
Expand All @@ -75,19 +79,17 @@ module.exports = {
ephemeral: true,
});
}
await interaction.deferReply();

// for all roles with name == chat name involving 4 letter prefix comp, seng, engg or binf,

// give the role the permission override to participate in the matching channel.
interaction.guild.roles
.fetch()
.then(
(roles) => (
editRoles(interaction, roles), console.log(`There are ${roles.size} roles.`)
),
)
.catch(console.error);
// Get all channels and run function
const channels = await interaction.guild.channels.fetch();

await editChannels(interaction, channels);
await interaction.editReply("Successfully ported all user permissions to roles.");
} catch (error) {
await interaction.reply("Error: " + error);
await interaction.editReply("Error: " + error);
}
},
};

0 comments on commit 65f32ef

Please sign in to comment.