diff --git a/lib/src/main/java/com/tribufu/TribufuApi.java b/lib/src/main/java/com/tribufu/TribufuApi.java new file mode 100644 index 0000000..56d56c9 --- /dev/null +++ b/lib/src/main/java/com/tribufu/TribufuApi.java @@ -0,0 +1,181 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu; + +import java.net.http.HttpClient; +import java.util.HashMap; +import java.util.Map; + +/** + * Tribufu API + * + * Use this class to interact with the Tribufu API. + * + * There are three ways to use the Tribufu API: + * 1. A api key give you public read only access to the Tribufu API. + * 2. A bot give you read and write access to the Tribufu API as a bot account. + * 3. A client give you read and write access to the Tribufu API as a client + * application. + */ +public class TribufuApi { + private static final String VERSION = "0.0.0"; + private static final String API_URL = "https://api.tribufu.com"; + + protected final String baseUrl; + protected final TribufuApiOptions options; + protected final HttpClient http; + + /** + * Create a TribufuApi with the default options. + */ + public TribufuApi() { + this(new TribufuApiOptions()); + } + + /** + * Create a TribufuApi with the given api key. + * + * A api key give you public read only access to the Tribufu API. + * + * @param apiKey + */ + public TribufuApi(String apiKey) { + this(new TribufuApiOptions(apiKey)); + } + + /** + * Create a TribufuApi with the given options. + * + * @param options + */ + public TribufuApi(TribufuApiOptions options) { + this.options = options; + this.baseUrl = TribufuApi.getBaseUrl(); + this.http = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_2) + .build(); + } + + /** + * Try to create a TribufuApi from environment variables. + * + * This will only work if the environment variables are set. + */ + public static TribufuApi fromEnv() { + return TribufuApi.fromEnv(null); + } + + /** + * Try to create a TribufuApi from environment variables. + * + * This will only work if the environment variables are set. + * + * @param prefix A prefix for the environment variables. + */ + public static TribufuApi fromEnv(String prefix) { + var envPrefix = ""; + + if (prefix != null && !prefix.isEmpty()) { + envPrefix = prefix + "_"; + } + + var apiKey = System.getenv(envPrefix + "API_KEY"); + + if (apiKey != null && !apiKey.isEmpty()) { + return new TribufuApi(apiKey); + } + + return null; + } + + /** + * Create a TribufuApi from environment variables or the default api. + * + * This will fallback to the default api if the environment variables are not + * set. + * + * @param prefix A prefix for the environment variables. + */ + public static TribufuApi fromEnvOrDefault(String prefix) { + var api = TribufuApi.fromEnv(prefix); + + if (api != null) { + return api; + } + + return new TribufuApi(); + } + + /** + * Get the base url for the Tribufu API. + * + * The base url can be set using the environment variable TRIBUFU_API_URL. + * The custom base url is only used if debug mode is enabled. + * The default base url is https://api.tribufu.com. + */ + private static String getBaseUrl() { + var baseUrl = System.getenv("TRIBUFU_API_URL"); + + if (baseUrl != null && !baseUrl.isEmpty()) { + return baseUrl; + } + + return TribufuApi.API_URL; + } + + /** + * Get the default headers for the Tribufu API. + */ + public static Map defaultHeaders() { + Map headers = new HashMap<>(); + headers.put("X-Tribufu-Language", "java"); + headers.put("X-Tribufu-Version", VERSION); + return headers; + } + + /** + * Get current headers with the api key or access token. + */ + protected Map getHeaders() { + Map headers = TribufuApi.defaultHeaders(); + + if (this.options.apiKey != null && !this.options.apiKey.isEmpty()) { + headers.put("Authorization", "ApiKey " + this.options.apiKey); + return headers; + } + + if (this.options.accessToken != null && !this.options.accessToken.isEmpty()) { + headers.put("Authorization", "Bearer " + this.options.accessToken); + return headers; + } + + return headers; + } + + /* + * private OAuth2TokenResponse getOAuthToken(OAuth2GrantType grantType, String + * grantValue, String clientId, + * String clientSecret, String subjectKey, String subjectValue) { + * try { + * var headers = defaultHeaders(); + * headers.put("Content-Type", "application/x-www-form-urlencoded"); + * + * var requestBuilder = HttpRequest.newBuilder(); + * for (var entry : headers.entrySet()) { + * requestBuilder.header(entry.getKey(), entry.getValue()); + * } + * + * var request = requestBuilder.build(); + * var response = this.http.send(request, HttpResponse.BodyHandlers.ofString()); + * + * if (response.statusCode() != 200) { + * return null; + * } + * + * return null; + * } catch (Exception e) { + * return null; + * } + * } + */ +} diff --git a/lib/src/main/java/com/tribufu/TribufuApiOptions.java b/lib/src/main/java/com/tribufu/TribufuApiOptions.java new file mode 100644 index 0000000..e75306d --- /dev/null +++ b/lib/src/main/java/com/tribufu/TribufuApiOptions.java @@ -0,0 +1,29 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu; + +public class TribufuApiOptions { + public String apiKey = null; + public String accessToken = null; + public String refreshToken = null; + public float expiresIn = 0; + + public TribufuApiOptions() { + this(null, null, null, 0); + } + + public TribufuApiOptions(String apiKey) { + this(apiKey, null, null, 0); + } + + public TribufuApiOptions(String accessToken, String refreshToken, float expiresIn) { + this(null, accessToken, refreshToken, expiresIn); + } + + private TribufuApiOptions(String apiKey, String accessToken, String refreshToken, float expiresIn) { + this.apiKey = apiKey; + this.accessToken = accessToken; + this.refreshToken = refreshToken; + this.expiresIn = expiresIn; + } +} diff --git a/lib/src/main/java/com/tribufu/TribufuBot.java b/lib/src/main/java/com/tribufu/TribufuBot.java new file mode 100644 index 0000000..b1fe69b --- /dev/null +++ b/lib/src/main/java/com/tribufu/TribufuBot.java @@ -0,0 +1,67 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu; + +/** + * Tribufu Bot + * + * To authenticate a bot you need to use the bot token obtained from the Tribufu + * Developer Portal. + * + * 1. A bot is a special type of user account. + * 2. A bot give you read and write access to the Tribufu API. + */ +public class TribufuBot extends TribufuApi { + private final String botId; + + /** + * Create a TribufuBot. + * + * @param botId + * @param botToken + */ + public TribufuBot(String botId, String botToken) { + super(new TribufuApiOptions(botToken, null, 0)); + this.botId = botId; + } + + /** + * Try to create a TribufuBot from environment variables. + * + * This will only work if the environment variables are set. + */ + public static TribufuBot fromEnv() { + return TribufuBot.fromEnv(null); + } + + /** + * Try to create a TribufuBot from environment variables. + * + * This will only work if the environment variables are set. + * + * @param prefix A prefix for the environment variables. + */ + public static TribufuBot fromEnv(String prefix) { + var envPrefix = ""; + + if (prefix != null && !prefix.isEmpty()) { + envPrefix = prefix + "_"; + } + + var botId = System.getenv(envPrefix + "BOT_ID"); + var botToken = System.getenv(envPrefix + "BOT_TOKEN"); + + if (botId != null && botToken != null) { + return new TribufuBot(botId, botToken); + } + + return null; + } + + /** + * Get the bot id. + */ + public String getBotId() { + return this.botId; + } +} diff --git a/lib/src/main/java/com/tribufu/TribufuClient.java b/lib/src/main/java/com/tribufu/TribufuClient.java index b79c004..0b038e0 100644 --- a/lib/src/main/java/com/tribufu/TribufuClient.java +++ b/lib/src/main/java/com/tribufu/TribufuClient.java @@ -2,38 +2,103 @@ package com.tribufu; -import java.net.http.HttpClient; -import java.util.HashMap; +import java.util.Base64; import java.util.Map; -public class TribufuClient { - public static final String VERSION = "0.0.0"; +/** + * Tribufu Client + * + * To authenticate a client you need to use the client id and client secret + * obtained from the Tribufu Developer Portal + * + * 1. A client is how external applications interact with the Tribufu API. + * 2. A client give you read and write access to the Tribufu API. + * 3. A client can be used to login users. + */ +public class TribufuClient extends TribufuApi { + private final String clientId; + private final String clientSecret; - private final long id; - private final String secret; - private final HttpClient http; - private Map defaultHeaders; - - public TribufuClient(long id, String secret) { - this.id = id; - this.secret = secret; - - String targetTriple = "Java"; - String userAgent = String.format("Tribufu/%s (+https://api.tribufu.com; %s)", VERSION, targetTriple); - - Map headers = new HashMap<>(); - headers.put("User-Agent", userAgent); - headers.put("X-Tribufu-Language", "java"); - headers.put("X-Tribufu-Version", VERSION); - - this.defaultHeaders = headers; - - this.http = HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_2) - .build(); + /** + * Create a TribufuClient. + * + * @param clientId + * @param clientSecret + */ + public TribufuClient(String clientId, String clientSecret) { + super(); + this.clientId = clientId; + this.clientSecret = clientSecret; } - public long getId() { - return this.id; + /** + * Try to create a TribufuClient from environment variables. + * + * This will only work if the environment variables are set. + */ + public static TribufuClient fromEnv() { + return TribufuClient.fromEnv(null); + } + + /** + * Try to create a TribufuClient from environment variables. + * + * This will only work if the environment variables are set. + * + * @param prefix A prefix for the environment variables. + */ + public static TribufuClient fromEnv(String prefix) { + var envPrefix = ""; + if (prefix != null && !prefix.isEmpty()) { + envPrefix = prefix + "_"; + } + + var clientId = System.getenv(envPrefix + "CLIENT_ID"); + var clientSecret = System.getenv(envPrefix + "CLIENT_SECRET"); + + if (clientId != null && clientSecret != null) { + return new TribufuClient(clientId, clientSecret); + } + + return null; + } + + /** + * Set the tokens. + * + * @param accessToken + * @param refreshToken + * @param expiresIn + */ + private void setTokens(String accessToken, String refreshToken, float expiresIn) { + this.options.accessToken = accessToken; + this.options.refreshToken = refreshToken; + this.options.expiresIn = expiresIn; + } + + /** + * Clear the tokens. + */ + protected void clearTokens() { + this.setTokens(null, null, 0); + } + + /** + * Get the headers for a oauth2 request. + */ + protected Map getOAuthHeaders() { + var headers = this.getHeaders(); + var credentials = this.clientId + ":" + this.clientSecret; + var credentialsBase64 = Base64.getEncoder().encodeToString(credentials.getBytes()); + headers.put("Authorization", "Basic " + credentialsBase64); + headers.put("Content-Type", "application/x-www-form-urlencoded"); + return headers; + } + + /** + * Get the client id. + */ + public String getClientId() { + return this.clientId; } } diff --git a/lib/src/main/java/com/tribufu/TribufuServer.java b/lib/src/main/java/com/tribufu/TribufuServer.java new file mode 100644 index 0000000..c0382ca --- /dev/null +++ b/lib/src/main/java/com/tribufu/TribufuServer.java @@ -0,0 +1,70 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu; + +/** + * Tribufu Server + * + * To authenticate a server you need to use the server id, client id and client + * secret obtained from your server subscription. + * + * 1. A server is a special type of client application. + * 2. A server is how game servers interact with the Tribufu API. + * 3. A server give you read and write access to the Tribufu API. + */ +public class TribufuServer extends TribufuClient { + private final String serverId; + + /** + * Create a TribufuServer. + * + * @param serverId + * @param clientId + * @param clientSecret + */ + public TribufuServer(String serverId, String clientId, String clientSecret) { + super(clientId, clientSecret); + this.serverId = serverId; + } + + /** + * Try to create a TribufuServer from environment variables. + * + * This will only work if the environment variables are set. + */ + public static TribufuServer fromEnv() { + return TribufuServer.fromEnv(null); + } + + /** + * Try to create a TribufuServer from environment variables. + * + * This will only work if the environment variables are set. + * + * @param prefix A prefix for the environment variables. + */ + public static TribufuServer fromEnv(String prefix) { + var envPrefix = ""; + + if (prefix != null && !prefix.isEmpty()) { + envPrefix = prefix + "_"; + } + + var serverId = System.getenv(envPrefix + "SERVER_ID"); + var clientId = System.getenv(envPrefix + "CLIENT_ID"); + var clientSecret = System.getenv(envPrefix + "CLIENT_SECRET"); + + if (serverId != null && clientId != null && clientSecret != null) { + return new TribufuServer(serverId, clientId, clientSecret); + } + + return null; + } + + /** + * Get the server id. + */ + public String getServerId() { + return this.serverId; + } +} diff --git a/lib/src/test/java/com/tribufu/TribufuApiTest.java b/lib/src/test/java/com/tribufu/TribufuApiTest.java new file mode 100644 index 0000000..e038b4f --- /dev/null +++ b/lib/src/test/java/com/tribufu/TribufuApiTest.java @@ -0,0 +1,14 @@ +// Copyright (c) Tribufu. All Rights Reserved + +package com.tribufu; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class TribufuApiTest { + @Test + void defaultApi() { + TribufuApi api = new TribufuApi(); + assertNotEquals(null, api); + } +} diff --git a/lib/src/test/java/com/tribufu/TribufuBotTest.java b/lib/src/test/java/com/tribufu/TribufuBotTest.java new file mode 100644 index 0000000..57b2ccf --- /dev/null +++ b/lib/src/test/java/com/tribufu/TribufuBotTest.java @@ -0,0 +1,14 @@ +// Copyright (c) Tribufu. All Rights Reserved + +package com.tribufu; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class TribufuBotTest { + @Test + void defaultApi() { + TribufuBot bot = new TribufuBot("0", "..."); + assertEquals("0", bot.getBotId()); + } +} diff --git a/lib/src/test/java/com/tribufu/TribufuClientTest.java b/lib/src/test/java/com/tribufu/TribufuClientTest.java index 52fd32d..6c0cbbe 100644 --- a/lib/src/test/java/com/tribufu/TribufuClientTest.java +++ b/lib/src/test/java/com/tribufu/TribufuClientTest.java @@ -7,8 +7,8 @@ import static org.junit.jupiter.api.Assertions.*; class TribufuClientTest { @Test - void clientGetId() { - TribufuClient client = new TribufuClient(0, "client_secret"); - assertEquals(0, client.getId()); + void defaultApi() { + TribufuClient client = new TribufuClient("0", "..."); + assertEquals("0", client.getClientId()); } } diff --git a/lib/src/test/java/com/tribufu/TribufuServerTest.java b/lib/src/test/java/com/tribufu/TribufuServerTest.java new file mode 100644 index 0000000..e698735 --- /dev/null +++ b/lib/src/test/java/com/tribufu/TribufuServerTest.java @@ -0,0 +1,15 @@ +// Copyright (c) Tribufu. All Rights Reserved + +package com.tribufu; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class TribufuServerTest { + @Test + void defaultApi() { + TribufuServer server = new TribufuServer("0", "1", "..."); + assertEquals("0", server.getServerId()); + assertEquals("1", server.getClientId()); + } +}