#761 Restore permission group in sync with limbo players

- Couple AuthGroupHandler closer to the LimboService: whenever a limbo player is restored, the auth group should be restored as well. This fixes some consistency issues.
- Move AuthGroupHandler into limbo package and make it package-private
- Change permission handler to skip any empty groups (prevents odd command output e.g. for BukkitPermissions)
This commit is contained in:
ljacqu
2017-04-29 22:37:34 +02:00
parent d4c1370da6
commit e0e4cd112d
15 changed files with 47 additions and 104 deletions
@@ -0,0 +1,105 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.entity.Player;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
/**
* Changes the permission group according to the auth status of the player and the configuration.
* <p>
* If this feature is enabled, the <i>primary permissions group</i> of a player is replaced until he has
* logged in. Some permission plugins have a notion of a primary group; for other permission plugins the
* first group is simply taken.
* <p>
* The groups that are used as replacement until the player logs in is configurable and depends on if
* the player is registered or not. Note that some (all?) permission systems require the group to actually
* exist for the replacement to take place. Furthermore, since some permission groups require that players
* be in at least one group, this will mean that the player is not removed from his primary group.
*/
class AuthGroupHandler implements Reloadable {
@Inject
private PermissionsManager permissionsManager;
@Inject
private Settings settings;
private String unregisteredGroup;
private String registeredGroup;
AuthGroupHandler() {
}
/**
* Sets the group of a player by its authentication status.
*
* @param player the player
* @param limbo the associated limbo player (nullable)
* @param groupType the group type
*/
void setGroup(Player player, LimboPlayer limbo, AuthGroupType groupType) {
if (!useAuthGroups()) {
return;
}
String primaryGroup = limbo == null ? "" : limbo.getGroup();
switch (groupType) {
// Implementation note: some permission systems don't support players not being in any group,
// so add the new group before removing the old ones
case UNREGISTERED:
permissionsManager.addGroup(player, unregisteredGroup);
permissionsManager.removeGroups(player, registeredGroup, primaryGroup);
break;
case REGISTERED_UNAUTHENTICATED:
permissionsManager.addGroup(player, registeredGroup);
permissionsManager.removeGroups(player, unregisteredGroup, primaryGroup);
break;
case LOGGED_IN:
permissionsManager.addGroup(player, primaryGroup);
permissionsManager.removeGroups(player, unregisteredGroup, registeredGroup);
break;
default:
throw new IllegalStateException("Encountered unhandled auth group type '" + groupType + "'");
}
ConsoleLogger.debug(() -> player.getName() + " changed to "
+ groupType + ": has groups " + permissionsManager.getGroups(player));
}
/**
* Returns whether the auth permissions group function should be used.
*
* @return true if should be used, false otherwise
*/
private boolean useAuthGroups() {
// Check whether the permissions check is enabled
if (!settings.getProperty(PluginSettings.ENABLE_PERMISSION_CHECK)) {
return false;
}
// Make sure group support is available
if (!permissionsManager.hasGroupSupport()) {
ConsoleLogger.warning("The current permissions system doesn't have group support, unable to set group!");
return false;
}
return true;
}
@Override
@PostConstruct
public void reload() {
unregisteredGroup = settings.getProperty(PluginSettings.UNREGISTERED_GROUP);
registeredGroup = settings.getProperty(PluginSettings.REGISTERED_GROUP);
}
}
@@ -0,0 +1,17 @@
package fr.xephi.authme.data.limbo;
/**
* Represents the group type based on the user's auth status.
*/
enum AuthGroupType {
/** Player does not have an account. */
UNREGISTERED,
/** Player is registered but not logged in. */
REGISTERED_UNAUTHENTICATED,
/** Player is logged in. */
LOGGED_IN
}
@@ -34,6 +34,9 @@ public class LimboService {
@Inject
private LimboPersistence persistence;
@Inject
private AuthGroupHandler authGroupHandler;
LimboService() {
}
@@ -63,6 +66,8 @@ public class LimboService {
taskManager.registerMessageTask(player, limboPlayer, isRegistered);
taskManager.registerTimeoutTask(player, limboPlayer);
helper.revokeLimboStates(player);
authGroupHandler.setGroup(player, limboPlayer,
isRegistered ? AuthGroupType.REGISTERED_UNAUTHENTICATED : AuthGroupType.UNREGISTERED);
entries.put(name, limboPlayer);
persistence.saveLimboPlayer(player, limboPlayer);
}
@@ -91,7 +96,7 @@ public class LimboService {
* Restores the limbo data and subsequently deletes the entry.
* <p>
* Note that teleportation on the player is performed by {@link fr.xephi.authme.service.TeleportationService} and
* changing the permission group is handled by {@link fr.xephi.authme.permission.AuthGroupHandler}.
* changing the permission group is handled by {@link fr.xephi.authme.data.limbo.AuthGroupHandler}.
*
* @param player the player whose data should be restored
*/
@@ -110,6 +115,7 @@ public class LimboService {
ConsoleLogger.debug("Restored LimboPlayer stats for `{0}`", lowerName);
persistence.removeLimboPlayer(player);
}
authGroupHandler.setGroup(player, limbo, AuthGroupType.LOGGED_IN);
}
/**
@@ -119,11 +125,12 @@ public class LimboService {
* @param player the player to reset the tasks for
*/
public void replaceTasksAfterRegistration(Player player) {
getLimboOrLogError(player, "reset tasks")
.ifPresent(limbo -> {
taskManager.registerTimeoutTask(player, limbo);
taskManager.registerMessageTask(player, limbo, true);
});
Optional<LimboPlayer> limboPlayer = getLimboOrLogError(player, "reset tasks");
limboPlayer.ifPresent(limbo -> {
taskManager.registerTimeoutTask(player, limbo);
taskManager.registerMessageTask(player, limbo, true);
});
authGroupHandler.setGroup(player, limboPlayer.orElse(null), AuthGroupType.REGISTERED_UNAUTHENTICATED);
}
/**
@@ -49,7 +49,7 @@ class LimboServiceHelper {
* Removes the data that is saved in a LimboPlayer from the player.
* <p>
* Note that teleportation on the player is performed by {@link fr.xephi.authme.service.TeleportationService} and
* changing the permission group is handled by {@link fr.xephi.authme.permission.AuthGroupHandler}.
* changing the permission group is handled by {@link fr.xephi.authme.data.limbo.AuthGroupHandler}.
*
* @param player the player to set defaults to
*/