This commit is contained in:
Sashegdev
2026-04-09 18:03:00 +00:00
parent c6dd215e9b
commit d7a6eb760e
4 changed files with 58 additions and 52 deletions
@@ -28,13 +28,18 @@ public class AuthManager {
private static volatile AuthSession session = null; private static volatile AuthSession session = null;
private static volatile UserInfo userInfo = null; private static volatile UserInfo userInfo = null;
// Роли // === Роли (для совместимости) ===
public static final int ROLE_USER = 0; public static final int ROLE_USER = 0;
public static final int ROLE_PASS_HOLDER = 1; public static final int ROLE_PASS_HOLDER = 1;
public static final int ROLE_MODERATOR = 2; public static final int ROLE_MODERATOR = 2;
public static final int ROLE_ELDER = 3; public static final int ROLE_ELDER = 3;
public static final int ROLE_CREATOR = 4; 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() { public static boolean loadSavedSession() {
if (!Files.exists(AUTH_FILE)) return false; if (!Files.exists(AUTH_FILE)) return false;
try { try {
@@ -44,7 +49,6 @@ public class AuthManager {
session = loaded; session = loaded;
// Получаем информацию о пользователе
if (session.username != null) { if (session.username != null) {
userInfo = fetchUserInfo(); userInfo = fetchUserInfo();
} }
@@ -90,7 +94,6 @@ public class AuthManager {
session.expiresAt = System.currentTimeMillis() / 1000L + session.expiresIn; session.expiresAt = System.currentTimeMillis() / 1000L + session.expiresIn;
saveSession(); saveSession();
// Получаем информацию о пользователе
userInfo = fetchUserInfo(); userInfo = fetchUserInfo();
return AuthResult.ok(); return AuthResult.ok();
@@ -144,20 +147,29 @@ public class AuthManager {
return session != null ? session.roleName : "Игрок"; return session != null ? session.roleName : "Игрок";
} }
// === Основные проверки ===
public static boolean hasPass() { public static boolean hasPass() {
if (userInfo != null) return userInfo.has_pass;
return getRole() >= ROLE_PASS_HOLDER; return getRole() >= ROLE_PASS_HOLDER;
} }
public static boolean isModerator() { public static boolean hasPermission(String permission) {
return getRole() >= ROLE_MODERATOR; 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 isElder() { public static boolean canViewPacks() {
return getRole() >= ROLE_ELDER; return hasPermission(PERM_VIEW_PACKS);
} }
public static boolean isCreator() { public static boolean canDownloadPacks() {
return getRole() == ROLE_CREATOR; return hasPermission(PERM_DOWNLOAD_PACK);
} }
public static String getAccessToken() { public static String getAccessToken() {
@@ -220,6 +232,7 @@ public class AuthManager {
session.accessToken = newAccessToken; session.accessToken = newAccessToken;
session.expiresAt = System.currentTimeMillis() / 1000L + expiresIn; session.expiresAt = System.currentTimeMillis() / 1000L + expiresIn;
saveSession(); saveSession();
userInfo = fetchUserInfo(); // обновляем информацию после рефреша
return true; return true;
} }
} catch (Exception ignored) {} } catch (Exception ignored) {}
@@ -242,7 +255,6 @@ public class AuthManager {
private static String extractError(String body) { private static String extractError(String body) {
try { try {
JsonObject json = JsonParser.parseString(body).getAsJsonObject(); JsonObject json = JsonParser.parseString(body).getAsJsonObject();
if (json.has("detail")) { if (json.has("detail")) {
if (json.get("detail").isJsonArray()) { if (json.get("detail").isJsonArray()) {
return json.getAsJsonArray("detail").get(0).getAsJsonObject() return json.getAsJsonArray("detail").get(0).getAsJsonObject()
@@ -254,12 +266,10 @@ public class AuthManager {
return json.get("error").getAsString(); return json.get("error").getAsString();
} }
} catch (Exception ignored) {} } catch (Exception ignored) {}
return body.length() > 200 ? body.substring(0, 200) + "..." : body; return body.length() > 200 ? body.substring(0, 200) + "..." : body;
} }
// ====================== ВНУТРЕННИЕ КЛАССЫ ====================== // ====================== ВНУТРЕННИЕ КЛАССЫ ======================
public static class AuthSession { public static class AuthSession {
@SerializedName("access_token") public String accessToken; @SerializedName("access_token") public String accessToken;
@SerializedName("refresh_token") public String refreshToken; @SerializedName("refresh_token") public String refreshToken;
@@ -281,6 +291,10 @@ public class AuthManager {
public Long last_login; public Long last_login;
public boolean has_pass; public boolean has_pass;
public List<String> permissions; public List<String> permissions;
public boolean hasPermission(String permission) {
return permissions != null && permissions.contains(permission);
}
} }
public static class AuthResult { public static class AuthResult {
@@ -81,13 +81,10 @@ public class LaunchMenu {
} }
private void installServerPack() throws Exception { private void installServerPack() throws Exception {
// Проверяем наличие проходки if (!AuthManager.canDownloadPacks()) {
if (!AuthManager.hasPass()) {
ConsoleUtils.clearScreen(); ConsoleUtils.clearScreen();
System.out.println(ZAnsi.brightRed("У вас нет активной проходки!")); System.out.println(ZAnsi.brightRed("У вас нет права на скачивание сборок!"));
System.out.println(ZAnsi.white("Чтобы скачивать сборки с сервера ZernMC, необходимо активировать проходку.")); System.out.println(ZAnsi.white("Для доступа к серверным сборкам необходима активная проходка."));
System.out.println();
System.out.println(ZAnsi.white("Обратитесь к администратору для получения проходки."));
ConsoleUtils.pause(); ConsoleUtils.pause();
return; return;
} }
@@ -514,7 +511,7 @@ public class LaunchMenu {
} }
private void launchExistingInstance(Instance instance) { private void launchExistingInstance(Instance instance) {
if (instance.isServerPack() && !AuthManager.hasPass()) { if (instance.isServerPack() && !AuthManager.canDownloadPacks()) {
ConsoleUtils.clearScreen(); ConsoleUtils.clearScreen();
System.out.println(ZAnsi.brightRed("Для запуска серверной сборки требуется активная проходка!")); System.out.println(ZAnsi.brightRed("Для запуска серверной сборки требуется активная проходка!"));
ConsoleUtils.pause(); ConsoleUtils.pause();
@@ -43,6 +43,9 @@ public class PackDownloader {
if (accessToken == null) { if (accessToken == null) {
throw new IOException("Не авторизован. Требуется проходка для просмотра сборок."); throw new IOException("Не авторизован. Требуется проходка для просмотра сборок.");
} }
if (!AuthManager.canViewPacks()) {
throw new IOException("Для просмотра сборок требуется активная проходка");
}
// Используем HttpURLConnection для GET с авторизацией // Используем HttpURLConnection для GET с авторизацией
java.net.HttpURLConnection connection = null; java.net.HttpURLConnection connection = null;
@@ -313,6 +316,9 @@ public class PackDownloader {
if (accessToken == null) { if (accessToken == null) {
throw new IOException("Не авторизован. Требуется проходка для скачивания сборок."); throw new IOException("Не авторизован. Требуется проходка для скачивания сборок.");
} }
if (!AuthManager.canDownloadPacks()) {
throw new IOException("Для скачивания сборок требуется активная проходка");
}
String url = ZHttpClient.getBaseUrl() + "/pack/" + packName + "/diff"; String url = ZHttpClient.getBaseUrl() + "/pack/" + packName + "/diff";
@@ -508,17 +514,6 @@ public class PackDownloader {
return sb.toString(); return sb.toString();
} }
/**
* Парсинг даты из строки
*/
private LocalDateTime parseDateTime(String dateTimeStr) {
try {
return LocalDateTime.parse(dateTimeStr, DATE_FORMATTER);
} catch (Exception e) {
return null;
}
}
// ====================== Вложенные классы ====================== // ====================== Вложенные классы ======================
public static class PackManifest { public static class PackManifest {
+1 -1
View File
@@ -25,7 +25,7 @@ import base64
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from auth import get_current_user, router as auth_router, init_db, verify_jwt from auth import get_current_user, router as auth_router, init_db, verify_jwt
from server.roles import Permissions, has_permission from roles import Permissions, has_permission
logger = structlog.get_logger(__name__) logger = structlog.get_logger(__name__)