mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-04-01 22:14:01 +03:00
idea cleanup launchserver
This commit is contained in:
parent
37251d15a1
commit
642cec3886
37 changed files with 496 additions and 496 deletions
|
@ -17,25 +17,6 @@ public class HttpRequester {
|
|||
public HttpRequester() {
|
||||
}
|
||||
|
||||
public static class SimpleErrorHandler<T> implements HttpHelper.HttpJsonErrorHandler<T, SimpleError> {
|
||||
private final Type type;
|
||||
|
||||
private SimpleErrorHandler(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHelper.HttpOptional<T, SimpleError> applyJson(JsonElement response, int statusCode) {
|
||||
if(statusCode < 200 || statusCode >= 300) {
|
||||
return new HttpHelper.HttpOptional<>(null, Launcher.gsonManager.gson.fromJson(response, SimpleError.class), statusCode);
|
||||
}
|
||||
if(type == Void.class) {
|
||||
return new HttpHelper.HttpOptional<>(null, null, statusCode);
|
||||
}
|
||||
return new HttpHelper.HttpOptional<>(Launcher.gsonManager.gson.fromJson(response, type), null, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> SimpleErrorHandler<T> makeEH(Class<T> clazz) {
|
||||
return new SimpleErrorHandler<>(clazz);
|
||||
}
|
||||
|
@ -48,7 +29,7 @@ public <T> HttpRequest get(String url, String token) {
|
|||
.header("Content-Type", "application/json; charset=UTF-8")
|
||||
.header("Accept", "application/json")
|
||||
.timeout(Duration.ofMillis(10000));
|
||||
if(token != null) {
|
||||
if (token != null) {
|
||||
requestBuilder.header("Authorization", "Bearer ".concat(token));
|
||||
}
|
||||
return requestBuilder.build();
|
||||
|
@ -65,7 +46,7 @@ public <T> HttpRequest post(String url, T request, String token) {
|
|||
.header("Content-Type", "application/json; charset=UTF-8")
|
||||
.header("Accept", "application/json")
|
||||
.timeout(Duration.ofMillis(10000));
|
||||
if(token != null) {
|
||||
if (token != null) {
|
||||
requestBuilder.header("Authorization", "Bearer ".concat(token));
|
||||
}
|
||||
return requestBuilder.build();
|
||||
|
@ -78,6 +59,25 @@ public <T> HttpHelper.HttpOptional<T, SimpleError> send(HttpRequest request, Cla
|
|||
return HttpHelper.send(httpClient, request, makeEH(clazz));
|
||||
}
|
||||
|
||||
public static class SimpleErrorHandler<T> implements HttpHelper.HttpJsonErrorHandler<T, SimpleError> {
|
||||
private final Type type;
|
||||
|
||||
private SimpleErrorHandler(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHelper.HttpOptional<T, SimpleError> applyJson(JsonElement response, int statusCode) {
|
||||
if (statusCode < 200 || statusCode >= 300) {
|
||||
return new HttpHelper.HttpOptional<>(null, Launcher.gsonManager.gson.fromJson(response, SimpleError.class), statusCode);
|
||||
}
|
||||
if (type == Void.class) {
|
||||
return new HttpHelper.HttpOptional<>(null, null, statusCode);
|
||||
}
|
||||
return new HttpHelper.HttpOptional<>(Launcher.gsonManager.gson.fromJson(response, type), null, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleError {
|
||||
public String error;
|
||||
public int code;
|
||||
|
|
|
@ -67,7 +67,7 @@ private static void visit(ClassNode classNode, Map<String, Object> values) {
|
|||
List<MethodNode> constructors = classNode.methods.stream().filter(method -> "<init>".equals(method.name))
|
||||
.collect(Collectors.toList());
|
||||
MethodNode initMethod = constructors.stream().filter(method -> method.invisibleAnnotations != null
|
||||
&& method.invisibleAnnotations.stream().anyMatch(annotation -> INJECTED_CONSTRUCTOR_DESC.equals(annotation.desc))).findFirst()
|
||||
&& method.invisibleAnnotations.stream().anyMatch(annotation -> INJECTED_CONSTRUCTOR_DESC.equals(annotation.desc))).findFirst()
|
||||
.orElseGet(() -> constructors.stream().filter(method -> method.desc.equals("()V")).findFirst().orElse(null));
|
||||
classNode.fields.forEach(field -> {
|
||||
// Notice that fields that will be used with this algo should not have default
|
||||
|
|
|
@ -38,15 +38,6 @@ public static Set<String> getFeatures(Class<?> clazz) {
|
|||
return list;
|
||||
}
|
||||
|
||||
public void internalShowOAuthWarnMessage() {
|
||||
if(!warnOAuthShow) {
|
||||
if(!(core instanceof MySQLCoreProvider) && !(core instanceof PostgresSQLCoreProvider)) { // MySQL and PostgreSQL upgraded later
|
||||
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
||||
}
|
||||
warnOAuthShow = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void getFeatures(Class<?> clazz, Set<String> list) {
|
||||
Features features = clazz.getAnnotation(Features.class);
|
||||
if (features != null) {
|
||||
|
@ -64,6 +55,15 @@ public static void getFeatures(Class<?> clazz, Set<String> list) {
|
|||
}
|
||||
}
|
||||
|
||||
public void internalShowOAuthWarnMessage() {
|
||||
if (!warnOAuthShow) {
|
||||
if (!(core instanceof MySQLCoreProvider) && !(core instanceof PostgresSQLCoreProvider)) { // MySQL and PostgreSQL upgraded later
|
||||
logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName());
|
||||
}
|
||||
warnOAuthShow = true;
|
||||
}
|
||||
}
|
||||
|
||||
public final <T> T isSupport(Class<T> clazz) {
|
||||
if (core == null) return null;
|
||||
T result = null;
|
||||
|
|
|
@ -91,7 +91,7 @@ public Map<String, Command> getCommands() {
|
|||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
AuthRequest.AuthPasswordInterface password = null;
|
||||
if(args.length > 1) {
|
||||
if (args.length > 1) {
|
||||
if (args[1].startsWith("{")) {
|
||||
password = Launcher.gsonManager.gson.fromJson(args[1], AuthRequest.AuthPasswordInterface.class);
|
||||
} else {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
public class HttpAuthCoreProvider extends AuthCoreProvider implements AuthSupportHardware {
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
private transient HttpRequester requester;
|
||||
public String bearerToken;
|
||||
public String getUserByUsernameUrl;
|
||||
public String getUserByLoginUrl;
|
||||
|
@ -49,6 +48,7 @@ public class HttpAuthCoreProvider extends AuthCoreProvider implements AuthSuppor
|
|||
public String getUsersByHardwareInfoUrl;
|
||||
public String banHardwareUrl;
|
||||
public String unbanHardwareUrl;
|
||||
private transient HttpRequester requester;
|
||||
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
|
@ -62,7 +62,7 @@ public User getUserByUsername(String username) {
|
|||
|
||||
@Override
|
||||
public User getUserByLogin(String login) {
|
||||
if(getUserByLoginUrl != null) {
|
||||
if (getUserByLoginUrl != null) {
|
||||
try {
|
||||
return requester.send(requester.get(CommonHelper.replace(getUserByLoginUrl, "login", login), null), HttpUser.class).getOrThrow();
|
||||
} catch (IOException e) {
|
||||
|
@ -85,7 +85,7 @@ public User getUserByUUID(UUID uuid) {
|
|||
|
||||
@Override
|
||||
public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails(Client client) {
|
||||
if(getAuthDetailsUrl == null) {
|
||||
if (getAuthDetailsUrl == null) {
|
||||
return super.getDetails(client);
|
||||
}
|
||||
try {
|
||||
|
@ -99,14 +99,14 @@ public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails(
|
|||
|
||||
@Override
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||
if(getUserByTokenUrl == null) {
|
||||
if (getUserByTokenUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
var result = requester.send(requester.get(getUserByTokenUrl, accessToken), HttpUserSession.class);
|
||||
if(!result.isSuccessful()) {
|
||||
if (!result.isSuccessful()) {
|
||||
var error = result.error().error;
|
||||
if(error.equals(AuthRequestEvent.OAUTH_TOKEN_EXPIRE)) {
|
||||
if (error.equals(AuthRequestEvent.OAUTH_TOKEN_EXPIRE)) {
|
||||
throw new OAuthAccessTokenExpired();
|
||||
}
|
||||
return null;
|
||||
|
@ -120,7 +120,7 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
|
||||
@Override
|
||||
public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthResponse.AuthContext context) {
|
||||
if(refreshTokenUrl == null) {
|
||||
if (refreshTokenUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -136,9 +136,9 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
|||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
var result = requester.send(requester.post(authorizeUrl, new AuthorizeRequest(login, context, password, minecraftAccess),
|
||||
bearerToken), HttpAuthReport.class);
|
||||
if(!result.isSuccessful()) {
|
||||
if (!result.isSuccessful()) {
|
||||
var error = result.error().error;
|
||||
if(error != null) {
|
||||
if (error != null) {
|
||||
throw new AuthException(error);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c
|
|||
|
||||
@Override
|
||||
public UserHardware getHardwareInfoByPublicKey(byte[] publicKey) {
|
||||
if(getHardwareInfoByPublicKeyUrl == null) {
|
||||
if (getHardwareInfoByPublicKeyUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -161,7 +161,7 @@ public UserHardware getHardwareInfoByPublicKey(byte[] publicKey) {
|
|||
|
||||
@Override
|
||||
public UserHardware getHardwareInfoByData(HardwareReportRequest.HardwareInfo info) {
|
||||
if(getHardwareInfoByDataUrl == null) {
|
||||
if (getHardwareInfoByDataUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -179,7 +179,7 @@ public UserHardware getHardwareInfoByData(HardwareReportRequest.HardwareInfo inf
|
|||
|
||||
@Override
|
||||
public UserHardware getHardwareInfoById(String id) {
|
||||
if(getHardwareInfoByIdUrl == null) {
|
||||
if (getHardwareInfoByIdUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -193,7 +193,7 @@ public UserHardware getHardwareInfoById(String id) {
|
|||
|
||||
@Override
|
||||
public UserHardware createHardwareInfo(HardwareReportRequest.HardwareInfo info, byte[] publicKey) {
|
||||
if(createHardwareInfoUrl == null) {
|
||||
if (createHardwareInfoUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -207,7 +207,7 @@ public UserHardware createHardwareInfo(HardwareReportRequest.HardwareInfo info,
|
|||
|
||||
@Override
|
||||
public void connectUserAndHardware(UserSession userSession, UserHardware hardware) {
|
||||
if(connectUserAndHardwareUrl == null) {
|
||||
if (connectUserAndHardwareUrl == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -219,11 +219,11 @@ public void connectUserAndHardware(UserSession userSession, UserHardware hardwar
|
|||
|
||||
@Override
|
||||
public void addPublicKeyToHardwareInfo(UserHardware hardware, byte[] publicKey) {
|
||||
if(addPublicKeyToHardwareInfoUrl == null) {
|
||||
if (addPublicKeyToHardwareInfoUrl == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
requester.send(requester.post(addPublicKeyToHardwareInfoUrl, new HardwareRequest((HttpUserHardware)hardware, publicKey), bearerToken), Void.class);
|
||||
requester.send(requester.post(addPublicKeyToHardwareInfoUrl, new HardwareRequest((HttpUserHardware) hardware, publicKey), bearerToken), Void.class);
|
||||
} catch (IOException e) {
|
||||
logger.error(e);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ public void addPublicKeyToHardwareInfo(UserHardware hardware, byte[] publicKey)
|
|||
|
||||
@Override
|
||||
public Iterable<User> getUsersByHardwareInfo(UserHardware hardware) {
|
||||
if(getUsersByHardwareInfoUrl == null) {
|
||||
if (getUsersByHardwareInfoUrl == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -245,7 +245,7 @@ public Iterable<User> getUsersByHardwareInfo(UserHardware hardware) {
|
|||
|
||||
@Override
|
||||
public void banHardware(UserHardware hardware) {
|
||||
if(banHardwareUrl == null) {
|
||||
if (banHardwareUrl == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -257,7 +257,7 @@ public void banHardware(UserHardware hardware) {
|
|||
|
||||
@Override
|
||||
public void unbanHardware(UserHardware hardware) {
|
||||
if(unbanHardwareUrl == null) {
|
||||
if (unbanHardwareUrl == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -267,14 +267,6 @@ public void unbanHardware(UserHardware hardware) {
|
|||
}
|
||||
}
|
||||
|
||||
public record HttpAuthReport(String minecraftAccessToken, String oauthAccessToken,
|
||||
String oauthRefreshToken, long oauthExpire,
|
||||
HttpUserSession session) {
|
||||
public AuthManager.AuthReport toAuthReport() {
|
||||
return new AuthManager.AuthReport(minecraftAccessToken, oauthAccessToken, oauthRefreshToken, oauthExpire, session);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateServerID(User user, String serverID) throws IOException {
|
||||
var result = requester.send(requester.post(updateServerIdUrl, new UpdateServerIdRequest(user.getUsername(), user.getUUID(), serverID),
|
||||
|
@ -293,6 +285,36 @@ public boolean joinServer(Client client, String username, String accessToken, St
|
|||
return result.isSuccessful();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer server) {
|
||||
requester = new HttpRequester();
|
||||
if (getUserByUsernameUrl == null) {
|
||||
throw new IllegalArgumentException("'getUserByUsernameUrl' can't be null");
|
||||
}
|
||||
if (getUserByUUIDUrl == null) {
|
||||
throw new IllegalArgumentException("'getUserByUUIDUrl' can't be null");
|
||||
}
|
||||
if (authorizeUrl == null) {
|
||||
throw new IllegalArgumentException("'authorizeUrl' can't be null");
|
||||
}
|
||||
if (checkServerUrl == null && joinServerUrl == null && updateServerIdUrl == null) {
|
||||
throw new IllegalArgumentException("Please set 'checkServerUrl' and 'joinServerUrl' or 'updateServerIdUrl'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public record HttpAuthReport(String minecraftAccessToken, String oauthAccessToken,
|
||||
String oauthRefreshToken, long oauthExpire,
|
||||
HttpUserSession session) {
|
||||
public AuthManager.AuthReport toAuthReport() {
|
||||
return new AuthManager.AuthReport(minecraftAccessToken, oauthAccessToken, oauthRefreshToken, oauthExpire, session);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpdateServerIdRequest {
|
||||
public String username;
|
||||
public UUID uuid;
|
||||
|
@ -331,28 +353,6 @@ public JoinServerRequest(String username, String accessToken, String serverId) {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer server) {
|
||||
requester = new HttpRequester();
|
||||
if(getUserByUsernameUrl == null) {
|
||||
throw new IllegalArgumentException("'getUserByUsernameUrl' can't be null");
|
||||
}
|
||||
if(getUserByUUIDUrl == null) {
|
||||
throw new IllegalArgumentException("'getUserByUUIDUrl' can't be null");
|
||||
}
|
||||
if(authorizeUrl == null) {
|
||||
throw new IllegalArgumentException("'authorizeUrl' can't be null");
|
||||
}
|
||||
if(checkServerUrl == null && joinServerUrl == null && updateServerIdUrl == null) {
|
||||
throw new IllegalArgumentException("Please set 'checkServerUrl' and 'joinServerUrl' or 'updateServerIdUrl'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public static class AuthorizeRequest {
|
||||
public String login;
|
||||
public AuthResponse.AuthContext context;
|
||||
|
@ -400,153 +400,6 @@ public HardwareRequest(byte[] key) {
|
|||
|
||||
}
|
||||
|
||||
public class HttpUser implements User, UserSupportTextures, UserSupportProperties, UserSupportHardware {
|
||||
private String username;
|
||||
private UUID uuid;
|
||||
private String serverId;
|
||||
private String accessToken;
|
||||
private ClientPermissions permissions;
|
||||
@Deprecated
|
||||
private Texture skin;
|
||||
@Deprecated
|
||||
private Texture cloak;
|
||||
private Map<String, Texture> assets;
|
||||
private Map<String, String> properties;
|
||||
private long hwidId;
|
||||
private transient HttpUserHardware hardware;
|
||||
|
||||
public HttpUser() {
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Texture skin, Texture cloak, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Texture skin, Texture cloak, Map<String, String> properties, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.properties = properties;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Map<String, Texture> assets, Map<String, String> properties, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.assets = assets;
|
||||
this.properties = properties;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerId() {
|
||||
return serverId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientPermissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getSkinTexture() {
|
||||
if(assets == null) {
|
||||
return skin;
|
||||
}
|
||||
return assets.get("SKIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getCloakTexture() {
|
||||
if(assets == null) {
|
||||
return cloak;
|
||||
}
|
||||
return assets.get("CAPE");
|
||||
}
|
||||
|
||||
public Map<String, Texture> getAssets() {
|
||||
if(assets == null) {
|
||||
Map<String, Texture> map = new HashMap<>();
|
||||
if(skin != null) {
|
||||
map.put("SKIN", skin);
|
||||
}
|
||||
if(cloak != null) {
|
||||
map.put("CAPE", cloak);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
if(properties == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpUser{" +
|
||||
"username='" + username + '\'' +
|
||||
", uuid=" + uuid +
|
||||
", serverId='" + serverId + '\'' +
|
||||
", accessToken='" + accessToken + '\'' +
|
||||
", permissions=" + permissions +
|
||||
", assets=" + getAssets() +
|
||||
", properties=" + properties +
|
||||
", hwidId=" + hwidId +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserHardware getHardware() {
|
||||
if (hardware != null) return hardware;
|
||||
HttpAuthCoreProvider.HttpUserHardware result = (HttpUserHardware) getHardwareInfoById(String.valueOf(hwidId));
|
||||
hardware = result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HttpUserSession implements UserSession {
|
||||
private String id;
|
||||
private HttpUser user;
|
||||
|
@ -646,4 +499,151 @@ public String toString() {
|
|||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpUser implements User, UserSupportTextures, UserSupportProperties, UserSupportHardware {
|
||||
private String username;
|
||||
private UUID uuid;
|
||||
private String serverId;
|
||||
private String accessToken;
|
||||
private ClientPermissions permissions;
|
||||
@Deprecated
|
||||
private Texture skin;
|
||||
@Deprecated
|
||||
private Texture cloak;
|
||||
private Map<String, Texture> assets;
|
||||
private Map<String, String> properties;
|
||||
private long hwidId;
|
||||
private transient HttpUserHardware hardware;
|
||||
|
||||
public HttpUser() {
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Texture skin, Texture cloak, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Texture skin, Texture cloak, Map<String, String> properties, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
this.properties = properties;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
public HttpUser(String username, UUID uuid, String serverId, String accessToken, ClientPermissions permissions, Map<String, Texture> assets, Map<String, String> properties, long hwidId) {
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.serverId = serverId;
|
||||
this.accessToken = accessToken;
|
||||
this.permissions = permissions;
|
||||
this.assets = assets;
|
||||
this.properties = properties;
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerId() {
|
||||
return serverId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientPermissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getSkinTexture() {
|
||||
if (assets == null) {
|
||||
return skin;
|
||||
}
|
||||
return assets.get("SKIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Texture getCloakTexture() {
|
||||
if (assets == null) {
|
||||
return cloak;
|
||||
}
|
||||
return assets.get("CAPE");
|
||||
}
|
||||
|
||||
public Map<String, Texture> getAssets() {
|
||||
if (assets == null) {
|
||||
Map<String, Texture> map = new HashMap<>();
|
||||
if (skin != null) {
|
||||
map.put("SKIN", skin);
|
||||
}
|
||||
if (cloak != null) {
|
||||
map.put("CAPE", cloak);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getProperties() {
|
||||
if (properties == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HttpUser{" +
|
||||
"username='" + username + '\'' +
|
||||
", uuid=" + uuid +
|
||||
", serverId='" + serverId + '\'' +
|
||||
", accessToken='" + accessToken + '\'' +
|
||||
", permissions=" + permissions +
|
||||
", assets=" + getAssets() +
|
||||
", properties=" + properties +
|
||||
", hwidId=" + hwidId +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserHardware getHardware() {
|
||||
if (hardware != null) return hardware;
|
||||
HttpAuthCoreProvider.HttpUserHardware result = (HttpUserHardware) getHardwareInfoById(String.valueOf(hwidId));
|
||||
hardware = result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,15 +13,19 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MemoryAuthCoreProvider extends AuthCoreProvider {
|
||||
private transient final List<MemoryUser> memory = new ArrayList<>(16);
|
||||
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
synchronized (memory) {
|
||||
for(MemoryUser u : memory) {
|
||||
if(u.username.equals(username)) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.username.equals(username)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +43,8 @@ public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails(
|
|||
@Override
|
||||
public User getUserByUUID(UUID uuid) {
|
||||
synchronized (memory) {
|
||||
for(MemoryUser u : memory) {
|
||||
if(u.uuid.equals(uuid)) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.uuid.equals(uuid)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +55,8 @@ public User getUserByUUID(UUID uuid) {
|
|||
@Override
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||
synchronized (memory) {
|
||||
for(MemoryUser u : memory) {
|
||||
if(u.accessToken.equals(accessToken)) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.accessToken.equals(accessToken)) {
|
||||
return new MemoryUserSession(u);
|
||||
}
|
||||
}
|
||||
|
@ -67,23 +71,23 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
|||
|
||||
@Override
|
||||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
if(login == null) {
|
||||
if (login == null) {
|
||||
throw AuthException.userNotFound();
|
||||
}
|
||||
MemoryUser user = null;
|
||||
synchronized (memory) {
|
||||
for(MemoryUser u : memory) {
|
||||
if(u.username.equals(login)) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.username.equals(login)) {
|
||||
user = u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(user == null) {
|
||||
if (user == null) {
|
||||
user = new MemoryUser(login);
|
||||
memory.add(user);
|
||||
}
|
||||
}
|
||||
if(!minecraftAccess) {
|
||||
if (!minecraftAccess) {
|
||||
return AuthManager.AuthReport.ofOAuth(user.accessToken, null, 0, new MemoryUserSession(user));
|
||||
} else {
|
||||
return AuthManager.AuthReport.ofOAuthWithMinecraft(user.accessToken, user.accessToken, null, 0, new MemoryUserSession(user));
|
||||
|
@ -100,8 +104,8 @@ protected boolean updateServerID(User user, String serverID) throws IOException
|
|||
@Override
|
||||
public User checkServer(Client client, String username, String serverID) throws IOException {
|
||||
synchronized (memory) {
|
||||
for(MemoryUser u : memory) {
|
||||
if(u.username.equals(username)) {
|
||||
for (MemoryUser u : memory) {
|
||||
if (u.username.equals(username)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
import java.io.IOException;
|
||||
import java.sql.*;
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Base64;
|
||||
import java.util.LinkedList;
|
||||
|
@ -107,7 +106,7 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
try {
|
||||
var info = LegacySessionHelper.getJwtInfoFromAccessToken(accessToken, server.keyAgreementManager.ecdsaPublicKey);
|
||||
var user = (MySQLUser) getUserByUUID(info.uuid());
|
||||
if(user == null) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
return new MySQLUserSession(user);
|
||||
|
@ -121,17 +120,17 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
@Override
|
||||
public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthResponse.AuthContext context) {
|
||||
String[] parts = refreshToken.split("\\.");
|
||||
if(parts.length != 2) {
|
||||
if (parts.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String username = parts[0];
|
||||
String token = parts[1];
|
||||
var user = (MySQLUser) getUserByUsername(username);
|
||||
if(user == null || user.password == null) {
|
||||
if (user == null || user.password == null) {
|
||||
return null;
|
||||
}
|
||||
var realToken = LegacySessionHelper.makeRefreshTokenFromPassword(username, user.password, server.keyAgreementManager.legacySalt);
|
||||
if(!token.equals(realToken)) {
|
||||
if (!token.equals(realToken)) {
|
||||
return null;
|
||||
}
|
||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||
|
@ -141,15 +140,15 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
|||
@Override
|
||||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
MySQLUser mySQLUser = (MySQLUser) getUserByLogin(login);
|
||||
if(mySQLUser == null) {
|
||||
if (mySQLUser == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
if(context != null) {
|
||||
if (context != null) {
|
||||
AuthPlainPassword plainPassword = (AuthPlainPassword) password;
|
||||
if(plainPassword == null) {
|
||||
if (plainPassword == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
if(!passwordVerifier.check(mySQLUser.password, plainPassword.password)) {
|
||||
if (!passwordVerifier.check(mySQLUser.password, plainPassword.password)) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
}
|
||||
|
@ -488,6 +487,31 @@ public String toString() {
|
|||
}
|
||||
}
|
||||
|
||||
public static class MySQLUserSession implements UserSession {
|
||||
private final MySQLUser user;
|
||||
private final String id;
|
||||
|
||||
public MySQLUserSession(MySQLUser user) {
|
||||
this.user = user;
|
||||
this.id = user.username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExpireIn() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class MySQLUser implements User, UserSupportHardware {
|
||||
protected UUID uuid;
|
||||
protected String username;
|
||||
|
@ -551,29 +575,4 @@ public String toString() {
|
|||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySQLUserSession implements UserSession {
|
||||
private final MySQLUser user;
|
||||
private final String id;
|
||||
|
||||
public MySQLUserSession(MySQLUser user) {
|
||||
this.user = user;
|
||||
this.id = user.username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExpireIn() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.*;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.Clock;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
@ -85,7 +88,7 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
try {
|
||||
var info = LegacySessionHelper.getJwtInfoFromAccessToken(accessToken, server.keyAgreementManager.ecdsaPublicKey);
|
||||
var user = (PostgresSQLUser) getUserByUUID(info.uuid());
|
||||
if(user == null) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
return new PostgresSQLCoreProvider.MySQLUserSession(user);
|
||||
|
@ -99,17 +102,17 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
@Override
|
||||
public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthResponse.AuthContext context) {
|
||||
String[] parts = refreshToken.split("\\.");
|
||||
if(parts.length != 2) {
|
||||
if (parts.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String username = parts[0];
|
||||
String token = parts[1];
|
||||
var user = (PostgresSQLUser) getUserByUsername(username);
|
||||
if(user == null || user.password == null) {
|
||||
if (user == null || user.password == null) {
|
||||
return null;
|
||||
}
|
||||
var realToken = LegacySessionHelper.makeRefreshTokenFromPassword(username, user.password, server.keyAgreementManager.legacySalt);
|
||||
if(!token.equals(realToken)) {
|
||||
if (!token.equals(realToken)) {
|
||||
return null;
|
||||
}
|
||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||
|
@ -119,15 +122,15 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
|||
@Override
|
||||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
PostgresSQLUser postgresSQLUser = (PostgresSQLUser) getUserByLogin(login);
|
||||
if(postgresSQLUser == null) {
|
||||
if (postgresSQLUser == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
if(context != null) {
|
||||
if (context != null) {
|
||||
AuthPlainPassword plainPassword = (AuthPlainPassword) password;
|
||||
if(plainPassword == null) {
|
||||
if (plainPassword == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
if(!passwordVerifier.check(postgresSQLUser.password, plainPassword.password)) {
|
||||
if (!passwordVerifier.check(postgresSQLUser.password, plainPassword.password)) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
public interface UserSessionSupportKeys {
|
||||
ClientProfileKeys getClientProfileKeys();
|
||||
record ClientProfileKeys(PublicKey publicKey, PrivateKey privateKey, byte[] signature /* V2 */, long expiresAt, long refreshedAfter) {
|
||||
|
||||
record ClientProfileKeys(PublicKey publicKey, PrivateKey privateKey, byte[] signature /* V2 */, long expiresAt,
|
||||
long refreshedAfter) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ default Map<String, Texture> getUserAssets() {
|
|||
var skin = getSkinTexture();
|
||||
var cape = getCloakTexture();
|
||||
Map<String, Texture> map = new HashMap<>();
|
||||
if(skin != null) {
|
||||
if (skin != null) {
|
||||
map.put("SKIN", skin);
|
||||
}
|
||||
if(cape != null) {
|
||||
if (cape != null) {
|
||||
map.put("CAPE", cape);
|
||||
}
|
||||
return map;
|
||||
|
|
|
@ -19,29 +19,6 @@ public class JsonPasswordVerifier extends PasswordVerifier {
|
|||
public String url;
|
||||
public String bearerToken;
|
||||
|
||||
@Override
|
||||
public boolean check(String encryptedPassword, String password) {
|
||||
JsonPasswordResponse response = jsonRequest(new JsonPasswordRequest(encryptedPassword, password), url, bearerToken, JsonPasswordResponse.class, client);
|
||||
if (response != null) {
|
||||
return response.success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class JsonPasswordRequest {
|
||||
public String encryptedPassword;
|
||||
public String password;
|
||||
|
||||
public JsonPasswordRequest(String encryptedPassword, String password) {
|
||||
this.encryptedPassword = encryptedPassword;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonPasswordResponse {
|
||||
public boolean success;
|
||||
}
|
||||
|
||||
public static <T, R> R jsonRequest(T request, String url, String bearerToken, Class<R> clazz, HttpClient client) {
|
||||
HttpRequest.BodyPublisher publisher;
|
||||
if (request != null) {
|
||||
|
@ -78,4 +55,27 @@ public static <T, R> R jsonRequest(T request, String url, String bearerToken, Cl
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(String encryptedPassword, String password) {
|
||||
JsonPasswordResponse response = jsonRequest(new JsonPasswordRequest(encryptedPassword, password), url, bearerToken, JsonPasswordResponse.class, client);
|
||||
if (response != null) {
|
||||
return response.success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class JsonPasswordRequest {
|
||||
public String encryptedPassword;
|
||||
public String password;
|
||||
|
||||
public JsonPasswordRequest(String encryptedPassword, String password) {
|
||||
this.encryptedPassword = encryptedPassword;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonPasswordResponse {
|
||||
public boolean success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||
import pro.gravit.launcher.events.request.HardwareReportRequestEvent;
|
||||
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
|
||||
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||
|
@ -157,9 +156,9 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken
|
|||
var parse = parser.parseClaimsJws(extendedToken);
|
||||
String hardwareInfoId = parse.getBody().get("hardware", String.class);
|
||||
if (hardwareInfoId == null) return false;
|
||||
if(client.auth == null) return false;
|
||||
if (client.auth == null) return false;
|
||||
var hardwareSupport = client.auth.core.isSupport(AuthSupportHardware.class);
|
||||
if(hardwareSupport == null) return false;
|
||||
if (hardwareSupport == null) return false;
|
||||
UserHardware hardware = hardwareSupport.getHardwareInfoById(hardwareInfoId);
|
||||
if (client.trustLevel == null) client.trustLevel = new Client.TrustLevel();
|
||||
client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
|
||||
|
|
|
@ -27,7 +27,7 @@ public void checkLaunchServerLicense() {
|
|||
|
||||
@Override
|
||||
public void init(LaunchServer server) {
|
||||
if(profileWhitelist != null && profileWhitelist.size() > 0) {
|
||||
if (profileWhitelist != null && profileWhitelist.size() > 0) {
|
||||
logger.warn("profileWhitelist deprecated. Please use permission 'launchserver.profile.PROFILE_UUID.show' and 'launchserver.profile.PROFILE_UUID.enter'");
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +48,13 @@ public boolean canGetUpdates(String updatesDirName, Client client) {
|
|||
}
|
||||
|
||||
private boolean isWhitelisted(String property, ClientProfile profile, Client client) {
|
||||
if(client.permissions != null) {
|
||||
if (client.permissions != null) {
|
||||
String permByUUID = String.format(property, profile.getUUID());
|
||||
if(client.permissions.hasPerm(permByUUID)) {
|
||||
if (client.permissions.hasPerm(permByUUID)) {
|
||||
return true;
|
||||
}
|
||||
String permByTitle = String.format(property, profile.getTitle().toLowerCase(Locale.ROOT));
|
||||
if(client.permissions.hasPerm(permByTitle)) {
|
||||
if (client.permissions.hasPerm(permByTitle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
import java.util.UUID;
|
||||
|
||||
public class JsonTextureProvider extends TextureProvider {
|
||||
public String url;
|
||||
private transient static final Type MAP_TYPE = new TypeToken<Map<String, Texture>>() {
|
||||
}.getType();
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
private transient static final Type MAP_TYPE = new TypeToken<Map<String, Texture>>() {}.getType();
|
||||
public String url;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
@ -42,14 +43,14 @@ public Map<String, Texture> getAssets(UUID uuid, String username, String client)
|
|||
var result = HTTPRequest.jsonRequest(null, "GET", new URL(RequestTextureProvider.getTextureURL(url, uuid, username, client)));
|
||||
|
||||
Map<String, Texture> map = Launcher.gsonManager.gson.fromJson(result, MAP_TYPE);
|
||||
if(map == null) {
|
||||
if (map == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
if(map.get("skin") != null) { // Legacy script
|
||||
if (map.get("skin") != null) { // Legacy script
|
||||
map.put("SKIN", map.get("skin"));
|
||||
map.remove("skin");
|
||||
}
|
||||
if(map.get("cloak") != null) {
|
||||
if (map.get("cloak") != null) {
|
||||
map.put("CAPE", map.get("cloak"));
|
||||
map.remove("cloak");
|
||||
}
|
||||
|
|
|
@ -33,17 +33,6 @@ public static void registerProviders() {
|
|||
|
||||
public abstract Texture getSkinTexture(UUID uuid, String username, String client) throws IOException;
|
||||
|
||||
@Deprecated
|
||||
public static class SkinAndCloakTextures {
|
||||
public final Texture skin;
|
||||
public final Texture cloak;
|
||||
|
||||
public SkinAndCloakTextures(Texture skin, Texture cloak) {
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public SkinAndCloakTextures getTextures(UUID uuid, String username, String client) {
|
||||
|
||||
|
@ -83,13 +72,24 @@ public Map<String, Texture> getAssets(UUID uuid, String username, String client)
|
|||
}
|
||||
|
||||
Map<String, Texture> map = new HashMap<>();
|
||||
if(skin != null) {
|
||||
if (skin != null) {
|
||||
map.put("SKIN", skin);
|
||||
}
|
||||
if(cloak != null) {
|
||||
if (cloak != null) {
|
||||
map.put("CAPE", cloak);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static class SkinAndCloakTextures {
|
||||
public final Texture skin;
|
||||
public final Texture cloak;
|
||||
|
||||
public SkinAndCloakTextures(Texture skin, Texture cloak) {
|
||||
this.skin = skin;
|
||||
this.cloak = cloak;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,8 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
|||
try {
|
||||
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, iKeySpec);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
|
||||
InvalidAlgorithmParameterException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try (OutputStream stream = new CipherOutputStream(new NoCloseOutputStream(output), cipher)) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public static CMSSignedDataGenerator gen(LaunchServerConfig.JarSignerConf config
|
|||
return SignHelper.createSignedDataGenerator(c,
|
||||
config.keyAlias, config.signAlgo, config.keyPass);
|
||||
} catch (CertificateEncodingException | UnrecoverableKeyException | KeyStoreException
|
||||
| OperatorCreationException | NoSuchAlgorithmException | CMSException e) {
|
||||
| OperatorCreationException | NoSuchAlgorithmException | CMSException e) {
|
||||
logger.error("Create signedDataGenerator failed", e);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
public class DebugCommand extends Command {
|
||||
private transient Logger logger = LogManager.getLogger();
|
||||
|
||||
public DebugCommand(LaunchServer server) {
|
||||
super(server);
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ public void invoke(String... args) throws Exception {
|
|||
LoggerConfig loggerConfig = config.getLoggerConfig("pro.gravit");
|
||||
loggerConfig.setLevel(value ? Level.TRACE : Level.DEBUG);
|
||||
ctx.updateLoggers();
|
||||
if(value) {
|
||||
if (value) {
|
||||
logger.info("Log level TRACE enabled");
|
||||
} else {
|
||||
logger.info("Log level TRACE disabled");
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.Downloader;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import proguard.OutputWriter;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -22,11 +20,9 @@
|
|||
import java.util.List;
|
||||
|
||||
public final class DownloadAssetCommand extends Command {
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
private static final String MINECRAFT_VERSIONS_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||
|
||||
private static final String RESOURCES_DOWNLOAD_URL = "https://resources.download.minecraft.net/";
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
public DownloadAssetCommand(LaunchServer server) {
|
||||
super(server);
|
||||
|
@ -52,23 +48,23 @@ public void invoke(String... args) throws Exception {
|
|||
Path assetDir = server.updatesDir.resolve(dirName);
|
||||
|
||||
// Create asset dir
|
||||
if(Files.notExists(assetDir)) {
|
||||
if (Files.notExists(assetDir)) {
|
||||
logger.info("Creating asset dir: '{}'", dirName);
|
||||
Files.createDirectory(assetDir);
|
||||
}
|
||||
|
||||
if(type.equals("mojang")) {
|
||||
if (type.equals("mojang")) {
|
||||
HttpRequester requester = new HttpRequester();
|
||||
logger.info("Fetch versions from {}", MINECRAFT_VERSIONS_URL);
|
||||
var versions = requester.send(requester.get(MINECRAFT_VERSIONS_URL, null), MinecraftVersions.class).getOrThrow();
|
||||
String profileUrl = null;
|
||||
for(var e : versions.versions) {
|
||||
if(e.id.equals(versionName)) {
|
||||
for (var e : versions.versions) {
|
||||
if (e.id.equals(versionName)) {
|
||||
profileUrl = e.url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(profileUrl == null) {
|
||||
if (profileUrl == null) {
|
||||
logger.error("Version {} not found", versionName);
|
||||
return;
|
||||
}
|
||||
|
@ -76,30 +72,30 @@ public void invoke(String... args) throws Exception {
|
|||
var profileInfo = requester.send(requester.get(profileUrl, null), MiniVersion.class).getOrThrow();
|
||||
String assetsIndexUrl = profileInfo.assetIndex.url;
|
||||
String assetIndex = profileInfo.assetIndex.id;
|
||||
Path indexPath = assetDir.resolve("indexes").resolve(assetIndex+".json");
|
||||
Path indexPath = assetDir.resolve("indexes").resolve(assetIndex + ".json");
|
||||
logger.info("Fetch asset index {} from {}", assetIndex, assetsIndexUrl);
|
||||
JsonObject assets = requester.send(requester.get(assetsIndexUrl, null), JsonObject.class).getOrThrow();
|
||||
JsonObject objects = assets.get("objects").getAsJsonObject();
|
||||
try(Writer writer = IOHelper.newWriter(indexPath)) {
|
||||
try (Writer writer = IOHelper.newWriter(indexPath)) {
|
||||
logger.info("Save {}", indexPath);
|
||||
Launcher.gsonManager.configGson.toJson(assets, writer);
|
||||
}
|
||||
if(!assetIndex.equals(versionName)) {
|
||||
Path targetPath = assetDir.resolve("indexes").resolve(versionName+".json");
|
||||
if (!assetIndex.equals(versionName)) {
|
||||
Path targetPath = assetDir.resolve("indexes").resolve(versionName + ".json");
|
||||
logger.info("Copy {} into {}", indexPath, targetPath);
|
||||
Files.copy(indexPath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
List<AsyncDownloader.SizedFile> toDownload = new ArrayList<>(128);
|
||||
for(var e : objects.entrySet()) {
|
||||
for (var e : objects.entrySet()) {
|
||||
var value = e.getValue().getAsJsonObject();
|
||||
var hash = value.get("hash").getAsString();
|
||||
hash = hash.substring(0, 2) + "/" + hash;
|
||||
var size = value.get("size").getAsLong();
|
||||
var path = "objects/" + hash;
|
||||
var target = assetDir.resolve(path);
|
||||
if(Files.exists(target)) {
|
||||
if (Files.exists(target)) {
|
||||
long fileSize = Files.size(target);
|
||||
if(fileSize != size) {
|
||||
if (fileSize != size) {
|
||||
logger.warn("File {} corrupted. Size {}, expected {}", target, size, fileSize);
|
||||
} else {
|
||||
continue;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
public class TokenCommand extends Command {
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
public TokenCommand(LaunchServer server) {
|
||||
super(server);
|
||||
this.childCommands.put("info", new SubCommand("[token]", "print token info") {
|
||||
|
@ -27,16 +28,16 @@ public void invoke(String... args) throws Exception {
|
|||
public void invoke(String... args) throws Exception {
|
||||
AuthProviderPair pair = args.length > 1 ? server.config.getAuthProviderPair(args[1]) : server.config.getAuthProviderPair();
|
||||
ClientProfile profile = null;
|
||||
for(ClientProfile p : server.getProfiles()) {
|
||||
if(p.getTitle().equals(args[0]) || p.getUUID().toString().equals(args[0])) {
|
||||
for (ClientProfile p : server.getProfiles()) {
|
||||
if (p.getTitle().equals(args[0]) || p.getUUID().toString().equals(args[0])) {
|
||||
profile = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(profile == null) {
|
||||
if (profile == null) {
|
||||
logger.warn("Profile {} not found", args[0]);
|
||||
}
|
||||
if(pair == null) {
|
||||
if (pair == null) {
|
||||
logger.error("AuthId {} not found", args[1]);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
import pro.gravit.utils.helper.UnpackHelper;
|
||||
import proguard.Configuration;
|
||||
import proguard.ConfigurationParser;
|
||||
import proguard.ParseException;
|
||||
import proguard.ProGuard;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -166,9 +166,9 @@ public void verify() {
|
|||
// Mirror check
|
||||
{
|
||||
boolean updateMirror = Boolean.getBoolean("launchserver.config.disableUpdateMirror");
|
||||
if(!updateMirror) {
|
||||
for(int i=0;i < mirrors.length;++i) {
|
||||
if("https://mirror.gravit.pro/5.2.x/".equals(mirrors[i])) {
|
||||
if (!updateMirror) {
|
||||
for (int i = 0; i < mirrors.length; ++i) {
|
||||
if ("https://mirror.gravit.pro/5.2.x/".equals(mirrors[i])) {
|
||||
logger.warn("Replace mirror 'https://mirror.gravit.pro/5.2.x/' to 'https://mirror.gravit.pro/5.3.x/'. If you really need to use original url, use '-Dlaunchserver.config.disableUpdateMirror=true'");
|
||||
mirrors[i] = "https://mirror.gravit.pro/5.3.x/";
|
||||
}
|
||||
|
|
|
@ -23,11 +23,61 @@
|
|||
|
||||
public final class HttpHelper {
|
||||
private static transient final Logger logger = LogManager.getLogger();
|
||||
|
||||
private HttpHelper() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public static class HttpOptional<T,E> {
|
||||
public static <T, E> HttpOptional<T, E> send(HttpClient client, HttpRequest request, HttpErrorHandler<T, E> handler) throws IOException {
|
||||
try {
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
|
||||
return handler.apply(response);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, E> CompletableFuture<HttpOptional<T, E>> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler<T, E> handler) throws IOException {
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(handler::apply);
|
||||
}
|
||||
|
||||
public static <T> HttpResponse.BodyHandler<T> ofJsonResult(Class<T> type) {
|
||||
return ofJsonResult((Type) type);
|
||||
}
|
||||
|
||||
public static <T> HttpResponse.BodyHandler<T> ofJsonResult(Type type) {
|
||||
return new JsonBodyHandler<>(HttpResponse.BodyHandlers.ofInputStream(), (input) -> {
|
||||
try (Reader reader = new InputStreamReader(input)) {
|
||||
return Launcher.gsonManager.gson.fromJson(reader, type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> HttpRequest.BodyPublisher jsonBodyPublisher(T obj) {
|
||||
return HttpRequest.BodyPublishers.ofString(Launcher.gsonManager.gson.toJson(obj));
|
||||
}
|
||||
|
||||
|
||||
public interface HttpErrorHandler<T, E> {
|
||||
HttpOptional<T, E> apply(HttpResponse<InputStream> response);
|
||||
}
|
||||
|
||||
public interface HttpJsonErrorHandler<T, E> extends HttpErrorHandler<T, E> {
|
||||
HttpOptional<T, E> applyJson(JsonElement response, int statusCode);
|
||||
|
||||
default HttpOptional<T, E> apply(HttpResponse<InputStream> response) {
|
||||
try (Reader reader = new InputStreamReader(response.body())) {
|
||||
var element = Launcher.gsonManager.gson.fromJson(reader, JsonElement.class);
|
||||
return applyJson(element, response.statusCode());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class HttpOptional<T, E> {
|
||||
protected final T result;
|
||||
protected final E error;
|
||||
protected final int statusCode;
|
||||
|
@ -41,17 +91,21 @@ public HttpOptional(T result, E error, int statusCode) {
|
|||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public E error() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public int statusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return statusCode >= 200 && statusCode < 300;
|
||||
}
|
||||
|
||||
public T getOrThrow() throws RequestException {
|
||||
if(isSuccessful()) {
|
||||
if (isSuccessful()) {
|
||||
return result;
|
||||
} else {
|
||||
throw new RequestException(error == null ? String.format("statusCode %d", statusCode) : error.toString());
|
||||
|
@ -59,22 +113,6 @@ public T getOrThrow() throws RequestException {
|
|||
}
|
||||
}
|
||||
|
||||
public interface HttpErrorHandler<T, E> {
|
||||
HttpOptional<T,E> apply(HttpResponse<InputStream> response);
|
||||
}
|
||||
|
||||
public interface HttpJsonErrorHandler<T, E> extends HttpErrorHandler<T,E> {
|
||||
HttpOptional<T,E> applyJson(JsonElement response, int statusCode);
|
||||
default HttpOptional<T,E> apply(HttpResponse<InputStream> response) {
|
||||
try(Reader reader = new InputStreamReader(response.body())) {
|
||||
var element = Launcher.gsonManager.gson.fromJson(reader, JsonElement.class);
|
||||
return applyJson(element, response.statusCode());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class BasicJsonHttpErrorHandler<T> implements HttpJsonErrorHandler<T, Void> {
|
||||
private final Class<T> type;
|
||||
|
||||
|
@ -88,38 +126,6 @@ public HttpOptional<T, Void> applyJson(JsonElement response, int statusCode) {
|
|||
}
|
||||
}
|
||||
|
||||
public static<T,E> HttpOptional<T,E> send(HttpClient client, HttpRequest request, HttpErrorHandler<T,E> handler) throws IOException {
|
||||
try {
|
||||
var response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
|
||||
return handler.apply(response);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static<T,E> CompletableFuture<HttpOptional<T,E>> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler<T,E> handler) throws IOException {
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(handler::apply);
|
||||
}
|
||||
|
||||
public static<T> HttpResponse.BodyHandler<T> ofJsonResult(Class<T> type) {
|
||||
return ofJsonResult((Type) type);
|
||||
}
|
||||
|
||||
public static<T> HttpResponse.BodyHandler<T> ofJsonResult(Type type) {
|
||||
return new JsonBodyHandler<>(HttpResponse.BodyHandlers.ofInputStream(), (input) -> {
|
||||
try(Reader reader = new InputStreamReader(input)) {
|
||||
return Launcher.gsonManager.gson.fromJson(reader, type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static<T> HttpRequest.BodyPublisher jsonBodyPublisher(T obj) {
|
||||
return HttpRequest.BodyPublishers.ofString(Launcher.gsonManager.gson.toJson(obj));
|
||||
}
|
||||
|
||||
private static class JsonBodyHandler<T> implements HttpResponse.BodyHandler<T> {
|
||||
private final HttpResponse.BodyHandler<InputStream> delegate;
|
||||
private final Function<InputStream, T> func;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Date;
|
||||
|
@ -20,7 +19,7 @@ public static String makeAccessJwtTokenFromString(User user, LocalDateTime expir
|
|||
.setSubject(user.getUsername())
|
||||
.claim("uuid", user.getUUID().toString())
|
||||
.setExpiration(Date.from(expirationTime
|
||||
.toInstant(ZoneOffset.UTC)))
|
||||
.toInstant(ZoneOffset.UTC)))
|
||||
.signWith(privateKey)
|
||||
.compact();
|
||||
}
|
||||
|
@ -38,7 +37,7 @@ public static JwtTokenInfo getJwtInfoFromAccessToken(String token, ECPublicKey p
|
|||
}
|
||||
|
||||
public static String makeRefreshTokenFromPassword(String username, String rawPassword, String secretSalt) {
|
||||
if(rawPassword == null) {
|
||||
if (rawPassword == null) {
|
||||
rawPassword = "";
|
||||
}
|
||||
return SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256,
|
||||
|
|
|
@ -18,7 +18,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
ClientProfileBuilder builder = new ClientProfileBuilder();
|
||||
builder.setVersion(version.name);
|
||||
builder.setDir(title);
|
||||
if(findOption(options, MakeProfileOptionGlobalAssets.class).isPresent()) {
|
||||
if (findOption(options, MakeProfileOptionGlobalAssets.class).isPresent()) {
|
||||
builder.setAssetDir("assets");
|
||||
} else {
|
||||
builder.setAssetDir("asset" + version.name);
|
||||
|
@ -46,10 +46,10 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
Set<OptionalFile> optionals = new HashSet<>();
|
||||
jvmArgs.add("-XX:+DisableAttachMechanism");
|
||||
// Official Mojang launcher java arguments
|
||||
if(version.compareTo(ClientProfile.Version.MC112) <= 0) {
|
||||
if (version.compareTo(ClientProfile.Version.MC112) <= 0) {
|
||||
jvmArgs.add("-XX:+UseConcMarkSweepGC");
|
||||
jvmArgs.add("-XX:+CMSIncrementalMode");
|
||||
} else if(version.compareTo(ClientProfile.Version.MC118) <= 0) { // 1.13 - 1.16.5
|
||||
} else if (version.compareTo(ClientProfile.Version.MC118) <= 0) { // 1.13 - 1.16.5
|
||||
jvmArgs.add("-XX:+UseG1GC");
|
||||
jvmArgs.add("-XX:+UnlockExperimentalVMOptions");
|
||||
} else { // 1.18+
|
||||
|
@ -236,7 +236,7 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP
|
|||
if (Files.exists(dir.resolve("libraries/forge/launchwrapper-1.12-launcherfixed.jar.jar")) || Files.exists(dir.resolve("libraries/net/minecraft/launchwrapper"))) {
|
||||
options.add(new MakeProfileOptionLaunchWrapper());
|
||||
}
|
||||
if(globalAssets) {
|
||||
if (globalAssets) {
|
||||
options.add(new MakeProfileOptionGlobalAssets());
|
||||
}
|
||||
return options.toArray(new MakeProfileOption[0]);
|
||||
|
|
|
@ -27,13 +27,7 @@
|
|||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
|
||||
public class AuthManager {
|
||||
|
@ -60,9 +54,6 @@ public String newCheckServerToken(String serverName, String authId) {
|
|||
.compact();
|
||||
}
|
||||
|
||||
public record CheckServerTokenInfo(String serverName, String authId) {
|
||||
}
|
||||
|
||||
public CheckServerTokenInfo parseCheckServerToken(String token) {
|
||||
try {
|
||||
var jwt = checkServerTokenParser.parseClaimsJws(token).getBody();
|
||||
|
@ -72,29 +63,6 @@ public CheckServerTokenInfo parseCheckServerToken(String token) {
|
|||
}
|
||||
}
|
||||
|
||||
public static class CheckServerVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||
private final LaunchServer server;
|
||||
|
||||
public CheckServerVerifier(LaunchServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Client client, AuthProviderPair pair, String extendedToken) {
|
||||
var info = server.authManager.parseCheckServerToken(extendedToken);
|
||||
if(info == null) {
|
||||
return false;
|
||||
}
|
||||
client.auth_id = info.authId;
|
||||
client.auth = server.config.getAuthProviderPair(info.authId);
|
||||
if(client.permissions == null) client.permissions = new ClientPermissions();
|
||||
client.permissions.addPerm("launchserver.checkserver");
|
||||
client.permissions.addPerm(String.format("launchserver.profile.%s.show", info.serverName));
|
||||
client.setProperty("launchserver.serverName", info.serverName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create AuthContext
|
||||
*
|
||||
|
@ -154,7 +122,7 @@ public AuthReport auth(AuthResponse.AuthContext context, AuthRequest.AuthPasswor
|
|||
String login = context.login;
|
||||
try {
|
||||
AuthReport result = provider.authorize(login, context, password, context.authType == AuthResponse.ConnectTypes.CLIENT && server.config.protectHandler.allowGetAccessToken(context));
|
||||
if(result == null || result.session == null || result.session.getUser() == null) {
|
||||
if (result == null || result.session == null || result.session.getUser() == null) {
|
||||
logger.error("AuthCoreProvider {} method 'authorize' return null", context.pair.name);
|
||||
throw new AuthException("Internal Auth Error");
|
||||
}
|
||||
|
@ -175,7 +143,7 @@ public AuthReport auth(AuthResponse.AuthContext context, AuthRequest.AuthPasswor
|
|||
* Writing authorization information to the Client object
|
||||
*/
|
||||
public void internalAuth(Client client, AuthResponse.ConnectTypes authType, AuthProviderPair pair, String username, UUID uuid, ClientPermissions permissions, boolean oauth) {
|
||||
if(!oauth) {
|
||||
if (!oauth) {
|
||||
throw new UnsupportedOperationException("Unsupported legacy session system");
|
||||
}
|
||||
client.isAuth = true;
|
||||
|
@ -265,7 +233,7 @@ public PlayerProfile getPlayerProfile(AuthProviderPair pair, UUID uuid, ClientPr
|
|||
|
||||
public PlayerProfile getPlayerProfile(AuthProviderPair pair, User user) {
|
||||
Map<String, String> properties;
|
||||
if(user instanceof UserSupportProperties userSupportProperties) {
|
||||
if (user instanceof UserSupportProperties userSupportProperties) {
|
||||
properties = userSupportProperties.getProperties();
|
||||
} else {
|
||||
properties = new HashMap<>();
|
||||
|
@ -325,6 +293,32 @@ private AuthRequest.AuthPasswordInterface tryDecryptPasswordPlain(AuthRequest.Au
|
|||
return password;
|
||||
}
|
||||
|
||||
public record CheckServerTokenInfo(String serverName, String authId) {
|
||||
}
|
||||
|
||||
public static class CheckServerVerifier implements RestoreResponse.ExtendedTokenProvider {
|
||||
private final LaunchServer server;
|
||||
|
||||
public CheckServerVerifier(LaunchServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Client client, AuthProviderPair pair, String extendedToken) {
|
||||
var info = server.authManager.parseCheckServerToken(extendedToken);
|
||||
if (info == null) {
|
||||
return false;
|
||||
}
|
||||
client.auth_id = info.authId;
|
||||
client.auth = server.config.getAuthProviderPair(info.authId);
|
||||
if (client.permissions == null) client.permissions = new ClientPermissions();
|
||||
client.permissions.addPerm("launchserver.checkserver");
|
||||
client.permissions.addPerm(String.format("launchserver.profile.%s.show", info.serverName));
|
||||
client.setProperty("launchserver.serverName", info.serverName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CheckServerReport {
|
||||
public UUID uuid;
|
||||
public User user;
|
||||
|
|
|
@ -66,7 +66,7 @@ public KeyAgreementManager(Path keyDirectory) throws IOException, InvalidKeySpec
|
|||
IOHelper.write(rsaPrivateKeyPath, rsaPrivateKey.getEncoded());
|
||||
}
|
||||
Path legacySaltPath = keyDirectory.resolve("legacySalt");
|
||||
if(IOHelper.isFile(legacySaltPath)) {
|
||||
if (IOHelper.isFile(legacySaltPath)) {
|
||||
legacySalt = new String(IOHelper.read(legacySaltPath), StandardCharsets.UTF_8);
|
||||
} else {
|
||||
legacySalt = SecurityHelper.randomStringToken();
|
||||
|
|
|
@ -33,8 +33,8 @@ public LaunchServerGsonManager(LaunchServerModulesManager modulesManager) {
|
|||
public void registerAdapters(GsonBuilder builder) {
|
||||
super.registerAdapters(builder);
|
||||
builder.registerTypeAdapterFactory(RecordTypeAdapterFactory.builder()
|
||||
.allowMissingComponentValues()
|
||||
.create());
|
||||
.allowMissingComponentValues()
|
||||
.create());
|
||||
builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers));
|
||||
builder.registerTypeAdapter(AuthCoreProvider.class, new UniversalJsonAdapter<>(AuthCoreProvider.providers));
|
||||
builder.registerTypeAdapter(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package pro.gravit.launchserver.manangers.hook;
|
||||
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.manangers.AuthManager;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
|
|
|
@ -65,12 +65,12 @@ public <T> void setProperty(String name, T object) {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public<T> T getStaticProperty(String name) {
|
||||
public <T> T getStaticProperty(String name) {
|
||||
if (staticProperties == null) staticProperties = new HashMap<>();
|
||||
return (T) staticProperties.get(name);
|
||||
}
|
||||
|
||||
public<T> void setStaticProperty(String name, T value) {
|
||||
public <T> void setStaticProperty(String name, T value) {
|
||||
if (staticProperties == null) staticProperties = new HashMap<>();
|
||||
staticProperties.put(name, value);
|
||||
}
|
||||
|
|
|
@ -93,6 +93,22 @@ public static void registerResponses() {
|
|||
providers.register("getPublicKey", GetPublicKeyResponse.class);
|
||||
}
|
||||
|
||||
public static String getIPFromContext(ChannelHandlerContext ctx) {
|
||||
var handler = ctx.pipeline().get(WebSocketFrameHandler.class);
|
||||
if (handler == null || handler.context == null || handler.context.ip == null) {
|
||||
return IOHelper.getIP(ctx.channel().remoteAddress());
|
||||
}
|
||||
return handler.context.ip;
|
||||
}
|
||||
|
||||
public static String getIPFromChannel(Channel channel) {
|
||||
var handler = channel.pipeline().get(WebSocketFrameHandler.class);
|
||||
if (handler == null || handler.context == null || handler.context.ip == null) {
|
||||
return IOHelper.getIP(channel.remoteAddress());
|
||||
}
|
||||
return handler.context.ip;
|
||||
}
|
||||
|
||||
public void forEachActiveChannels(BiConsumer<Channel, WebSocketFrameHandler> callback) {
|
||||
for (Channel channel : channels) {
|
||||
if (channel == null || channel.pipeline() == null) continue;
|
||||
|
@ -176,25 +192,9 @@ public void registerClient(Channel channel) {
|
|||
channels.add(channel);
|
||||
}
|
||||
|
||||
public static String getIPFromContext(ChannelHandlerContext ctx) {
|
||||
var handler = ctx.pipeline().get(WebSocketFrameHandler.class);
|
||||
if(handler == null || handler.context == null || handler.context.ip == null) {
|
||||
return IOHelper.getIP(ctx.channel().remoteAddress());
|
||||
}
|
||||
return handler.context.ip;
|
||||
}
|
||||
|
||||
public static String getIPFromChannel(Channel channel) {
|
||||
var handler = channel.pipeline().get(WebSocketFrameHandler.class);
|
||||
if(handler == null || handler.context == null || handler.context.ip == null) {
|
||||
return IOHelper.getIP(channel.remoteAddress());
|
||||
}
|
||||
return handler.context.ip;
|
||||
}
|
||||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise());
|
||||
|
@ -202,7 +202,7 @@ public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
|||
|
||||
public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise());
|
||||
|
@ -210,7 +210,7 @@ public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
|
|||
|
||||
public void sendObject(Channel channel, Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg);
|
||||
}
|
||||
channel.writeAndFlush(new TextWebSocketFrame(msg), channel.voidPromise());
|
||||
|
@ -218,7 +218,7 @@ public void sendObject(Channel channel, Object obj) {
|
|||
|
||||
public void sendObject(Channel channel, Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg);
|
||||
}
|
||||
channel.writeAndFlush(new TextWebSocketFrame(msg), channel.voidPromise());
|
||||
|
@ -226,7 +226,7 @@ public void sendObject(Channel channel, Object obj, Type type) {
|
|||
|
||||
public void sendObjectAll(Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to all: {}", msg);
|
||||
}
|
||||
for (Channel ch : channels) {
|
||||
|
@ -236,7 +236,7 @@ public void sendObjectAll(Object obj) {
|
|||
|
||||
public void sendObjectAll(Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to all: {}", msg);
|
||||
}
|
||||
for (Channel ch : channels) {
|
||||
|
@ -252,7 +252,7 @@ public void sendObjectToUUID(UUID userUuid, Object obj, Type type) {
|
|||
Client client = wsHandler.getClient();
|
||||
if (client == null || !userUuid.equals(client.uuid)) continue;
|
||||
String msg = gson.toJson(obj, type);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send to {}({}): {}", getIPFromChannel(ch), userUuid, msg);
|
||||
}
|
||||
ch.writeAndFlush(new TextWebSocketFrame(msg), ch.voidPromise());
|
||||
|
@ -320,7 +320,7 @@ public boolean kickByIP(String ip, boolean isClose) {
|
|||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg)).addListener(ChannelFutureListener.CLOSE);
|
||||
|
@ -328,7 +328,7 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
|||
|
||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) {
|
||||
String msg = gson.toJson(obj, type);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg);
|
||||
}
|
||||
ctx.writeAndFlush(new TextWebSocketFrame(msg)).addListener(ChannelFutureListener.CLOSE);
|
||||
|
@ -337,7 +337,7 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type)
|
|||
@Deprecated
|
||||
public void sendEvent(EventResult obj) {
|
||||
String msg = gson.toJson(obj, WebSocketEvent.class);
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Send event: {}", msg);
|
||||
}
|
||||
channels.writeAndFlush(new TextWebSocketFrame(msg), ChannelMatchers.all(), true);
|
||||
|
|
|
@ -64,7 +64,7 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
|||
logger.error("WebSocket frame handler hook error", ex);
|
||||
}
|
||||
if (frame instanceof TextWebSocketFrame) {
|
||||
if(logger.isTraceEnabled()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Message from {}: {}", context.ip == null ? IOHelper.getIP(ctx.channel().remoteAddress()) : context.ip, ((TextWebSocketFrame) frame).text());
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package pro.gravit.launchserver.socket.response.auth;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.ClientPermissions;
|
||||
import pro.gravit.launcher.events.request.AdditionalDataRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AuthResponse extends SimpleResponse {
|
||||
private transient final Logger logger = LogManager.getLogger();
|
||||
public String login;
|
||||
|
|
|
@ -31,7 +31,7 @@ public void execute(ChannelHandlerContext ctx, Client pClient) {
|
|||
try {
|
||||
server.authHookManager.checkServerHook.hook(this, pClient);
|
||||
AuthManager.CheckServerReport report = server.authManager.checkServer(pClient, username, serverID);
|
||||
if(report == null) {
|
||||
if (report == null) {
|
||||
sendError("User not verified");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public static void exit(LaunchServer server, WebSocketFrameHandler wsHandler, Ch
|
|||
Client chClient = wsHandler.getClient();
|
||||
Client newCusClient = new Client();
|
||||
newCusClient.checkSign = chClient.checkSign;
|
||||
if(chClient.staticProperties != null) {
|
||||
if (chClient.staticProperties != null) {
|
||||
newCusClient.staticProperties = new HashMap<>(chClient.staticProperties);
|
||||
}
|
||||
wsHandler.setClient(newCusClient);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.FetchClientProfileKeyRequestEvent;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportKeys;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
|
@ -22,7 +21,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
|||
}
|
||||
UserSession session = client.sessionObject;
|
||||
UserSessionSupportKeys.ClientProfileKeys keys;
|
||||
if(session instanceof UserSessionSupportKeys support) {
|
||||
if (session instanceof UserSessionSupportKeys support) {
|
||||
keys = support.getClientProfileKeys();
|
||||
} else {
|
||||
keys = server.authManager.createClientProfileKeys(client.uuid);
|
||||
|
|
Loading…
Reference in a new issue