diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java index 6a7e2438..ba529063 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java @@ -58,6 +58,7 @@ import java.util.zip.CRC32; public final class LaunchServer implements Runnable, AutoCloseable, Reloadable { + @Override public void reload() throws Exception { config.close(); @@ -422,6 +423,8 @@ public static void main(String... args) throws Throwable { public final SessionManager sessionManager; + public final OAuthManager cacheHandler; + public final SocketHookManager socketHookManager; public final AuthHookManager authHookManager; @@ -581,7 +584,9 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException socketHookManager = new SocketHookManager(); authHookManager = new AuthHookManager(); configManager = new ConfigManager(); + cacheHandler = new OAuthManager(); GarbageManager.registerNeedGC(sessionManager); + GarbageManager.registerNeedGC(cacheHandler); reloadManager.registerReloadable("launchServer", this); registerObject("permissionsHandler", config.permissionsHandler); for (int i = 0; i < config.auth.length; ++i) { @@ -785,7 +790,7 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException { newConfig.netty.downloadURL = "http://" + address + ":9274/%dirname%/"; newConfig.netty.launcherURL = "http://" + address + ":9274/Launcher.jar"; newConfig.netty.launcherEXEURL = "http://" + address + ":9274/Launcher.exe"; - newConfig.netty.OAuthBackURL = "https://" + address + "/OAuth.html"; + newConfig.netty.OAuthBackURL = "http://" + address + "/OAuth.html"; newConfig.netty.sendExceptionEnabled = true; // Write LaunchServer config diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/CommandHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/CommandHandler.java index 47829d21..3309d0a8 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/CommandHandler.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/CommandHandler.java @@ -88,5 +88,8 @@ public static void registerCommands(ru.gravit.utils.command.CommandHandler handl service.registerCommand("getPermissions", new GetPermissionsCommand(server)); Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components"); handler.registerCategory(serviceCategory); + + service.registerCommand("cache", new OAuthCacheHandler(server)); + service.registerCommand("token", new OAuthTokenGet(server)); } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthCacheHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthCacheHandler.java new file mode 100644 index 00000000..a5563260 --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthCacheHandler.java @@ -0,0 +1,31 @@ +package ru.gravit.launchserver.command.handler; + +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.command.Command; +import ru.gravit.launchserver.manangers.OAuthManager; +import ru.gravit.utils.helper.LogHelper; + +public final class OAuthCacheHandler extends Command { + + protected OAuthCacheHandler(LaunchServer server) { + super(server); + } + + @Override + public String getArgsDescription() { + return null; + } + + @Override + public String getUsageDescription() { + return "Debug all OAuthCache"; + } + + @Override + public void invoke(String... args) { + LogHelper.subInfo("Length of Cache " + OAuthManager.stageAreaLength()); + for(int i=0; i < OAuthManager.stageAreaLength(); i++ ){ + LogHelper.subInfo("IP is: " + LaunchServer.server.cacheHandler.stageArea[i].IP()); + } + } +} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthTokenGet.java b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthTokenGet.java new file mode 100644 index 00000000..e38bfdef --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/OAuthTokenGet.java @@ -0,0 +1,61 @@ +package ru.gravit.launchserver.command.handler; + + +import com.vk.api.sdk.client.ClientResponse; +import com.vk.api.sdk.client.TransportClient; +import com.vk.api.sdk.client.actors.UserActor; +import com.vk.api.sdk.exceptions.ApiException; +import com.vk.api.sdk.exceptions.ClientException; +import com.vk.api.sdk.httpclient.HttpTransportClient; +import com.vk.api.sdk.objects.UserAuthResponse; +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.command.Command; +import com.vk.api.sdk.client.VkApiClient; +import ru.gravit.utils.helper.LogHelper; + +import java.io.File; +import java.io.IOException; + + +public class OAuthTokenGet extends Command { + + TransportClient transportClient = new HttpTransportClient(); + VkApiClient vk = new VkApiClient(transportClient); + + protected OAuthTokenGet(LaunchServer server) { + super(server); + } + + @Override + public String getArgsDescription() { + return "Code"; + } + + @Override + public String getUsageDescription() { + return "Возвращает access token в обмен на code"; + } + + @Override + public void invoke(String... args) { + String code = args[0]; + UserAuthResponse authResponse = mToken(code, vk); + LogHelper.subInfo(authResponse.getAccessToken()); + } + + public static UserAuthResponse mToken(String code, VkApiClient vk) { + UserAuthResponse authResponse= null; + try { + authResponse = vk.oAuth(). + userAuthorizationCodeFlow(LaunchServer.server.config.OAuthAppID, + LaunchServer.server.config.OAuthAppSecret, + LaunchServer.server.config.getOAuthBackURL(), + code).execute(); + return authResponse; + } catch (ApiException e) { + e.printStackTrace(); + } catch (ClientException e) { + e.printStackTrace(); + } + } +} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/OAuthManager.java b/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/OAuthManager.java new file mode 100644 index 00000000..9e99c66c --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/manangers/OAuthManager.java @@ -0,0 +1,136 @@ +package ru.gravit.launchserver.manangers; + +import com.vk.api.sdk.actions.OAuth; +import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.NeedGarbageCollection; +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.socket.Client; +import ru.gravit.utils.helper.IOHelper; +import ru.gravit.utils.helper.LogHelper; + +import java.io.IOException; +import java.util.Timer; +import java.util.TimerTask; + +public class OAuthManager implements NeedGarbageCollection { + + @Override + public void garbageCollection() { + for(int i=0; i < 5; i++ ) + { + LaunchServer.server.cacheHandler.stageArea[i].destroy.run(); + } + LogHelper.subInfo("OAuthCache purged"); + } + + public Entry[] stageArea; + + public OAuthManager(){ + if(stageArea == null) { + stageArea = newEntryArray(); + } + } + + public static class Entry{ + + public void setEntry(Client client, ChannelHandlerContext ctx){ + if(client != null && ctx != null) { + this.init = true; + this.client = client; + this.ctx = ctx; + LogHelper.subInfo("New Entry with IP " + IP()); + this.mTimer = new Timer(); + this.mTimer.schedule(destroy, 300000L); + } + } + + public void Entry(){ + this.init = false; + this.mTimer = null; + this.client = null; + this.ctx = null; + } + + private boolean init = false; + + private Client client = null; + + private ChannelHandlerContext ctx = null; + + private Timer mTimer = null; + + public String IP(){ + return IOHelper.getIP(getCtx().channel().remoteAddress()); + } + + private TimerTask destroy = new TimerTask() { + @Override + public void run() { + if(init == false) + return; + LogHelper.info("cache purged, IP: " + IP()); + init = false; + mTimer = null; + client = null; + ctx = null; + } + }; + + public boolean isInit() { + return init; + } + + public Client getClient() { + return client; + } + + public ChannelHandlerContext getCtx() { + return ctx; + } + + } + public static int stageAreaLength(){ + int i = 0; + for(int e=0; e < 5; e++ ) + { + i += LaunchServer.server.cacheHandler.stageArea[e].isInit() ? 1 : 0; + } + return i; + } + + public static void stretchCache(Client client, ChannelHandlerContext ctx){ + getUnused().setEntry(client, ctx); + } + + public static Entry getUnused(){ + for(int i=0; i < 5; i++ ) + { + if(!LaunchServer.server.cacheHandler.stageArea[i].isInit()) + return LaunchServer.server.cacheHandler.stageArea[i]; + } + try { + throw new OAuthException("OAuth Overloaded"); + } catch (OAuthException e) { + e.printStackTrace(); + } + return null; + } + + public static Entry[] newEntryArray(){ + return new Entry[]{new Entry(), new Entry(), new Entry(), new Entry(), new Entry()}; + } + + public static final class OAuthException extends IOException { + + public OAuthException(String message) { + super(message); + } + + @Override + public String toString() { + return getMessage(); + } + } + + +} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/WebSocketService.java b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/WebSocketService.java index 7795aae9..799f7f6d 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/WebSocketService.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/WebSocketService.java @@ -162,6 +162,7 @@ public void registerClient(Channel channel) { public void registerResponses() { registerResponse("auth", AuthResponse.class); registerResponse("oauth", OAuthResponse.class); + registerResponse("OAuthURL", OAuthConfirmResponse.class); registerResponse("checkServer", CheckServerResponse.class); registerResponse("joinServer", JoinServerResponse.class); registerResponse("profiles", ProfilesResponse.class); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthConfirmResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthConfirmResponse.java new file mode 100644 index 00000000..5b6da4f9 --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthConfirmResponse.java @@ -0,0 +1,59 @@ +package ru.gravit.launchserver.websocket.json.auth; + +import com.vk.api.sdk.client.TransportClient; +import com.vk.api.sdk.client.VkApiClient; +import com.vk.api.sdk.exceptions.ApiException; +import com.vk.api.sdk.exceptions.ClientException; +import com.vk.api.sdk.httpclient.HttpTransportClient; +import com.vk.api.sdk.objects.UserAuthResponse; +import io.netty.channel.ChannelHandlerContext; + +import ru.gravit.launcher.events.request.OAuthConfirmRequestEvent; + +import ru.gravit.launchserver.LaunchServer; + +import ru.gravit.launchserver.command.handler.OAuthTokenGet; +import ru.gravit.launchserver.manangers.OAuthManager; +import ru.gravit.launchserver.socket.Client; +import ru.gravit.launchserver.websocket.json.SimpleResponse; +import ru.gravit.utils.HookException; + + +public class OAuthConfirmResponse extends SimpleResponse { + + TransportClient transportClient = new HttpTransportClient(); + VkApiClient vk = new VkApiClient(transportClient); + + public String code; + + @Override + public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception { + try { + if(code == null) { + try { + throw new OAuthManager.OAuthException("Empty code"); + }catch (OAuthManager.OAuthException e) { + sendError(e.getMessage()); + } + } + //LogHelper.debug("code get"); + + OAuthTokenGet.mToken(code, vk); + int ID = authResponse.getUserId(); + + OAuthConfirmRequestEvent result = new OAuthConfirmRequestEvent(); + result.str = "Continue in Launcher"; + sendResultAndClose(result); + + } catch (HookException e) { + sendError(e.getMessage()); + } + } + + @Override + public String getType() { + return "OAuthURL"; + } +} + + diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthResponse.java index cb313f2f..c1dd1b21 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/websocket/json/auth/OAuthResponse.java @@ -4,9 +4,11 @@ import ru.gravit.launcher.OshiHWID; import ru.gravit.launcher.events.request.OAuthRequestEvent; import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.manangers.OAuthManager; import ru.gravit.launchserver.socket.Client; import ru.gravit.launchserver.websocket.json.SimpleResponse; import ru.gravit.utils.HookException; +import ru.gravit.utils.helper.LogHelper; import java.net.MalformedURLException; import java.net.URL; @@ -18,6 +20,7 @@ public class OAuthResponse extends SimpleResponse { @Override public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception { try { + OAuthManager.stretchCache(clientData, ctx); OAuthRequestEvent result = new OAuthRequestEvent(); result.URL = getAcsessURL(); sendResult(result); @@ -27,7 +30,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti } public URL getAcsessURL() throws MalformedURLException { - String url = "https://oauth.vk.com/authorize?client_id=" + LaunchServer.server.config.OAuthAppID + "&display=page&response_type=code&v=5.69&redirect_uri=" + LaunchServer.server.config.getOAuthBackURL(); + String url = "http://oauth.vk.com/authorize?client_id=" + LaunchServer.server.config.OAuthAppID + "&display=page&scope=offline&response_type=code&v=5.69&redirect_uri=" + LaunchServer.server.config.getOAuthBackURL(); return new URL(url); } diff --git a/Launcher/runtime/dialog/dialog.js b/Launcher/runtime/dialog/dialog.js index 16ce9d2f..0cfa2fd1 100644 --- a/Launcher/runtime/dialog/dialog.js +++ b/Launcher/runtime/dialog/dialog.js @@ -70,6 +70,7 @@ function initLoginScene() { authOptions = pane.lookup("#authOptions"); pane.lookup("#goAuth").setOnAction(goAuth); + pane.lookup("#goOAuth").setOnAction(goOAuth); } /* ======== init Menu window======== */ @@ -220,6 +221,14 @@ function goAuth(event) { settings.login = login; doAuth(login, rsaPassword, authTypes[auth]); } + + function goOAuth(event) { + if (overlay.current !== null) { + return; + } + + doOAuth(); + } /* ======== Console ======== */ function goConsole(event) { @@ -298,12 +307,15 @@ function doAuth(login, rsaPassword, auth_type) { }) }); } -function goOAuth(event) { +function doOAuth() { processing.resetOverlay(); overlay.show(processing.overlay, function (event) { FunctionalBridge.getHWID.join(); makeOAuthRequest(function (result) { - openURL(result); + openURL(new java.net.URL(result.URL)); + overlay.hide(600000, function () { + setCurrentScene(menuScene); + }); return result; }) }); diff --git a/Launcher/runtime/dialog/overlay/processing/processing.js b/Launcher/runtime/dialog/overlay/processing/processing.js index 282340cf..8b89334a 100644 --- a/Launcher/runtime/dialog/overlay/processing/processing.js +++ b/Launcher/runtime/dialog/overlay/processing/processing.js @@ -122,12 +122,13 @@ function makeAuthRequest(login, rsaPassword, auth_type, callback) { startTask(task); } function makeOAuthRequest(callback) { - newRequestTask(new OAuthRequest(FunctionalBridge.getHWID())); + var task = newRequestTask(new OAuthRequest(FunctionalBridge.getHWID())); processing.setTaskProperties(task, callback, null, true); - task.updateMessage("Ожидание авторизации"); + task.updateMessage("Ожидание авторизация на сервере"); startTask(task); } + function launchClient(assetHDir, clientHDir, profile, params, callback) { var task = newTask(function() ClientLauncher.launch(assetHDir, clientHDir, profile, params, settings.debug)); diff --git a/Launcher/runtime/dialog/styles.css b/Launcher/runtime/dialog/styles.css index 3aa2b423..01c7a413 100644 --- a/Launcher/runtime/dialog/styles.css +++ b/Launcher/runtime/dialog/styles.css @@ -131,8 +131,8 @@ .vkauth { -fx-font-size: 0pt; -fx-background-image: url('images/icons/vk.png'); -fx-background-repeat: no-repeat; - -fx-pref-width: 55px; - -fx-pref-height: 55px; + -fx-pref-width: 62px; + -fx-pref-height: 62px; -fx-effect: dropshadow(gaussian, rgba(23, 25, 29, 0.3), 15,0,0,3); } diff --git a/Launcher/runtime/engine/api.js b/Launcher/runtime/engine/api.js index 8a8c393a..f2b64f55 100644 --- a/Launcher/runtime/engine/api.js +++ b/Launcher/runtime/engine/api.js @@ -17,7 +17,7 @@ var ServerPinger = ServerPingerClass.static; var Request = RequestClass.static; var RequestType = RequestTypeClass.static; var RequestException = RequestExceptionClass.static; -//var PingRequest = PingRequestClass.static; +var PingRequest = PingRequestClass.static; var AuthRequest = AuthRequestClass.static; var OAuthRequest = OAuthRequestClass.static; var JoinServerRequest = JoinServerRequestClass.static; diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java index 1436d4ea..23a05c35 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java +++ b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java @@ -65,6 +65,7 @@ public static void addLauncherClassBindings(Map bindings) { bindings.put("RequestExceptionClass", RequestException.class); bindings.put("PingRequestClass", PingRequest.class); bindings.put("AuthRequestClass", AuthRequest.class); + bindings.put("OAuthRequestClass", OAuthRequest.class); bindings.put("JoinServerRequestClass", JoinServerRequest.class); bindings.put("CheckServerRequestClass", CheckServerRequest.class); bindings.put("UpdateRequestClass", UpdateRequest.class); diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthConfirmRequestEvent.java b/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthConfirmRequestEvent.java new file mode 100644 index 00000000..1d12e2a2 --- /dev/null +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthConfirmRequestEvent.java @@ -0,0 +1,33 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.LauncherNetworkAPI; +import ru.gravit.launcher.events.RequestEvent; +import ru.gravit.utils.event.EventInterface; + +import java.util.UUID; + +public class OAuthConfirmRequestEvent extends RequestEvent implements EventInterface { + + private static final UUID uuid = UUID.fromString("77e1bfd7-adf9-4f5d-87d6-a7dd068deb74"); + + @LauncherNetworkAPI + public String str; + + @Override + public UUID getUUID() { + return uuid; + } + + @Override + public String getType() { + return "OAuthURL"; + } + + public OAuthConfirmRequestEvent(){ + } + public OAuthConfirmRequestEvent(String str){ + this.str = str; + } + + +} diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthRequestEvent.java b/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthRequestEvent.java index 3364f81b..c894dbff 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthRequestEvent.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/events/request/OAuthRequestEvent.java @@ -26,5 +26,9 @@ public String getType() { public OAuthRequestEvent(){ } + public OAuthRequestEvent(URL url){ + this.URL = url; + } + } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/OAuthRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/OAuthRequest.java index 8b52c676..1cab5f6d 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/OAuthRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/OAuthRequest.java @@ -2,21 +2,25 @@ import ru.gravit.launcher.HWID; import ru.gravit.launcher.LauncherAPI; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.events.request.AuthRequestEvent; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.websockets.RequestInterface; +import ru.gravit.utils.helper.LogHelper; public final class OAuthRequest extends Request implements RequestInterface { - private HWID hwid; + @LauncherNetworkAPI + private final HWID hwid; - @LauncherAPI public OAuthRequest(HWID hwid) { + LogHelper.info("Requesting"); this.hwid = hwid; } + @Override public String getType() { return "oauth"; } -} +} \ No newline at end of file