diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index ededb1c..b1d4393 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -27,3 +27,7 @@ build.gradle src/main/java/org/openapitools/client/model/FilterType.java README.md settings.gradle + +#the api client contains the custom code for static initialization from the json file +src/main/java/io/tiledb/cloud/TileDBClient.java +src/main/java/io/tiledb/cloud/rest_api/Login.java diff --git a/src/main/java/examples/Examples.java b/src/main/java/examples/Examples.java index 75591cc..15a9b82 100644 --- a/src/main/java/examples/Examples.java +++ b/src/main/java/examples/Examples.java @@ -1,11 +1,11 @@ package examples; // Import classes: +import io.tiledb.cloud.TileDBClient; import io.tiledb.cloud.rest_api.ApiClient; import io.tiledb.cloud.rest_api.ApiException; -import io.tiledb.cloud.rest_api.Configuration; +import io.tiledb.cloud.Login; import io.tiledb.cloud.rest_api.api.GroupsApi; -import io.tiledb.cloud.rest_api.auth.ApiKeyAuth; import io.tiledb.cloud.rest_api.api.ArrayApi; import io.tiledb.cloud.rest_api.model.ArrayInfo; import io.tiledb.cloud.rest_api.model.ArrayInfoUpdate; @@ -28,15 +28,24 @@ public class Examples { public static void main(String[] args) { - ApiClient defaultClient = Configuration.getDefaultApiClient(); - defaultClient.setBasePath("https://api.tiledb.com/v1"); - // Configure API key authorization: ApiKeyAuth - ApiKeyAuth ApiKeyAuth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth"); - ApiKeyAuth.setApiKey(""); +// if using cloud for the first time create the client with a Login object to pass your credentials. + TileDBClient tileDBClient = new TileDBClient( + new Login(null, + null, + "https://api.tiledb.com/v1", + "", + true, + true, + true)); - ArrayApi apiInstance = new ArrayApi(defaultClient); +// If the "RememberME" option is set to true in your first login you can access TileDB-Cloud without the need +// to pass any credentials from now on. Just create the client as follows: +// TileDBClient tileDBClient = new TileDBClient(); + ArrayApi apiInstance = new ArrayApi(tileDBClient.getApiClient()); + +// Uncomment to run whichever example you want // getArraySchema(apiInstance); // createArray(apiInstance); // registerArray(apiInstance); @@ -95,7 +104,7 @@ private static void listGroups(ApiClient defaultClient) Integer page = null; // Integer | pagination offset Integer perPage = null; // Integer | pagination limit String search = null; // String | search string that will look at name, namespace or description fields - String namespace = "TileDB-Inc"; // String | namespace + String namespace = ""; // String | namespace String orderby = null; // String | sort by which field valid values include last_accessed, size, name String permissions = null; // String | permissions valid values include read, read_write, write, admin List tag = null; // List | tag to search for, more than one can be included @@ -138,7 +147,7 @@ private static void listArrays(ArrayApi apiInstance) private static void getArraySchema(ArrayApi arrayApi){ String namespace = ""; // String | namespace array is in (an organization name or user's username) - String array = "my_array"; // String | name/uri of array that is url-encoded + String array = ""; // String | name/uri of array that is url-encoded String contentType = "application/json"; // String | Content Type of input and return mime try { ArraySchema result = arrayApi.getArray(namespace, array, contentType); diff --git a/src/main/java/io/tiledb/cloud/Login.java b/src/main/java/io/tiledb/cloud/Login.java new file mode 100644 index 0000000..08621c0 --- /dev/null +++ b/src/main/java/io/tiledb/cloud/Login.java @@ -0,0 +1,73 @@ +package io.tiledb.cloud; + +import java.util.Objects; + +public class Login { + /** The client password */ + private String password; + + /** The client username */ + private String username; + + /** The host*/ + private String host; + + /** The User's api token. Can be found in the TileDB console at https://www.console.tiledb.com */ + private String apiKey; + + /** True to verify SSL */ + private boolean verifySSL; + + /** True if the user wants their login credentials to be remembered. If yes, they will be saved at ~/.tiledb/cloud.json */ + private boolean rememberMe; + + /** True if the user wants their current login input to overwrite the last one */ + private boolean overwritePrevious; + + public Login(String username, String password, String host, String apiKey, boolean verifySSL, boolean rememberMe, boolean overwritePrevious) { + Objects.requireNonNull(host, "host must not be null"); + this.password = password; + this.username = username; + this.host = host; + this.apiKey = apiKey; + this.verifySSL = verifySSL; + this.rememberMe = rememberMe; + this.overwritePrevious = overwritePrevious; + } + + public Login() { + this.overwritePrevious = false; + } + + public String getPassword() { + return password; + } + + public String getUsername() { + return username; + } + + public String getHost() { + return host; + } + + public String getApiKey() { + return apiKey; + } + + public boolean overwritePrevious() { + return overwritePrevious; + } + + public boolean isVerifySSL() { + return verifySSL; + } + + public boolean rememberMe() { + return rememberMe; + } + + public boolean isValid(){ + return apiKey != null || (password != null && username != null); + } +} diff --git a/src/main/java/io/tiledb/cloud/TileDBClient.java b/src/main/java/io/tiledb/cloud/TileDBClient.java new file mode 100644 index 0000000..ab46744 --- /dev/null +++ b/src/main/java/io/tiledb/cloud/TileDBClient.java @@ -0,0 +1,233 @@ +package io.tiledb.cloud; + +import io.tiledb.cloud.rest_api.ApiClient; +import okhttp3.OkHttpClient; +import org.json.JSONObject; +import org.json.JSONTokener; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.Map; +import java.util.Objects; + +public class TileDBClient{ + + private static String apiKey; + private static String username; + private static String password; + private static String basePath; + + private static boolean verifyingSsl = true; + + private static boolean loginInfoIsInJSONFile; + + private static final String homeDir = System.getProperty("user.home"); + + private ApiClient apiClient; + + /** + * Static initialization. + */ + static + { + apiKey = ""; + username = ""; + password = ""; + basePath = "https://api.tiledb.com/v1"; + loginInfoIsInJSONFile = true; + System.out.println("STATIC INIT"); + boolean ok = false; + try { + ok = loadCloudJSONFileFromHome(); + } catch (Exception e) { + loginInfoIsInJSONFile = false; + } + if (!ok) { + loginInfoIsInJSONFile = false; + } + } + + /** + * If exists, it reads the cloud.json file which is stored in the home + * folder to look for stored credentials. + * @return true if found + * @throws IOException + */ + private static boolean loadCloudJSONFileFromHome() throws IOException { + String fileName = homeDir + "/.tiledb/cloud.json"; + + File initialFile = new File(fileName); + InputStream is = Files.newInputStream(initialFile.toPath()); + + JSONTokener tokener = new JSONTokener(is); + JSONObject object = new JSONObject(tokener); + + if (object.has("api_key")){ + apiKey = object.getString("api_key"); + } + if (object.has("username")){ + username = object.getString("username"); + } + if (object.has("password")){ + password = object.getString("password"); + } + if (object.has("host")){ + basePath = object.getString("host"); + } + if (object.has("verify_ssl")){ + boolean verifySSL = object.getBoolean("verify_ssl"); + verifyingSsl = verifySSL; + } + + // check if credentials are adequate for logging in + if (Objects.equals(basePath, "") || + (Objects.equals(apiKey, "") && (Objects.equals(password, "") && !Objects.equals(username, "")) + || (Objects.equals(apiKey, "") && ((Objects.equals(password, "") || Objects.equals(username, "")))))){ + return false; + } + + return true; + } + + /** + * This method throws an exception if there is no login information in the json file or passed + * as a parameter. If the login information has data it calls another helper method to save it. + * @param login + */ + private void findCredentials(Login login) { + if (!loginInfoIsInJSONFile) { + //requires login from user for the first time + if (login == null || !login.isValid()){ + throw new RuntimeException("No login info was provided nor found. " + + "Use the Login class to login for the first time"); + } else { + populateFieldsFromLogin(login); + } + } else if (login != null && login.overwritePrevious()){ //in this case the data in the json is overwritten. + populateFieldsFromLogin(login); + } + } + + /** + * Saves the data from the Login object. + * @param login The Login object + */ + private void populateFieldsFromLogin(Login login) { + apiKey = login.getApiKey(); + username = login.getUsername(); + password = login.getPassword(); + basePath = login.getHost(); + verifyingSsl = login.isVerifySSL(); + if (login.rememberMe()) { //save credentials + writeAuthJSONFileToHome(); + } + } + + /** + * Writes the json file to the home folder + */ + private void writeAuthJSONFileToHome() { + JSONObject jsonObject = new JSONObject(); + //Inserting key-value pairs into the json object + jsonObject.put("api_key", apiKey); + jsonObject.put("username", username); + jsonObject.put("password", password); + jsonObject.put("host", basePath); + jsonObject.put("verify_ssl", verifyingSsl); + try { + File file = new File(homeDir + "/.tiledb/cloud.json"); + file.getParentFile().mkdirs(); //create /.tiledb dir if not present + FileWriter fileWriter = new FileWriter(file); + fileWriter.write(jsonObject.toString()); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Basic constructor with custom OkHttpClient + * + * @param client an okhttp3.OkHttpClient object + * @param login Login object with credentials + */ + public TileDBClient(OkHttpClient client, Login login){ + apiClient = new ApiClient(client); + setClientCredentials(login); + } + + /** + * Basic constructor with custom OkHttpClient + * + * @param client an okhttp3.OkHttpClient object + */ + public TileDBClient(OkHttpClient client){ + apiClient = new ApiClient(client); + setClientCredentials(new Login()); + } + + /** + * Basic constructor + * + * @param login Login object with credentials + */ + public TileDBClient(Login login){ + apiClient = new ApiClient(); + setClientCredentials(login); + } + + /** + * Basic constructor + * + */ + public TileDBClient(){ + apiClient = new ApiClient(); + setClientCredentials(new Login()); + } + + /** + * Constructor for TileDBClient to support access token retry on 401/403 configured with base path, client ID, secret, and additional parameters + * + * @param basePath base path + * @param clientId client ID + * @param clientSecret client secret + * @param parameters a java.util.Map of parameters + */ + public TileDBClient(String basePath, String clientId, String clientSecret, Map parameters){ + apiClient = new ApiClient(basePath, clientId, clientSecret, parameters); + setClientCredentials(new Login()); + } + + /** + * Constructor for TileDBClient to support access token retry on 401/403 configured with base path, client ID, secret, and additional parameters + * + * @param basePath base path + * @param clientId client ID + * @param clientSecret client secret + * @param parameters a java.util.Map of parameters + * @param login Login object with credentials + */ + public TileDBClient(String basePath, String clientId, String clientSecret, Map parameters, Login login){ + apiClient = new ApiClient(basePath, clientId, clientSecret, parameters); + setClientCredentials(login); + } + + /** + * Finds and sets the credentials to the client + * @param login + */ + private void setClientCredentials(Login login) { + findCredentials(login); + apiClient.setApiKey(apiKey); + apiClient.setUsername(username); + apiClient.setPassword(password); + apiClient.setBasePath(basePath); + } + + public ApiClient getApiClient() { + return apiClient; + } +} \ No newline at end of file diff --git a/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java b/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java index f8a1770..1bbcfc2 100644 --- a/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java +++ b/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java @@ -3,7 +3,7 @@ * TileDB Storage Platform REST API * * The version of the OpenAPI document: 2.2.19 - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -165,8 +165,8 @@ public ApiClient(String basePath, String clientId, String clientSecret, Map