diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index d796dd66..9ecc1485 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -3,7 +3,6 @@ package fr.xephi.authme; import ch.jalu.injector.Injector; import ch.jalu.injector.InjectorBuilder; import com.google.common.annotations.VisibleForTesting; -import fr.xephi.authme.api.API; import fr.xephi.authme.api.NewAPI; import fr.xephi.authme.command.CommandHandler; import fr.xephi.authme.data.auth.PlayerCache; @@ -118,10 +117,12 @@ public class AuthMe extends JavaPlugin { } /** - * Method used to obtain the plugin's api instance + * Method used to obtain the v2 plugin's api instance + * @deprecated Will be removed in 5.3! * * @return The plugin's api instance */ + @Deprecated public static NewAPI getApi() { return NewAPI.getInstance(); } @@ -263,8 +264,8 @@ public class AuthMe extends JavaPlugin { commandHandler = injector.getSingleton(CommandHandler.class); // Trigger construction of API classes; they will keep track of the singleton + injector.getSingleton(fr.xephi.authme.api.v3.AuthMeAPI.class); injector.getSingleton(NewAPI.class); - injector.getSingleton(API.class); } /** diff --git a/src/main/java/fr/xephi/authme/api/API.java b/src/main/java/fr/xephi/authme/api/API.java deleted file mode 100644 index 75e746e6..00000000 --- a/src/main/java/fr/xephi/authme/api/API.java +++ /dev/null @@ -1,168 +0,0 @@ -package fr.xephi.authme.api; - -import fr.xephi.authme.AuthMe; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.service.PluginHookService; -import fr.xephi.authme.process.Management; -import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.security.crypts.HashedPassword; -import fr.xephi.authme.service.ValidationService; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; - -import javax.inject.Inject; - -/** - * Deprecated API of AuthMe. Please use {@link NewAPI} instead. - * - * @deprecated Use {@link NewAPI} - */ -@Deprecated -@SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore -public class API { - - private static AuthMe instance; - private static DataSource dataSource; - private static PasswordSecurity passwordSecurity; - private static Management management; - private static PluginHookService pluginHookService; - private static ValidationService validationService; - - /* - * Constructor. - */ - @Inject - API(AuthMe instance, DataSource dataSource, PasswordSecurity passwordSecurity, Management management, - PluginHookService pluginHookService, ValidationService validationService) { - API.instance = instance; - API.dataSource = dataSource; - API.passwordSecurity = passwordSecurity; - API.management = management; - API.pluginHookService = pluginHookService; - API.validationService = validationService; - } - - /** - * Hook into AuthMe. - * - * @return AuthMe instance - */ - public static AuthMe hookAuthMe() { - if (instance != null) { - return instance; - } - Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin("AuthMe"); - if (plugin == null || !(plugin instanceof AuthMe)) { - return null; - } - instance = (AuthMe) plugin; - return instance; - } - - /** - * Return whether the player is authenticated. - * - * @param player The player to verify - * @return true if the player is authenticated - */ - public static boolean isAuthenticated(Player player) { - return PlayerCache.getInstance().isAuthenticated(player.getName()); - } - - /** - * Return whether the player is unrestricted. - * - * @param player The player to verify - * @return true if the player is unrestricted - */ - public static boolean isUnrestricted(Player player) { - return validationService.isUnrestricted(player.getName()); - } - - public static Location getLastLocation(Player player) { - PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase()); - - if (auth != null) { - return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); - } - return null; - } - - public static void setPlayerInventory(Player player, ItemStack[] content, ItemStack[] armor) { - player.getInventory().setContents(content); - player.getInventory().setArmorContents(armor); - } - - /** - * Check whether the given player name is registered. - * - * @param playerName The player name to verify - * @return true if player is registered - */ - public static boolean isRegistered(String playerName) { - String player = playerName.toLowerCase(); - return dataSource.isAuthAvailable(player); - } - - /** - * Check the password for the given player. - * - * @param playerName The name of the player - * @param passwordToCheck The password to check - * @return true if the password is correct, false otherwise - */ - public static boolean checkPassword(String playerName, String passwordToCheck) { - return isRegistered(playerName) && passwordSecurity.comparePassword(passwordToCheck, playerName); - } - - /** - * Register a player. - * - * @param playerName The name of the player - * @param password The password - * @return true if the player was registered correctly - */ - public static boolean registerPlayer(String playerName, String password) { - String name = playerName.toLowerCase(); - HashedPassword hashedPassword = passwordSecurity.computeHash(password, name); - if (isRegistered(name)) { - return false; - } - PlayerAuth auth = PlayerAuth.builder() - .name(name) - .password(hashedPassword) - .lastLogin(0) - .realName(playerName) - .build(); - return dataSource.saveAuth(auth); - } - - /** - * Force a player to log in. - * - * @param player The player to log in - */ - public static void forceLogin(Player player) { - management.forceLogin(player); - } - - public AuthMe getPlugin() { - return instance; - } - - /** - * Check whether the player is an NPC. - * - * @param player The player to verify - * @return true if player is an npc - */ - public boolean isNPC(Player player) { - return pluginHookService.isNpc(player); - } - -} diff --git a/src/main/java/fr/xephi/authme/api/NewAPI.java b/src/main/java/fr/xephi/authme/api/NewAPI.java index 62f1fefc..6d2dfad6 100644 --- a/src/main/java/fr/xephi/authme/api/NewAPI.java +++ b/src/main/java/fr/xephi/authme/api/NewAPI.java @@ -20,12 +20,16 @@ import java.util.ArrayList; import java.util.List; /** - * The current API of AuthMe. Recommended method of retrieving the API object: + * The v2 API of AuthMe. + * @deprecated Will be removed in 5.3! + * + * Recommended method of retrieving the API object: * - * NewAPI authmeApi = AuthMe.getApi(); + * NewAPI authmeApi = NewAPI.getInstance(); * */ @SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore +@Deprecated public class NewAPI { private static NewAPI singleton; diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeAPI.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeAPI.java new file mode 100644 index 00000000..ac5d2d9e --- /dev/null +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeAPI.java @@ -0,0 +1,261 @@ +package fr.xephi.authme.api.v3; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.data.auth.PlayerAuth; +import fr.xephi.authme.data.auth.PlayerCache; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.process.Management; +import fr.xephi.authme.process.register.executors.ApiPasswordRegisterParams; +import fr.xephi.authme.process.register.executors.RegistrationMethod; +import fr.xephi.authme.security.PasswordSecurity; +import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.service.PluginHookService; +import fr.xephi.authme.service.ValidationService; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +/** + * The current AuthMeAPI of AuthMe. + * + * Recommended method of retrieving the AuthMeAPI object: + * + * AuthMeAPI authmeApi = AuthMeAPI.getInstance(); + * + */ +@SuppressWarnings({"checkstyle:AbbreviationAsWordInName"}) // Justification: Class name cannot be changed anymore +public class AuthMeAPI { + + private static AuthMeAPI singleton; + private final AuthMe plugin; + private final PluginHookService pluginHookService; + private final DataSource dataSource; + private final PasswordSecurity passwordSecurity; + private final Management management; + private final ValidationService validationService; + private final PlayerCache playerCache; + + /* + * Constructor for NewAPI. + */ + @Inject + AuthMeAPI(AuthMe plugin, PluginHookService pluginHookService, DataSource dataSource, PasswordSecurity passwordSecurity, + Management management, ValidationService validationService, PlayerCache playerCache) { + this.plugin = plugin; + this.pluginHookService = pluginHookService; + this.dataSource = dataSource; + this.passwordSecurity = passwordSecurity; + this.management = management; + this.validationService = validationService; + this.playerCache = playerCache; + AuthMeAPI.singleton = this; + } + + /** + * Get the AuthMeAPI object for AuthMe. + * + * @return The AuthMeAPI object, or null if the AuthMe plugin is not enabled or not fully initialized yet + */ + public static AuthMeAPI getInstance() { + if (singleton != null) { + return singleton; + } + // NewAPI is initialized in AuthMe#onEnable -> if singleton is null, + // it means AuthMe isn't initialized (yet) + return null; + } + + /** + * Return the plugin instance. + * + * @return The AuthMe instance + */ + public AuthMe getPlugin() { + return plugin; + } + + /** + * Gather the version number of the plugin. + * This can be used to determine whether certain AuthMeAPI features are available or not. + * + * @return Plugin version identifier as a string. + */ + public String getPluginVersion() { + return AuthMe.getPluginVersion(); + } + + /** + * Return whether the given player is authenticated. + * + * @param player The player to verify + * @return true if the player is authenticated + */ + public boolean isAuthenticated(Player player) { + return playerCache.isAuthenticated(player.getName()); + } + + /** + * Check whether the given player is an NPC. + * + * @param player The player to verify + * @return true if the player is an npc + */ + public boolean isNPC(Player player) { + return pluginHookService.isNpc(player); + } + + /** + * Check whether the given player is unrestricted. For such players, AuthMe will not require + * them to authenticate. + * + * @param player The player to verify + * @return true if the player is unrestricted + * @see fr.xephi.authme.settings.properties.RestrictionSettings#UNRESTRICTED_NAMES + */ + public boolean isUnrestricted(Player player) { + return validationService.isUnrestricted(player.getName()); + } + + /** + * Get the last location of an online player. + * + * @param player The player to process + * @return Location The location of the player + */ + public Location getLastLocation(Player player) { + PlayerAuth auth = playerCache.getAuth(player.getName()); + if (auth != null) { + return new Location(Bukkit.getWorld(auth.getWorld()), + auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); + } + return null; + } + + /** + * Return whether the player is registered. + * + * @param playerName The player name to check + * @return true if player is registered, false otherwise + */ + public boolean isRegistered(String playerName) { + String player = playerName.toLowerCase(); + return dataSource.isAuthAvailable(player); + } + + /** + * Check the password for the given player. + * + * @param playerName The player to check the password for + * @param passwordToCheck The password to check + * @return true if the password is correct, false otherwise + */ + public boolean checkPassword(String playerName, String passwordToCheck) { + return passwordSecurity.comparePassword(passwordToCheck, playerName); + } + + /** + * Register an OFFLINE/ONLINE player with the given password. + * + * @param playerName The player to register + * @param password The password to register the player with + * + * @return true if the player was registered successfully + */ + public boolean registerPlayer(String playerName, String password) { + String name = playerName.toLowerCase(); + HashedPassword result = passwordSecurity.computeHash(password, name); + if (isRegistered(name)) { + return false; + } + PlayerAuth auth = PlayerAuth.builder() + .name(name) + .password(result) + .realName(playerName) + .build(); + return dataSource.saveAuth(auth); + } + + /** + * Force a player to login, i.e. the player is logged in without needing his password. + * + * @param player The player to log in + */ + public void forceLogin(Player player) { + management.forceLogin(player); + } + + /** + * Force a player to logout. + * + * @param player The player to log out + */ + public void forceLogout(Player player) { + management.performLogout(player); + } + + /** + * Force an ONLINE player to register. + * + * @param player The player to register + * @param password The password to use + * @param autoLogin Should the player be authenticated automatically after the registration? + */ + public void forceRegister(Player player, String password, boolean autoLogin) { + management.performRegister(RegistrationMethod.API_REGISTRATION, + ApiPasswordRegisterParams.of(player, password, autoLogin)); + } + + /** + * Register an ONLINE player with the given password. + * + * @param player The player to register + * @param password The password to use + */ + public void forceRegister(Player player, String password) { + forceRegister(player, password, true); + } + + /** + * Unregister a player from AuthMe. + * + * @param player The player to unregister + */ + public void forceUnregister(Player player) { + management.performUnregisterByAdmin(null, player.getName(), player); + } + + /** + * Unregister a player from AuthMe by name. + * + * @param name the name of the player (case-insensitive) + */ + public void forceUnregister(String name) { + management.performUnregisterByAdmin(null, name, Bukkit.getPlayer(name)); + } + + /** + * Get all the registered names (lowercase) + * + * @return registered names + */ + public List getRegisteredNames() { + List registeredNames = new ArrayList<>(); + dataSource.getAllAuths().forEach(auth -> registeredNames.add(auth.getNickname())); + return registeredNames; + } + + /** + * Get all the registered real-names (original case) + * + * @return registered real-names + */ + public List getRegisteredRealNames() { + List registeredNames = new ArrayList<>(); + dataSource.getAllAuths().forEach(auth -> registeredNames.add(auth.getRealName())); + return registeredNames; + } +} diff --git a/src/test/java/fr/xephi/authme/api/NewAPITest.java b/src/test/java/fr/xephi/authme/api/AuthMeAPIv3Test.java similarity index 95% rename from src/test/java/fr/xephi/authme/api/NewAPITest.java rename to src/test/java/fr/xephi/authme/api/AuthMeAPIv3Test.java index cc3dd188..b9b23481 100644 --- a/src/test/java/fr/xephi/authme/api/NewAPITest.java +++ b/src/test/java/fr/xephi/authme/api/AuthMeAPIv3Test.java @@ -2,6 +2,7 @@ package fr.xephi.authme.api; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; +import fr.xephi.authme.api.v3.AuthMeAPI; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; @@ -35,13 +36,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; /** - * Test for {@link NewAPI}. + * Test for {@link fr.xephi.authme.api.v3.AuthMeAPI}. */ @RunWith(MockitoJUnitRunner.class) -public class NewAPITest { +public class AuthMeAPIv3Test { @InjectMocks - private NewAPI api; + private AuthMeAPI api; @Mock private AuthMe authMe; @@ -60,11 +61,11 @@ public class NewAPITest { @Test public void shouldReturnInstanceOrNull() { - NewAPI result = NewAPI.getInstance(); + AuthMeAPI result = AuthMeAPI.getInstance(); assertThat(result, sameInstance(api)); - ReflectionTestUtils.setField(NewAPI.class, null, "singleton", null); - assertThat(NewAPI.getInstance(), nullValue()); + ReflectionTestUtils.setField(AuthMeAPI.class, null, "singleton", null); + assertThat(AuthMeAPI.getInstance(), nullValue()); } @Test