test penis

This commit is contained in:
Sashegdev
2026-04-09 18:13:21 +00:00
parent d7a6eb760e
commit 8b56652a73
2 changed files with 164 additions and 138 deletions
+3
View File
@@ -13,6 +13,9 @@
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.organization.name>ZernMC</project.organization.name>
<project.inceptionYear>2026</project.inceptionYear>
<project.description>ZernMC Launcher - just a minimalistic launcher by SashegDev</project.description>
<mainClass>me.sashegdev.zernmc.launcher.Main</mainClass>
</properties>
@@ -1,44 +1,40 @@
package me.sashegdev.zernmc.launcher.auth;
import com.google.gson.*;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import me.sashegdev.zernmc.launcher.utils.Config;
import me.sashegdev.zernmc.launcher.utils.ZAnsi;
import me.sashegdev.zernmc.launcher.utils.ZHttpClient;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
public class AuthManager {
private static final Path AUTH_FILE = Config.getConfigDir().resolve("auth.json");
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(15))
.build();
private static volatile AuthSession session = null;
private static volatile UserInfo userInfo = null;
// === Роли (для совместимости) ===
// === Роли ===
public static final int ROLE_USER = 0;
public static final int ROLE_PASS_HOLDER = 1;
public static final int ROLE_MODERATOR = 2;
public static final int ROLE_ELDER = 3;
public static final int ROLE_CREATOR = 4;
// === Права доступа (синхронизировано с сервером) ===
// === Права доступа ===
public static final String PERM_VIEW_PACKS = "view_packs";
public static final String PERM_DOWNLOAD_PACK = "download_pack";
public static final String PERM_REQUEST_PASS = "request_pass";
public static boolean loadSavedSession() {
if (!Files.exists(AUTH_FILE)) return false;
@@ -48,10 +44,7 @@ public class AuthManager {
if (loaded == null || loaded.accessToken == null) return false;
session = loaded;
if (session.username != null) {
userInfo = fetchUserInfo();
}
userInfo = fetchUserInfo();
if (isAccessTokenExpired()) {
return tryRefresh();
@@ -62,6 +55,7 @@ public class AuthManager {
}
}
// ====================== АВТОРИЗАЦИЯ ======================
public static AuthResult login(String username, String password) {
return authRequest("/auth/login", username, password);
}
@@ -72,36 +66,22 @@ public class AuthManager {
private static AuthResult authRequest(String endpoint, String username, String password) {
try {
JsonObject body = new JsonObject();
body.addProperty("username", username);
body.addProperty("password", password);
String body = GSON.toJson(new LoginRequest(username, password));
SimpleHttpResponse resp = post(endpoint, body);
String jsonBody = GSON.toJson(body);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(ZHttpClient.getBaseUrl() + endpoint))
.timeout(Duration.ofSeconds(15))
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("User-Agent", "ZernMC-Launcher/1.0")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody, StandardCharsets.UTF_8))
.build();
HttpResponse<String> response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
session = GSON.fromJson(response.body(), AuthSession.class);
if (resp.statusCode() == 200) {
session = GSON.fromJson(resp.body(), AuthSession.class);
session.expiresAt = System.currentTimeMillis() / 1000L + session.expiresIn;
saveSession();
userInfo = fetchUserInfo();
return AuthResult.ok();
} else if (resp.statusCode() == 422) {
return AuthResult.fail("Ошибка валидации: " + extractError(resp.body()));
} else {
String error = extractError(response.body());
return AuthResult.fail(error);
return AuthResult.fail(extractError(resp.body()));
}
} catch (Exception e) {
e.printStackTrace();
return AuthResult.fail("Ошибка соединения: " + e.getMessage());
}
}
@@ -109,17 +89,7 @@ public class AuthManager {
public static void logout() {
if (session != null && session.refreshToken != null) {
try {
JsonObject body = new JsonObject();
body.addProperty("refresh_token", session.refreshToken);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(ZHttpClient.getBaseUrl() + "/auth/logout"))
.timeout(Duration.ofSeconds(10))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
.build();
HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
post("/auth/logout", "{\"refresh_token\":\"" + session.refreshToken + "\"}");
} catch (Exception ignored) {}
}
session = null;
@@ -139,68 +109,12 @@ public class AuthManager {
return session != null ? session.uuid : "00000000-0000-0000-0000-000000000000";
}
public static int getRole() {
return session != null ? session.role : ROLE_USER;
}
public static String getRoleName() {
return session != null ? session.roleName : "Игрок";
}
// === Основные проверки ===
public static boolean hasPass() {
if (userInfo != null) return userInfo.has_pass;
return getRole() >= ROLE_PASS_HOLDER;
}
public static boolean hasPermission(String permission) {
if (userInfo != null && userInfo.permissions != null) {
return userInfo.permissions.contains(permission);
}
// Fallback на старую систему
if (PERM_VIEW_PACKS.equals(permission) || PERM_DOWNLOAD_PACK.equals(permission)) {
return hasPass();
}
return false;
}
public static boolean canViewPacks() {
return hasPermission(PERM_VIEW_PACKS);
}
public static boolean canDownloadPacks() {
return hasPermission(PERM_DOWNLOAD_PACK);
}
public static String getAccessToken() {
if (session == null) return null;
if (session == null) return "0";
if (isAccessTokenExpired()) {
tryRefresh();
}
return session != null ? session.accessToken : null;
}
private static UserInfo fetchUserInfo() {
if (!isLoggedIn()) return null;
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(ZHttpClient.getBaseUrl() + "/admin/me"))
.timeout(Duration.ofSeconds(10))
.header("Authorization", "Bearer " + session.accessToken)
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return GSON.fromJson(response.body(), UserInfo.class);
}
} catch (Exception e) {
System.err.println("Не удалось получить информацию о пользователе: " + e.getMessage());
}
return null;
return session != null && session.accessToken != null ? session.accessToken : "0";
}
private static boolean isAccessTokenExpired() {
@@ -210,33 +124,19 @@ public class AuthManager {
private static boolean tryRefresh() {
if (session == null || session.refreshToken == null) return false;
try {
JsonObject body = new JsonObject();
body.addProperty("refresh_token", session.refreshToken);
String body = "{\"refresh_token\":\"" + session.refreshToken + "\"}";
SimpleHttpResponse resp = post("/auth/refresh", body);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(ZHttpClient.getBaseUrl() + "/auth/refresh"))
.timeout(Duration.ofSeconds(15))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
.build();
HttpResponse<String> response = HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject();
String newAccessToken = json.get("access_token").getAsString();
int expiresIn = json.get("expires_in").getAsInt();
session.accessToken = newAccessToken;
session.expiresAt = System.currentTimeMillis() / 1000L + expiresIn;
if (resp.statusCode() == 200) {
AuthSession newSession = GSON.fromJson(resp.body(), AuthSession.class);
newSession.expiresAt = System.currentTimeMillis() / 1000L + newSession.expiresIn;
session = newSession;
userInfo = fetchUserInfo();
saveSession();
userInfo = fetchUserInfo(); // обновляем информацию после рефреша
return true;
}
} catch (Exception ignored) {}
session = null;
userInfo = null;
try { Files.deleteIfExists(AUTH_FILE); } catch (Exception ignored) {}
@@ -252,19 +152,122 @@ public class AuthManager {
}
}
// ==================== ПОЛУЧЕНИЕ ИНФОРМАЦИИ О ПОЛЬЗОВАТЕЛЕ ====================
private static UserInfo fetchUserInfo() {
if (!isLoggedIn() || session.accessToken == null) return null;
try {
// Используем существующий метод ZHttpClient.get() + вручную добавляем токен
java.net.HttpURLConnection conn = null;
try {
URL url = new URL(ZHttpClient.getBaseUrl() + "/admin/me");
conn = (java.net.HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Authorization", "Bearer " + session.accessToken);
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
int responseCode = conn.getResponseCode();
if (responseCode != 200) return null;
StringBuilder response = new StringBuilder();
try (var reader = new java.io.BufferedReader(
new java.io.InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
}
return GSON.fromJson(response.toString(), UserInfo.class);
} finally {
if (conn != null) conn.disconnect();
}
} catch (Exception e) {
System.err.println("Не удалось получить UserInfo: " + e.getMessage());
return null;
}
}
// ==================== ПРОВЕРКИ ПРАВ ====================
public static boolean hasPass() {
if (userInfo != null) return userInfo.has_pass;
return getRole() >= ROLE_PASS_HOLDER;
}
public static boolean canViewPacks() {
if (userInfo != null && userInfo.permissions != null) {
return userInfo.permissions.contains(PERM_VIEW_PACKS);
}
return hasPass(); // fallback для старых аккаунтов
}
public static boolean canDownloadPacks() {
if (userInfo != null && userInfo.permissions != null) {
return userInfo.permissions.contains(PERM_DOWNLOAD_PACK);
}
return hasPass(); // fallback
}
public static int getRole() {
return session != null ? session.role : ROLE_USER;
}
// ====================== POST ======================
private static SimpleHttpResponse post(String endpoint, String jsonBody) throws Exception {
String fullUrl = ZHttpClient.getBaseUrl() + endpoint;
HttpURLConnection conn = null;
try {
URL url = new URL(fullUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "ZernMC-Launcher/1.0");
conn.setRequestProperty("Connection", "close");
if (session != null && session.accessToken != null) {
conn.setRequestProperty("Authorization", "Bearer " + session.accessToken);
}
conn.setDoOutput(true);
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
byte[] input = jsonBody.getBytes(StandardCharsets.UTF_8);
conn.setFixedLengthStreamingMode(input.length);
try (var os = conn.getOutputStream()) {
os.write(input);
os.flush();
}
int statusCode = conn.getResponseCode();
var is = (statusCode >= 200 && statusCode < 300) ? conn.getInputStream() : conn.getErrorStream();
String responseBody;
try (var scanner = new java.util.Scanner(is, StandardCharsets.UTF_8.name())) {
responseBody = scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
}
return new SimpleHttpResponse(statusCode, responseBody);
} finally {
if (conn != null) conn.disconnect();
}
}
private static String extractError(String body) {
try {
JsonObject json = JsonParser.parseString(body).getAsJsonObject();
if (json.has("detail")) {
if (json.get("detail").isJsonArray()) {
return json.getAsJsonArray("detail").get(0).getAsJsonObject()
.get("msg").getAsString();
return json.getAsJsonArray("detail").get(0).getAsJsonObject().get("msg").getAsString();
}
return json.get("detail").getAsString();
}
if (json.has("error")) {
return json.get("error").getAsString();
}
} catch (Exception ignored) {}
return body.length() > 200 ? body.substring(0, 200) + "..." : body;
}
@@ -278,7 +281,6 @@ public class AuthManager {
public String username;
public String uuid;
public int role;
@SerializedName("role_name") public String roleName;
}
public static class UserInfo {
@@ -287,13 +289,20 @@ public class AuthManager {
public String uuid;
public int role;
public String role_name;
public long created_at;
public Long last_login;
public boolean has_pass;
public List<String> permissions;
public boolean hasPermission(String permission) {
return permissions != null && permissions.contains(permission);
public boolean hasPermission(String perm) {
return permissions != null && permissions.contains(perm);
}
}
private static class LoginRequest {
final String username;
final String password;
LoginRequest(String u, String p) {
this.username = u;
this.password = p;
}
}
@@ -304,4 +313,18 @@ public class AuthManager {
public static AuthResult ok() { return new AuthResult(true, null); }
public static AuthResult fail(String msg) { return new AuthResult(false, msg); }
}
}
// ====================== ВСПОМОГАТЕЛЬНЫЙ КЛАСС ======================
class SimpleHttpResponse {
final int statusCode;
final String body;
SimpleHttpResponse(int statusCode, String body) {
this.statusCode = statusCode;
this.body = body;
}
int statusCode() { return statusCode; }
String body() { return body; }
}