diff options
| author | ilotterytea <iltsu@alright.party> | 2025-01-04 18:17:36 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-01-04 18:17:36 +0500 |
| commit | 6053418526536a932f9e6ad51e648b7098eeb2da (patch) | |
| tree | ef8aebbdb5514b6dd5a4e7e9d42150f0cfe60069 /core/src | |
| parent | 7d5dc081c71d209778ad7fd05d41c9d909643af0 (diff) | |
feat: authentication system
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/kz/ilotterytea/maxon/MaxonConstants.java | 9 | ||||
| -rw-r--r-- | core/src/kz/ilotterytea/maxon/MaxonGame.java | 179 | ||||
| -rw-r--r-- | core/src/kz/ilotterytea/maxon/localization/LineId.java | 9 | ||||
| -rw-r--r-- | core/src/kz/ilotterytea/maxon/screens/MenuScreen.java | 206 | ||||
| -rw-r--r-- | core/src/kz/ilotterytea/maxon/session/SessionClient.java | 323 |
5 files changed, 632 insertions, 94 deletions
diff --git a/core/src/kz/ilotterytea/maxon/MaxonConstants.java b/core/src/kz/ilotterytea/maxon/MaxonConstants.java index 5139ccc..cab66f4 100644 --- a/core/src/kz/ilotterytea/maxon/MaxonConstants.java +++ b/core/src/kz/ilotterytea/maxon/MaxonConstants.java @@ -18,6 +18,7 @@ public class MaxonConstants { public static final String GAME_APP_PACKAGE = "kz.ilotterytea." + GAME_APP_ID; public static final String GAME_APP_URL; public static final String GAME_VERSION = "1.0.1"; + public static final Integer GAME_PROTOCOL = 1; public static final String GAME_MAIN_DEVELOPER = "ilotterytea"; public static final List<Triple<String, String, Integer>> GAME_DEVELOPERS = Arrays.asList( @@ -55,6 +56,12 @@ public class MaxonConstants { public static final DecimalFormat DECIMAL_FORMAT2 = new DecimalFormat("###,###"); public static final String GAME_VERSIONS_FILE_URL = "https://assets.ilotterytea.kz/maxon/versions.json"; + public static final String IDENTITY_BASE_URL = "https://id.ilotterytea.kz"; + public static final String IDENTITY_INVALIDATE_URL = IDENTITY_BASE_URL + "/invalidate"; + public static final String IDENTITY_VALIDATE_URL = IDENTITY_BASE_URL + "/validate"; + public static final String IDENTITY_REFRESH_URL = IDENTITY_BASE_URL + "/refresh"; + public static final String IDENTITY_AUTHENTICATION_URL = IDENTITY_BASE_URL + "/authenticate"; + public static final String IDENTITY_REGISTRATION_URL = IDENTITY_BASE_URL; public static final long DISCORD_APPLICATION_ID = 1051092609659052062L; @@ -68,7 +75,7 @@ public class MaxonConstants { for (int y = 0; y < checkers; y++) { for (int x = 0; x < checkers; x++) { - if ((x + y) % 2 == 0){ + if ((x + y) % 2 == 0) { pixmap.setColor(Color.MAGENTA); } else { pixmap.setColor(Color.BLACK); diff --git a/core/src/kz/ilotterytea/maxon/MaxonGame.java b/core/src/kz/ilotterytea/maxon/MaxonGame.java index 63de3e8..b53c510 100644 --- a/core/src/kz/ilotterytea/maxon/MaxonGame.java +++ b/core/src/kz/ilotterytea/maxon/MaxonGame.java @@ -8,93 +8,100 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import kz.ilotterytea.maxon.localization.LocalizationManager; import kz.ilotterytea.maxon.pets.PetManager; import kz.ilotterytea.maxon.screens.SplashScreen; +import kz.ilotterytea.maxon.session.SessionClient; import kz.ilotterytea.maxon.utils.GameUpdater; public class MaxonGame extends Game { - public SpriteBatch batch; - public AssetManager assetManager; - public Preferences prefs; - - private LocalizationManager locale; - private PetManager petManager; - - private DiscordActivityClient discordActivityClient; - - private static MaxonGame instance; - - public static MaxonGame getInstance() { - if (instance == null) { - instance = new MaxonGame(); - } - return instance; - } - - public PetManager getPetManager() { - return petManager; - } - - public DiscordActivityClient getDiscordActivityClient() { - return discordActivityClient; - } - - public LocalizationManager getLocale() { - return locale; - } - - public void setLocale(LocalizationManager locale) { - this.locale = locale; - } - - @Override - public void create () { - // Check the latest version - new GameUpdater().checkLatestUpdate(); - - batch = new SpriteBatch(); - prefs = Gdx.app.getPreferences(MaxonConstants.GAME_APP_PACKAGE); - locale = new LocalizationManager(Gdx.files.internal("i18n/" + prefs.getString("lang", "en_us") + ".json")); - - Gdx.graphics.setVSync(prefs.getBoolean("vsync", true)); - - if (prefs.getBoolean("fullscreen", false)) { - Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); - } else if ( - prefs.contains("width") || - prefs.contains("height") - ) { - int width = prefs.getInteger("width", 800); - - if (width < 800) { - width = 800; - prefs.putInteger("width", width); - } - - int height = prefs.getInteger("height", 600); - - if (height < 600) { - height = 600; - prefs.putInteger("height", height); - } - - prefs.flush(); - Gdx.graphics.setWindowedMode(width, height); - } - - assetManager = new AssetManager(); - petManager = new PetManager(assetManager); - - discordActivityClient = new DiscordActivityClient(); - - this.setScreen(new SplashScreen()); - } - - @Override - public void dispose () { - batch.dispose(); - for (String name : assetManager.getAssetNames()) { - assetManager.unload(name); - } - assetManager.dispose(); - discordActivityClient.dispose(); - } + public SpriteBatch batch; + public AssetManager assetManager; + public Preferences prefs; + + private LocalizationManager locale; + private PetManager petManager; + + private DiscordActivityClient discordActivityClient; + private SessionClient sessionClient; + + private static MaxonGame instance; + + public static MaxonGame getInstance() { + if (instance == null) { + instance = new MaxonGame(); + } + return instance; + } + + public PetManager getPetManager() { + return petManager; + } + + public DiscordActivityClient getDiscordActivityClient() { + return discordActivityClient; + } + + public SessionClient getSessionClient() { + return sessionClient; + } + + public LocalizationManager getLocale() { + return locale; + } + + public void setLocale(LocalizationManager locale) { + this.locale = locale; + } + + @Override + public void create() { + // Check the latest version + new GameUpdater().checkLatestUpdate(); + + sessionClient = new SessionClient(Gdx.app.getPreferences("kz.ilotterytea.SigninSession")); + batch = new SpriteBatch(); + prefs = Gdx.app.getPreferences(MaxonConstants.GAME_APP_PACKAGE); + locale = new LocalizationManager(Gdx.files.internal("i18n/" + prefs.getString("lang", "en_us") + ".json")); + + Gdx.graphics.setVSync(prefs.getBoolean("vsync", true)); + + if (prefs.getBoolean("fullscreen", false)) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else if ( + prefs.contains("width") || + prefs.contains("height") + ) { + int width = prefs.getInteger("width", 800); + + if (width < 800) { + width = 800; + prefs.putInteger("width", width); + } + + int height = prefs.getInteger("height", 600); + + if (height < 600) { + height = 600; + prefs.putInteger("height", height); + } + + prefs.flush(); + Gdx.graphics.setWindowedMode(width, height); + } + + assetManager = new AssetManager(); + petManager = new PetManager(assetManager); + + discordActivityClient = new DiscordActivityClient(); + + this.setScreen(new SplashScreen()); + } + + @Override + public void dispose() { + batch.dispose(); + for (String name : assetManager.getAssetNames()) { + assetManager.unload(name); + } + assetManager.dispose(); + discordActivityClient.dispose(); + } } diff --git a/core/src/kz/ilotterytea/maxon/localization/LineId.java b/core/src/kz/ilotterytea/maxon/localization/LineId.java index 2ef671a..23eedc1 100644 --- a/core/src/kz/ilotterytea/maxon/localization/LineId.java +++ b/core/src/kz/ilotterytea/maxon/localization/LineId.java @@ -24,6 +24,15 @@ public enum LineId { CreditsTester, CreditsMoral, + LoginTitle, + LoginUsername, + LoginPassword, + LoginRegister, + LoginSend, + LoginProcessing, + LoginButton, + LoginAuthorised, + GiftboxOpen, MinigameSlotsSpinbutton, diff --git a/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java b/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java index 43dfbca..ec60b33 100644 --- a/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java +++ b/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java @@ -1,6 +1,7 @@ package kz.ilotterytea.maxon.screens; -import com.badlogic.gdx.*; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.audio.Sound; @@ -27,7 +28,10 @@ import kz.ilotterytea.maxon.constants.SettingsConstants; import kz.ilotterytea.maxon.localization.LineId; import kz.ilotterytea.maxon.localization.LocalizationManager; import kz.ilotterytea.maxon.player.Savegame; -import kz.ilotterytea.maxon.ui.*; +import kz.ilotterytea.maxon.session.SessionClient; +import kz.ilotterytea.maxon.ui.DebugWidget; +import kz.ilotterytea.maxon.ui.SavegameWidget; +import kz.ilotterytea.maxon.ui.ShakingImageButton; import kz.ilotterytea.maxon.utils.GameUpdater; import kz.ilotterytea.maxon.utils.OsUtils; import net.mgsx.gltf.scene3d.attributes.PBRCubemapAttribute; @@ -38,14 +42,19 @@ import net.mgsx.gltf.scene3d.scene.SceneManager; import net.mgsx.gltf.scene3d.scene.SceneSkybox; import net.mgsx.gltf.scene3d.utils.EnvironmentUtil; import net.mgsx.gltf.scene3d.utils.IBLBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; public class MenuScreen implements Screen { + private static final Logger log = LoggerFactory.getLogger(MenuScreen.class); private MaxonGame game; private Stage stage; private Skin uiSkin; + private TextButton loginButton; + private Music menuMusic; private final Savegame savegame = Savegame.getInstance(); @@ -57,7 +66,8 @@ public class MenuScreen implements Screen { private Sound clickSound; private float soundVolume; - @Override public void show() { + @Override + public void show() { this.game = MaxonGame.getInstance(); game.getDiscordActivityClient().runThread(); @@ -317,7 +327,18 @@ public class MenuScreen implements Screen { } }); + // Login button + loginButton = new TextButton(game.getLocale().getLine(LineId.LoginButton), uiSkin); + loginButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + showLoginWindow(); + } + }); + if (!OsUtils.isMobile) { + rightGameControlTable.add(loginButton).padRight(16f); rightGameControlTable.add(localeButton).size(iconSize).padRight(16f); rightGameControlTable.add(musicButton).size(iconSize).padRight(16f); rightGameControlTable.add(resolutionButton).size(iconSize); @@ -384,6 +405,57 @@ public class MenuScreen implements Screen { stage.act(delta); stage.draw(); + + // Login button logic + SessionClient session = game.getSessionClient(); + if (!session.isProcessing() && !session.isAuthorised() && !loginButton.getText().equals(game.getLocale().getLine(LineId.LoginButton))) { + loginButton.setText(game.getLocale().getLine(LineId.LoginButton)); + loginButton.clearListeners(); + loginButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + showLoginWindow(); + } + + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + super.enter(event, x, y, pointer, fromActor); + loginButton.setColor(new Color(0xffffffff)); + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor) { + super.exit(event, x, y, pointer, fromActor); + loginButton.setColor(new Color(0xeeeeeeff)); + } + }); + loginButton.setStyle(uiSkin.get("default", TextButton.TextButtonStyle.class)); + loginButton.setDisabled(false); + } else if (session.isAuthorised() && !loginButton.getText().equals(game.getLocale().getFormattedLine(LineId.LoginAuthorised, session.getUsername()))) { + loginButton.setText(game.getLocale().getFormattedLine(LineId.LoginAuthorised, session.getUsername())); + loginButton.clearListeners(); + loginButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + session.invalidateToken(); + } + + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + super.enter(event, x, y, pointer, fromActor); + loginButton.setColor(new Color(0xffaaaaff)); + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor) { + super.exit(event, x, y, pointer, fromActor); + loginButton.setColor(Color.WHITE); + } + }); + loginButton.setDisabled(true); + } } @Override @@ -392,9 +464,16 @@ public class MenuScreen implements Screen { sceneManager.updateViewport(width, height); } - @Override public void pause() {} - @Override public void resume() {} - @Override public void hide() { + @Override + public void pause() { + } + + @Override + public void resume() { + } + + @Override + public void hide() { for (Timer.Task task : tasks) { task.cancel(); } @@ -403,7 +482,9 @@ public class MenuScreen implements Screen { menuMusic.stop(); dispose(); } - @Override public void dispose() { + + @Override + public void dispose() { stage.dispose(); sceneManager.dispose(); } @@ -669,4 +750,115 @@ public class MenuScreen implements Screen { }); engineCredits.add(engineImage).height(OsUtils.isMobile ? 64f : 32f).width(OsUtils.isMobile ? 360f : 180f); } + + private void showLoginWindow() { + Image bgTint = new Image(uiSkin, "halftransparentblack"); + bgTint.setFillParent(true); + stage.addActor(bgTint); + + // Table + Table table = new Table(); + table.setFillParent(true); + table.align(Align.center); + + stage.addActor(table); + + // Window + Table window = new Table(uiSkin); + window.setBackground("bg"); + window.align(Align.center); + table.add(window).size(460f, 400f); + + // Table for title and close button + Table titleTable = new Table(uiSkin); + titleTable.setBackground("bg2"); + window.add(titleTable).growX().row(); + + // Title + Label titleLabel = new Label(game.getLocale().getLine(LineId.LoginTitle), uiSkin); + titleTable.add(titleLabel).pad(8f, 16f, 8f, 16f).growX(); + + // Close button + TextButton closeButton = new TextButton(" X ", uiSkin); + closeButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + table.remove(); + bgTint.remove(); + clickSound.play(soundVolume); + } + }); + titleTable.add(closeButton).pad(8f, 16f, 8f, 16f); + + // Table for fields + Table contentTable = new Table(); + window.add(contentTable).pad(16f).grow().row(); + + // Username + Label usernameLabel = new Label(game.getLocale().getLine(LineId.LoginUsername), uiSkin); + contentTable.add(usernameLabel).grow().row(); + + TextField usernameField = new TextField("", uiSkin); + usernameField.setMessageText("..."); + usernameField.setTextFieldFilter((textField, c) -> Character.toString(c).matches("^[a-zA-Z0-9]")); + usernameField.setMaxLength(25); + contentTable.add(usernameField).padBottom(15f).grow().row(); + + // Password + Label passwordLabel = new Label(game.getLocale().getLine(LineId.LoginPassword), uiSkin); + contentTable.add(passwordLabel).grow().row(); + + TextField passwordField = new TextField("", uiSkin); + passwordField.setMessageText("..."); + + String[] passwords = {"", ""}; + + passwordField.setTextFieldListener((textField, c) -> { + String hiddenText = passwords[0]; + String fieldText = passwords[1]; + + if (c == 8 && !fieldText.isEmpty() && !hiddenText.isEmpty()) { + fieldText = fieldText.substring(0, fieldText.length() - 1); + hiddenText = hiddenText.substring(0, hiddenText.length() - 1); + } else if (c != 8) { + fieldText += '*'; + hiddenText += c; + } + + textField.setText(fieldText); + passwords[0] = hiddenText; + passwords[1] = fieldText; + }); + + contentTable.add(passwordField).grow().row(); + + // Register button + TextButton registerButton = new TextButton(game.getLocale().getLine(LineId.LoginRegister), uiSkin, "link"); + registerButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + Gdx.net.openURI(MaxonConstants.IDENTITY_REGISTRATION_URL); + } + }); + contentTable.add(registerButton).padTop(15f).padBottom(15f).grow().row(); + + // Login button + TextButton sendButton = new TextButton(game.getLocale().getLine(LineId.LoginSend), uiSkin); + sendButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + MaxonGame.getInstance().getSessionClient().authorize(usernameField.getText(), passwords[0]); + loginButton.setText(game.getLocale().getLine(LineId.LoginProcessing)); + loginButton.setDisabled(true); + // maybe we could somehow fire the close button instead of cv pasting + table.remove(); + bgTint.remove(); + clickSound.play(soundVolume); + } + }); + contentTable.add(sendButton).grow().row(); + } } diff --git a/core/src/kz/ilotterytea/maxon/session/SessionClient.java b/core/src/kz/ilotterytea/maxon/session/SessionClient.java new file mode 100644 index 0000000..31edd6e --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/session/SessionClient.java @@ -0,0 +1,323 @@ +package kz.ilotterytea.maxon.session; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Net; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.net.HttpRequestBuilder; +import com.badlogic.gdx.net.HttpStatus; +import com.badlogic.gdx.utils.JsonReader; +import com.badlogic.gdx.utils.JsonValue; +import com.badlogic.gdx.utils.JsonWriter; +import com.badlogic.gdx.utils.Timer; +import kz.ilotterytea.maxon.MaxonConstants; +import kz.ilotterytea.maxon.utils.RandomUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SessionClient { + private final Logger log; + + private final Preferences sessionPreferences; + private final String clientToken; + private String accessToken; + private String userId, username, password; + private boolean isProcessing, isAuthorised; + + public SessionClient(Preferences sessionPreferences) { + startValidationThread(); + this.log = LoggerFactory.getLogger(SessionClient.class); + + this.clientToken = RandomUtils.generateRandomString(); + this.sessionPreferences = sessionPreferences; + this.isProcessing = false; + this.isAuthorised = false; + + if (sessionPreferences.contains("username") && sessionPreferences.contains("password")) { + this.authorize(sessionPreferences.getString("username"), sessionPreferences.getString("password")); + } + } + + public void authorize(String username, String password) { + log.info("Authorising..."); + this.isProcessing = true; + sessionPreferences.putString("username", username); + sessionPreferences.putString("password", password); + sessionPreferences.flush(); + + JsonValue agent = new JsonValue(JsonValue.ValueType.object); + agent.addChild("name", new JsonValue(String.valueOf(MaxonConstants.GAME_APP_ID.charAt(0)).toUpperCase() + MaxonConstants.GAME_APP_ID.substring(1))); + agent.addChild("version", new JsonValue(MaxonConstants.GAME_PROTOCOL)); + + JsonValue json = new JsonValue(JsonValue.ValueType.object); + json.addChild("agent", agent); + json.addChild("username", new JsonValue(username)); + json.addChild("password", new JsonValue(password)); + json.addChild("clientToken", new JsonValue(clientToken)); + + Net.HttpRequest request = + new HttpRequestBuilder() + .newRequest() + .method(Net.HttpMethods.POST) + .url(MaxonConstants.IDENTITY_AUTHENTICATION_URL) + .timeout(20000) + .header("Content-Type", "application/json") + .content(json.toJson(JsonWriter.OutputType.json)) + .build(); + + Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() { + @Override + public void handleHttpResponse(Net.HttpResponse httpResponse) { + SessionClient.this.isProcessing = false; + + try { + JsonValue json = new JsonReader().parse(httpResponse.getResultAsString()); + + if (httpResponse.getStatus().getStatusCode() != HttpStatus.SC_OK) { + String type = json.get("error").getString("type"); + String error = json.get("error").getString("message"); + log.error("Failed to authorise: {} ({})", error, type); + + sessionPreferences.remove("username"); + sessionPreferences.remove("password"); + sessionPreferences.flush(); + + return; + } + + SessionClient.this.username = username; + SessionClient.this.password = password; + SessionClient.this.accessToken = json.get("data").getString("accessToken"); + SessionClient.this.userId = String.valueOf(json.get("data").get("user").getInt("id")); + SessionClient.this.isAuthorised = true; + log.info("Successfully authorised! Welcome back, {}!", SessionClient.this.username); + } catch (Exception e) { + log.error("An exception was thrown while authorising", e); + } + } + + @Override + public void failed(Throwable t) { + log.error("Failed to send an authorisation request", t); + } + + @Override + public void cancelled() { + log.info("Authorisation request was cancelled!"); + } + }); + } + + public void validateToken() { + if (clientToken == null || accessToken == null) { + return; + } + + log.info("Validating token..."); + + JsonValue json = new JsonValue(JsonValue.ValueType.object); + json.addChild("clientToken", new JsonValue(clientToken)); + json.addChild("accessToken", new JsonValue(accessToken)); + + Net.HttpRequest request = + new HttpRequestBuilder() + .newRequest() + .method(Net.HttpMethods.POST) + .url(MaxonConstants.IDENTITY_VALIDATE_URL) + .timeout(20000) + .header("Content-Type", "application/json") + .content(json.toJson(JsonWriter.OutputType.json)) + .build(); + + Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() { + @Override + public void handleHttpResponse(Net.HttpResponse httpResponse) { + try { + JsonValue json = new JsonReader().parse(httpResponse.getResultAsString()); + + if (httpResponse.getStatus().getStatusCode() != HttpStatus.SC_OK) { + String type = json.get("error").getString("type"); + String error = json.get("error").getString("message"); + log.error("Failed to validate: {} ({})", error, type); + accessToken = null; + userId = null; + isAuthorised = false; + authorize(username, password); + return; + } + + int expiresInSeconds = json.get("data").getInt("expiresInSeconds"); + + if (expiresInSeconds < 1000) { + refreshToken(); + } + + log.info("Token validated!"); + } catch (Exception e) { + log.error("An exception was thrown while validating", e); + } + } + + @Override + public void failed(Throwable t) { + log.error("Failed to send a validation request", t); + } + + @Override + public void cancelled() { + log.info("Validation request was cancelled!"); + } + }); + } + + public void invalidateToken() { + if (clientToken == null || accessToken == null) { + return; + } + + log.info("Invalidating token..."); + + JsonValue json = new JsonValue(JsonValue.ValueType.object); + json.addChild("clientToken", new JsonValue(clientToken)); + json.addChild("accessToken", new JsonValue(accessToken)); + + Net.HttpRequest request = + new HttpRequestBuilder() + .newRequest() + .method(Net.HttpMethods.POST) + .url(MaxonConstants.IDENTITY_INVALIDATE_URL) + .timeout(20000) + .header("Content-Type", "application/json") + .content(json.toJson(JsonWriter.OutputType.json)) + .build(); + + Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() { + @Override + public void handleHttpResponse(Net.HttpResponse httpResponse) { + try { + JsonValue json = new JsonReader().parse(httpResponse.getResultAsString()); + + if (httpResponse.getStatus().getStatusCode() != HttpStatus.SC_OK) { + String type = json.get("error").getString("type"); + String error = json.get("error").getString("message"); + log.error("Failed to invalidate: {} ({})", error, type); + return; + } + + log.info("Invalidated! Bye, {}", username); + + accessToken = null; + userId = null; + username = null; + password = null; + isAuthorised = false; + sessionPreferences.remove("username"); + sessionPreferences.remove("password"); + sessionPreferences.flush(); + } catch (Exception ignored) { + } + } + + @Override + public void failed(Throwable t) { + } + + @Override + public void cancelled() { + } + }); + } + + public void refreshToken() { + if (clientToken == null || accessToken == null) { + return; + } + + log.info("Refreshing token..."); + + JsonValue json = new JsonValue(JsonValue.ValueType.object); + json.addChild("clientToken", new JsonValue(clientToken)); + json.addChild("accessToken", new JsonValue(accessToken)); + + Net.HttpRequest request = + new HttpRequestBuilder() + .newRequest() + .method(Net.HttpMethods.POST) + .url(MaxonConstants.IDENTITY_REFRESH_URL) + .timeout(20000) + .header("Content-Type", "application/json") + .content(json.toJson(JsonWriter.OutputType.json)) + .build(); + + Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() { + @Override + public void handleHttpResponse(Net.HttpResponse httpResponse) { + try { + JsonValue json = new JsonReader().parse(httpResponse.getResultAsString()); + + if (httpResponse.getStatus().getStatusCode() != HttpStatus.SC_OK) { + String type = json.get("error").getString("type"); + String error = json.get("error").getString("message"); + log.error("Failed to refresh: {} ({})", error, type); + accessToken = null; + userId = null; + isAuthorised = false; + log.warn(error); + return; + } + + accessToken = json.get("data").get("accessToken").asString(); + log.info("Token has been refreshed!"); + } catch (Exception e) { + log.error("An exception was thrown while refreshing", e); + } + } + + @Override + public void failed(Throwable t) { + log.error("Failed to send a refresh request", t); + } + + @Override + public void cancelled() { + log.info("Refresh request was cancelled!"); + } + }); + } + + public boolean isAuthorised() { + return this.isAuthorised; + } + + public boolean isProcessing() { + return isProcessing; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getAccessToken() { + return accessToken; + } + + public String getClientToken() { + return clientToken; + } + + public String getUserId() { + return userId; + } + + private void startValidationThread() { + Timer.schedule(new Timer.Task() { + @Override + public void run() { + validateToken(); + } + }, 60000, 60000); + } +} |
