Skip to content

Commit c524f18

Browse files
committed
compute permissions in one place
1 parent 0d3c329 commit c524f18

File tree

6 files changed

+42
-38
lines changed

6 files changed

+42
-38
lines changed

Discord.C++/Channel.cpp

-18
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,3 @@ void DiscordCPP::Channel::delete_channel() {
4141

4242
api_call(url, "DELETE");
4343
}
44-
45-
DiscordCPP::Permissions DiscordCPP::Channel::merge_permission_overwrites(const Permissions& permissions, const std::string& id) {
46-
if (permissions.has_permission(Permissions::ADMINISTRATOR)) {
47-
return Permissions::All();
48-
}
49-
50-
Permissions result;
51-
result.add(permissions);
52-
53-
for (auto overwrite : permission_overwrites) {
54-
if (overwrite.get_id() == id) {
55-
result.add(overwrite.get_allowed_permissions());
56-
result.remove(overwrite.get_denied_permissions());
57-
}
58-
}
59-
60-
return result;
61-
}

Discord.C++/Channel.h

-5
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ class Channel : public DiscordObject {
5252
/// @return Channelname as std::string
5353
DLL_EXPORT explicit operator std::string() { return name; };
5454

55-
/** Merge permission overwrites into given permission set
56-
@param permissions permission set
57-
@param id member or role id */
58-
DLL_EXPORT Permissions merge_permission_overwrites(const Permissions& permissions, const std::string& id);
59-
6055
/// @return the ChannelType of the channel
6156
DLL_EXPORT Type get_type() { return type; }
6257
/// @return the sorting position

Discord.C++/ChannelHelper.h

+4
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,9 @@ class ChannelHelper {
3030
DLL_EXPORT static std::string get_channel_id(const ChannelVariant& channel) {
3131
return std::visit([](auto& c) { return c.get_id(); }, channel);
3232
}
33+
34+
DLL_EXPORT static std::vector<PermissionOverwrites> get_permission_overwrites(const ChannelVariant& channel) {
35+
return std::visit([](auto& c) { return c.get_permission_overwrites(); }, channel);
36+
}
3337
};
3438
} // namespace DiscordCPP

Discord.C++/Guild.cpp

+34-9
Original file line numberDiff line numberDiff line change
@@ -200,29 +200,54 @@ void DiscordCPP::Guild::unban(const User& user) {
200200
api_call(url, "DEL");
201201
}
202202

203-
DiscordCPP::Permissions DiscordCPP::Guild::get_member_permissions(const Member& member) {
203+
DiscordCPP::Permissions DiscordCPP::Guild::get_member_permissions(const Member& member, const ChannelVariant& channel) {
204204
if (owner_id.has_value() && owner_id.value() == member.get_id()) {
205205
return Permissions::All();
206206
}
207207

208+
std::vector<std::string> ids;
209+
ids.push_back(this->get_id()); // everyone
210+
for (const auto& id : member.get_roles()) {
211+
ids.push_back(id);
212+
}
213+
208214
std::map<std::string, Permissions> permission_map;
209-
for (const Role& role : roles) {
215+
for (const auto& role : roles) {
210216
permission_map.insert({role.get_id(), role.get_permissions()});
211217
}
212218

213219
Permissions permissions;
214-
for (std::string role : member.get_roles()) {
215-
if (permission_map.find(role) == permission_map.end()) {
216-
throw DiscordException("unknown role " + role + " for member " + member.get_id() + " in guild " + get_id());
220+
for (const auto& id : ids) {
221+
if (permission_map.find(id) == permission_map.end()) {
222+
throw DiscordException("unknown role " + id + " for member " + member.get_id() + " in guild " + get_id());
217223
}
218224

219-
if (permission_map.at(role).has_permission(Permissions::ADMINISTRATOR)) {
220-
return Permissions::All();
221-
}
225+
permissions.add(permission_map.at(id));
226+
}
227+
228+
if (permissions.has_permission(Permissions::ADMINISTRATOR)) {
229+
return Permissions::All();
230+
}
231+
232+
ids.push_back(member.get_id());
233+
234+
std::map<std::string, PermissionOverwrites> overwrite_map;
235+
for (const auto& overwrite : ChannelHelper::get_permission_overwrites(channel)) {
236+
overwrite_map.emplace(overwrite.get_id(), overwrite);
237+
}
222238

223-
permissions.add(permission_map.at(role));
239+
Permissions denied;
240+
Permissions allowed;
241+
for (const auto& id : ids) {
242+
if (overwrite_map.find(id) != overwrite_map.end()) {
243+
denied.add(overwrite_map.at(id).get_denied_permissions());
244+
allowed.add(overwrite_map.at(id).get_allowed_permissions());
245+
}
224246
}
225247

248+
permissions.remove(denied);
249+
permissions.add(allowed);
250+
226251
return permissions;
227252
}
228253

Discord.C++/Guild.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,10 @@ class Guild : public DiscordObject {
151151
DLL_EXPORT void unban(const User& user);
152152

153153
/** @return the members permissions in the guild
154+
@param[in] member the member whose permissions to check
155+
@param[in] channel the channel to for permission overwrites
154156
@throws DiscordException if an unknown role is encountered */
155-
DLL_EXPORT Permissions get_member_permissions(const Member& member);
157+
DLL_EXPORT Permissions get_member_permissions(const Member& member, const ChannelVariant& channel);
156158

157159
/// @return the guild's name
158160
DLL_EXPORT std::string get_name() { return name; }

test_bot/main.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,7 @@ class Client : public Discord {
471471
Channel channel = interaction.get_channel().value();
472472
Guild guild = interaction.get_guild().value();
473473

474-
Permissions permissions = guild.get_member_permissions(member);
475-
permissions = channel.merge_permission_overwrites(permissions, member.get_id());
476-
for (auto role : member.get_roles()) {
477-
permissions = channel.merge_permission_overwrites(permissions, role);
478-
}
474+
Permissions permissions = guild.get_member_permissions(member, channel);
479475

480476
bool is_admin = permissions.has_permission(DiscordCPP::Permissions::ADMINISTRATOR);
481477
bool can_delete_messages = permissions.has_permission(DiscordCPP::Permissions::MANAGE_MESSAGES);

0 commit comments

Comments
 (0)