Skip to content

Commit

Permalink
"Fixed" permissions (#605)
Browse files Browse the repository at this point in the history
logic improvements
Add userlimit check for joining a channel instead of moving from one to another
  • Loading branch information
MinnDevelopment authored Feb 2, 2018
1 parent 9c1d83f commit c439055
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import net.dv8tion.jda.core.managers.AudioManager;
import net.dv8tion.jda.core.utils.Checks;
import net.dv8tion.jda.core.utils.NativeUtil;
import net.dv8tion.jda.core.utils.PermissionUtil;

import java.io.IOException;

Expand Down Expand Up @@ -95,6 +94,7 @@ public void openAudioConnection(VoiceChannel channel)

if (audioConnection == null)
{
checkUserlimit(channel, self);
//Start establishing connection, joining provided channel
queuedAudioConnection = channel;
api.getClient().queueAudioConnect(channel);
Expand All @@ -107,23 +107,33 @@ public void openAudioConnection(VoiceChannel channel)
if (channel.equals(audioConnection.getChannel()))
return;

final int userLimit = channel.getUserLimit(); // userLimit is 0 if no limit is set!
if (!self.isOwner() && !self.hasPermission(Permission.ADMINISTRATOR))
{
final long perms = PermissionUtil.getExplicitPermission(channel, self);
final long voicePerm = Permission.VOICE_MOVE_OTHERS.getRawValue();
if (userLimit > 0 // If there is a userlimit
&& userLimit <= channel.getMembers().size() // if that userlimit is reached
&& (perms & voicePerm) != voicePerm) // If we don't have voice move others permissions
throw new InsufficientPermissionException(Permission.VOICE_MOVE_OTHERS, // then throw exception!
"Unable to connect to VoiceChannel due to userlimit! Requires permission VOICE_MOVE_OTHERS to bypass");
}
checkUserlimit(channel, self);

api.getClient().queueAudioConnect(channel);
audioConnection.setChannel(channel);
}
}

private void checkUserlimit(VoiceChannel channel, Member self)
{
final int userLimit = channel.getUserLimit(); // userLimit is 0 if no limit is set!
if (userLimit > 0 && !self.hasPermission(Permission.ADMINISTRATOR))
{
// Check if we can actually join this channel
// - If there is a userlimit
// - If that userlimit is reached
// - If we don't have voice move others permissions
// VOICE_MOVE_OTHERS allows access because you would be able to move people out to
// open up a slot anyway
if (userLimit <= channel.getMembers().size()
&& !guild.getSelfMember().hasPermission(channel, Permission.VOICE_MOVE_OTHERS))
{
throw new InsufficientPermissionException(Permission.VOICE_MOVE_OTHERS,
"Unable to connect to VoiceChannel due to userlimit! Requires permission VOICE_MOVE_OTHERS to bypass");
}
}
}

@Override
public void closeAudioConnection()
{
Expand Down
32 changes: 18 additions & 14 deletions src/main/java/net/dv8tion/jda/core/utils/PermissionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,32 +377,36 @@ public static long getEffectivePermission(Channel channel, Member member)
return Permission.ALL_PERMISSIONS;
}

long permission = getEffectivePermission(member) | getExplicitPermission(channel, member);
if (isApplied(permission, Permission.ADMINISTRATOR.getRawValue()))
long permission = getEffectivePermission(member);
final long admin = Permission.ADMINISTRATOR.getRawValue();
if (isApplied(permission, admin))
return Permission.ALL_PERMISSIONS;

AtomicLong allow = new AtomicLong(0);
AtomicLong deny = new AtomicLong(0);

getExplicitOverrides(channel, member, allow, deny);
permission = apply(permission, allow.get(), deny.get());

if (!isApplied(permission, Permission.VIEW_CHANNEL.getRawValue()))
{
//When the permission to view the channel is not applied it is not granted
// This means that we have no access to this channel at all
return 0;
}

final long viewChannel = Permission.VIEW_CHANNEL.getRawValue();

//When the permission to view the channel is not applied it is not granted
// This means that we have no access to this channel at all
return isApplied(permission, viewChannel) ? permission : 0;
/*
// currently discord doesn't implicitly grant permissions that the user can grant others
// so instead the user has to explicitly make an override to grant them the permission in order to be granted that permission
// yes this makes no sense but what can i do, the devs don't like changing things apparently...
// I've been told half a year ago this would be changed but nothing happens
// so instead I'll just bend over for them so people get "correct" permission checks...
//
// only time will tell if something happens and I can finally re-implement this section wew
final long managePerms = Permission.MANAGE_PERMISSIONS.getRawValue();
final long manageChannel = Permission.MANAGE_CHANNEL.getRawValue();
if ((permission & (managePerms | manageChannel)) != 0)
{
// In channels, MANAGE_CHANNEL and MANAGE_PERMISSIONS grant full text/voice permissions
permission |= Permission.ALL_TEXT_PERMISSIONS | Permission.ALL_VOICE_PERMISSIONS;
}

return apply(permission, allow.get(), deny.get());
*/
}

/**
Expand Down Expand Up @@ -517,7 +521,7 @@ public static long getExplicitPermission(Channel channel, Member member)
final Guild guild = member.getGuild();
checkGuild(channel.getGuild(), guild, "Member");

long permission = guild.getPublicRole().getPermissionsRaw();
long permission = getExplicitPermission(member);

AtomicLong allow = new AtomicLong(0);
AtomicLong deny = new AtomicLong(0);
Expand Down

0 comments on commit c439055

Please sign in to comment.