package launchserver.auth.provider;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
import launcher.serialize.config.entry.BlockConfigEntry;
import launchserver.helpers.HTTPRequestHelper;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.regex.Pattern;
public class MineSocialAuthProvider extends AuthProvider
{
private static final Pattern UUID_REGEX = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})");
private static final java.net.URL URL;
static
{
try
{
URL = new URL("https://authserver.minesocial.net/authenticate");
}
catch (MalformedURLException e)
{
throw new InternalError(e);
}
}
MineSocialAuthProvider(BlockConfigEntry block)
{
super(block);
}
@Override
public AuthProviderResult auth(String login, String password, String ip) throws Throwable
{
String clientToken = UUID.randomUUID().toString().replaceAll("-", "");
// https://wiki.vg/Authentication#Payload
JsonObject request = Json.object().
add("agent", Json.object().add("name", "Minecraft").add("version", 1)).
add("username", login).add("password", getHash(password)).add("clientToken", clientToken).
add("crypto", "SHA-1");
// Verify there's no error
JsonObject response = HTTPRequestHelper.makeAuthlibRequest(URL, request, "MineSocial");
if (response == null)
{
authError("Empty MineSocial Provider response");
}
JsonValue errorMessage = response.get("errorMessage");
if (errorMessage != null)
{
authError(errorMessage.asString());
}
// Parse JSON data
JsonObject selectedProfile = response.get("selectedProfile").asObject();
String username = selectedProfile.get("name").asString();
String accessToken = response.get("accessToken").asString();
UUID uuid = UUID.fromString(UUID_REGEX.matcher(selectedProfile.get("id").asString()).replaceFirst("$1-$2-$3-$4-$5"));
String launcherToken = response.get("clientToken").asString();
// We're done
return new AuthlibAuthProviderResult(username, accessToken, uuid, launcherToken);
}
@Override
public void close()
{
// Do nothing
}
/**
* Класс, отвечающий за безопасность отправляемых данных
* на сервер MineSocial.NET (ну хотя бы попытка)
*
* Функция предназначена для обертки пароля в SHA1,
* где он сверяется с BCrypt на стороне сервиса
*
* Я не могу хранить данные в открытом виде, поэтому хотя бы так.
**/
// TODO: Сверить хеш после технических работ
private static String getHash(String password)
{
try
{
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] array = md.digest(password.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);
}
return sb.toString().toLowerCase(); // На всякий случай
}
catch (NoSuchAlgorithmException e)
{
// Need?
return null;
}
}
}