diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java index 0a06e4e3..d11fd0ba 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java @@ -1,18 +1,48 @@ package pro.gravit.launchserver.auth.protect; +import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler; +import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.auth.AuthResponse; import pro.gravit.utils.helper.SecurityHelper; -public class StdProtectHandler extends ProtectHandler { - public final boolean checkSecure = true; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +public class StdProtectHandler extends ProtectHandler implements ProfilesProtectHandler { + public Map> profileWhitelist = new HashMap<>(); + public List allowUpdates = new ArrayList<>(); @Override public boolean allowGetAccessToken(AuthResponse.AuthContext context) { - return (context.authType == AuthResponse.ConnectTypes.CLIENT) && (!checkSecure || context.client.checkSign); + return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign; } @Override public void checkLaunchServerLicense() { } + + @Override + public boolean canGetProfile(ClientProfile profile, Client client) { + return canChangeProfile(profile, client); + } + + @Override + public boolean canChangeProfile(ClientProfile profile, Client client) { + return client.isAuth && client.username != null && isWhitelisted(profile.getTitle(), client.username); + } + + @Override + public boolean canGetUpdates(String updatesDirName, Client client) { + return client.profile != null && ( client.profile.getDir().equals(updatesDirName) || client.profile.getAssetDir().equals(updatesDirName) || allowUpdates.contains(updatesDirName)); + } + + public boolean isWhitelisted(String profileTitle, String username) + { + List allowedUsername = profileWhitelist.get(profileTitle); + if(allowedUsername == null) return true; + return allowedUsername.contains(username); + } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/interfaces/ProfilesProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/interfaces/ProfilesProtectHandler.java new file mode 100644 index 00000000..534cde65 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/interfaces/ProfilesProtectHandler.java @@ -0,0 +1,23 @@ +package pro.gravit.launchserver.auth.protect.interfaces; + +import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.socket.Client; + +public interface ProfilesProtectHandler { + default boolean canGetProfiles(Client client) + { + return true; + } + default boolean canGetProfile(ClientProfile profile, Client client) + { + return true; + } + default boolean canChangeProfile(ClientProfile profile, Client client) + { + return client.isAuth; + } + default boolean canGetUpdates(String updatesDirName, Client client) + { + return true; + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ProfilesResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ProfilesResponse.java index 5c00006e..cd426cd7 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ProfilesResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ProfilesResponse.java @@ -3,9 +3,14 @@ import io.netty.channel.ChannelHandlerContext; import pro.gravit.launcher.events.request.ErrorRequestEvent; import pro.gravit.launcher.events.request.ProfilesRequestEvent; +import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; +import java.util.ArrayList; +import java.util.List; + public class ProfilesResponse extends SimpleResponse { @Override public String getType() { @@ -14,10 +19,29 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (!client.checkSign && !client.isAuth) { - service.sendObject(ctx, new ErrorRequestEvent("Access denied")); + if (server.config.protectHandler instanceof ProfilesProtectHandler && !((ProfilesProtectHandler) server.config.protectHandler).canGetProfiles(client)) { + sendError("Access denied"); return; } - sendResult(new ProfilesRequestEvent(server.getProfiles())); + + List profileList; + List serverProfiles = server.getProfiles(); + if (server.config.protectHandler instanceof ProfilesProtectHandler) + { + ProfilesProtectHandler protectHandler = (ProfilesProtectHandler) server.config.protectHandler; + profileList = new ArrayList<>(4); + for(ClientProfile profile : serverProfiles) + { + if(protectHandler.canGetProfile(profile, client)) + { + profileList.add(profile); + } + } + } + else + { + profileList = serverProfiles; + } + sendResult(new ProfilesRequestEvent(profileList)); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetProfileResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetProfileResponse.java index 54111cac..5488d739 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetProfileResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/SetProfileResponse.java @@ -3,6 +3,7 @@ import io.netty.channel.ChannelHandlerContext; import pro.gravit.launcher.events.request.SetProfileRequestEvent; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.utils.HookException; @@ -19,10 +20,6 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (!client.isAuth) { - sendError("Access denied"); - return; - } try { server.authHookManager.setProfileHook.hook(this, client); } catch (HookException e) { @@ -31,6 +28,11 @@ public void execute(ChannelHandlerContext ctx, Client client) { Collection profiles = server.getProfiles(); for (ClientProfile p : profiles) { if (p.getTitle().equals(this.client)) { + if (server.config.protectHandler instanceof ProfilesProtectHandler && + ((ProfilesProtectHandler) server.config.protectHandler).canChangeProfile(p, client)) { + sendError("Access denied"); + return; + } client.profile = p; sendResult(new SetProfileRequestEvent(p)); return; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java index c3b4846b..68a21a6d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java @@ -4,6 +4,7 @@ import pro.gravit.launcher.events.request.UpdateRequestEvent; import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launchserver.auth.protect.interfaces.ProfilesProtectHandler; import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; @@ -20,7 +21,7 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) { - if (!client.isAuth || client.type != AuthResponse.ConnectTypes.CLIENT || client.profile == null) { + if (server.config.protectHandler instanceof ProfilesProtectHandler && ((ProfilesProtectHandler) server.config.protectHandler).canGetUpdates(dirName, client)) { sendError("Access denied"); return; }