Spigot2FA/src/main/java/eu/oskar3123/spigot2fa/handler/TFAHandler.java

219 lines
6.2 KiB
Java

package eu.oskar3123.spigot2fa.handler;
import eu.oskar3123.spigot2fa.Main;
import eu.oskar3123.spigot2fa.config.PlayersConfiguration;
import eu.oskar3123.spigot2fa.map.QRMapRenderer;
import eu.oskar3123.spigot2fa.tfa.TFA;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.map.MapView;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class TFAHandler
{
private Main plugin;
private Map<UUID, String> isInProcess = new HashMap<>();
public TFAHandler(Main plugin)
{
this.plugin = plugin;
}
public void abortAll()
{
for (Player player : Bukkit.getOnlinePlayers())
{
if (!isInProcess.containsKey(player.getUniqueId()))
{
continue;
}
isInProcess.remove(player.getUniqueId());
player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
}
}
public boolean shouldBypassCode(Player player)
{
UUID uuid = player.getUniqueId();
String ip = player.getAddress().getAddress().getHostAddress();
if (!hasEnabled2FA(uuid))
{
return true;
}
long now = new Date().getTime();
long sessionTimeInMs = plugin.configHandler.getConfig(plugin.config).getLong("2fa.sessiontime") * 60000L;
PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
if (playersData == null)
{
return true;
}
long last = playersData.getLastLogin();
String lastIp = playersData.getLastIP();
return last >= now - sessionTimeInMs && ip.equalsIgnoreCase(lastIp);
}
public void setLastLogin(Player player, Long time)
{
UUID uuid = player.getUniqueId();
String ip = player.getAddress().getAddress().getHostAddress();
if (!hasEnabled2FA(uuid))
{
return;
}
long now;
if (time == null)
{
now = new Date().getTime();
}
else
{
now = time;
}
PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
PlayersConfiguration.PlayersData newData = new PlayersConfiguration.PlayersData(uuid, playersData.getSecret(), ip, now);
if (!plugin.players.setData(uuid, newData))
{
plugin.getLogger().severe("Failed to set data");
}
}
public String formatSecret(String secret)
{
return secret.toLowerCase().replaceAll("(.{4})(?=.{4})", "$1 ");
}
public void remove2FA(UUID uuid)
{
if (!plugin.players.setData(uuid, null))
{
plugin.getLogger().severe("Failed to set data");
}
}
public boolean hasEnabled2FA(UUID uuid)
{
return plugin.players.hasData(uuid);
}
public void creatingSuccess(Player player)
{
String secret = remove(player.getUniqueId());
player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
PlayersConfiguration.PlayersData playersData = new PlayersConfiguration.PlayersData(player.getUniqueId(), secret, player.getAddress().getAddress().getHostAddress(), 0);
if (!plugin.players.setData(player.getUniqueId(), playersData))
{
plugin.getLogger().severe("Failed to set data");
}
}
public void creatingFailed(Player player)
{
remove(player.getUniqueId());
player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
}
public boolean matchCode(String secret, String code)
{
String[] actualCodes = TFA.getTOTPCodes(secret);
for (String actualCode : actualCodes)
{
if (actualCode.equalsIgnoreCase(code))
{
return true;
}
}
return false;
}
public boolean matchCode(Player player, String code)
{
return matchCode(getKey(player.getUniqueId()), code);
}
private String remove(UUID uuid)
{
return isInProcess.remove(uuid);
}
public boolean startCreating(Player player)
{
String key = TFA.getRandomSecretKey();
boolean couldShow = showQRCode(player, key);
if (couldShow)
{
isInProcess.put(player.getUniqueId(), key);
}
return couldShow;
}
private boolean showQRCode(Player player, String secret)
{
ItemStack inHand = player.getInventory().getItemInMainHand();
if (inHand != null && inHand.getType() != Material.AIR)
{
return false;
}
try
{
ItemStack map = new ItemStack(Material.FILLED_MAP);
MapView view = Bukkit.createMap(player.getWorld());
view.getRenderers().clear();
view.addRenderer(new QRMapRenderer(plugin, formatSecret(secret), player));
MapMeta mapMeta = (MapMeta) map.getItemMeta();
mapMeta.setMapId(view.getId());
map.setItemMeta(mapMeta);
player.getInventory().setItemInMainHand(map);
Location loc = player.getLocation();
loc.setPitch(90f);
player.teleport(loc);
player.sendMap(view);
return true;
}
catch (IOException e)
{
e.printStackTrace();
player.sendMessage("Failed to generate qr code");
return false;
}
}
public boolean isInProcess(UUID uuid)
{
return isInProcess.containsKey(uuid);
}
public String getKey(UUID uuid)
{
if (isInProcess.containsKey(uuid))
{
return isInProcess.get(uuid);
}
PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
if (playersData == null)
{
return null;
}
return playersData.getSecret();
}
public void stopCreating(Player player)
{
if (!isInProcess(player.getUniqueId()))
{
return;
}
isInProcess.remove(player.getUniqueId());
}
}