From 6dcc1e540ed316a930160db8fa4a4a2ea62f622b Mon Sep 17 00:00:00 2001 From: dimitrisstaratzis Date: Tue, 4 Oct 2022 18:31:30 +0100 Subject: [PATCH 1/3] add login with 'remember me' option by storing data in $home/.tiledb/cloud.json --- .openapi-generator-ignore | 4 + src/main/java/examples/Examples.java | 26 +- .../io/tiledb/cloud/rest_api/ApiClient.java | 224 +++++++++++++----- .../java/io/tiledb/cloud/rest_api/Login.java | 73 ++++++ 4 files changed, 265 insertions(+), 62 deletions(-) create mode 100644 src/main/java/io/tiledb/cloud/rest_api/Login.java diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index ededb1c..d77ba9e 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/rest_api/ApiClient.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..c55d28a 100644 --- a/src/main/java/examples/Examples.java +++ b/src/main/java/examples/Examples.java @@ -4,6 +4,7 @@ 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.rest_api.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; @@ -28,15 +29,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. + ApiClient apiClient = new ApiClient( + new Login(null, + null, + "https://api.tiledb.com/v1", + "", + true, + true, + false)); - 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: +// ApiClient apiClient = new ApiClient(); + ArrayApi apiInstance = new ArrayApi(apiClient); + +// Uncomment to run whichever example you want // getArraySchema(apiInstance); // createArray(apiInstance); // registerArray(apiInstance); @@ -95,7 +105,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 +148,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/rest_api/ApiClient.java b/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java index f8a1770..c41994f 100644 --- a/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java +++ b/src/main/java/io/tiledb/cloud/rest_api/ApiClient.java @@ -24,10 +24,7 @@ import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; import javax.net.ssl.*; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.lang.reflect.Type; import java.net.URI; import java.net.URLConnection; @@ -56,13 +53,14 @@ import io.tiledb.cloud.rest_api.auth.OAuth; import io.tiledb.cloud.rest_api.auth.RetryingOAuth; import io.tiledb.cloud.rest_api.auth.OAuthFlow; +import org.json.JSONObject; +import org.json.JSONTokener; /** *

ApiClient class.

*/ public class ApiClient { - private String basePath = "/v1"; private boolean debugging = false; private Map defaultHeaderMap = new HashMap(); private Map defaultCookieMap = new HashMap(); @@ -76,90 +74,210 @@ public class ApiClient { private int dateLength; private InputStream sslCaCert; - private boolean verifyingSsl; + private static boolean verifyingSsl = true; private KeyManager[] keyManagers; private OkHttpClient httpClient; private JSON json; + private static String apiKey; + private static String username; + private static String password; + private static String basePath; + private HttpLoggingInterceptor loggingInterceptor; + private static boolean loginInfoIsInJSONFile; + + private static final String homeDir = System.getProperty("user.home"); + /** - * Basic constructor for ApiClient + * Static initialization. */ - public ApiClient() { - init(); - initHttpClient(); + 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; + } + } - // Setup authentications (key: authentication name, value: authentication). - authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); - authentications.put("BasicAuth", new HttpBasicAuth()); - authentications.put("OAuth2", new OAuth()); - // Prevent the authentications from being modified. - authentications = Collections.unmodifiableMap(authentications); + /** + * 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; } /** - * Basic constructor with custom OkHttpClient - * - * @param client a {@link okhttp3.OkHttpClient} object + * 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 */ - public ApiClient(OkHttpClient client) { - init(); + private void setupCredentials(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); + } + } - httpClient = client; + /** + * 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(); + } + } + /** + * Uses all authentication data to create an authentications map + */ + private void createAuthentications() { // Setup authentications (key: authentication name, value: authentication). - authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); - authentications.put("BasicAuth", new HttpBasicAuth()); + ApiKeyAuth apiKeyAuth = new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY"); + apiKeyAuth.setApiKey(apiKey); + authentications.put("ApiKeyAuth", apiKeyAuth); + + HttpBasicAuth httpBasicAuth = new HttpBasicAuth(); + httpBasicAuth.setUsername(username); + httpBasicAuth.setPassword(password); + authentications.put("BasicAuth", httpBasicAuth); + authentications.put("OAuth2", new OAuth()); + // Prevent the authentications from being modified. authentications = Collections.unmodifiableMap(authentications); } /** - * Constructor for ApiClient to support access token retry on 401/403 configured with client ID - * - * @param clientId client ID + * Empty constructor */ - public ApiClient(String clientId) { - this(clientId, null, null); + public ApiClient(){ + this(new Login()); } /** - * Constructor for ApiClient to support access token retry on 401/403 configured with client ID and additional parameters - * - * @param clientId client ID - * @param parameters a {@link java.util.Map} of parameters + * Basic constructor for ApiClient */ - public ApiClient(String clientId, Map parameters) { - this(clientId, null, parameters); + public ApiClient(Login login) { + init(); + initHttpClient(); + + //setup all credentials either from the json file or from the login object. + setupCredentials(login); + + //create the authentication by using the credentials + createAuthentications(); } /** - * Constructor for ApiClient to support access token retry on 401/403 configured with client ID, secret, and additional parameters + * Basic constructor with custom OkHttpClient * - * @param clientId client ID - * @param clientSecret client secret - * @param parameters a {@link java.util.Map} of parameters + * @param client a {@link okhttp3.OkHttpClient} object */ - public ApiClient(String clientId, String clientSecret, Map parameters) { - this(null, clientId, clientSecret, parameters); + public ApiClient(OkHttpClient client, Login login) { + init(); + + httpClient = client; + + //setup all credentials either from the json file or from the login object. + setupCredentials(login); + + //create the authentication by using the credentials + createAuthentications(); } /** * Constructor for ApiClient 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 {@link java.util.Map} of parameters */ - public ApiClient(String basePath, String clientId, String clientSecret, Map parameters) { + public ApiClient(String clientId, String clientSecret, Map parameters, Login login) { init(); - if (basePath != null) { - this.basePath = basePath; - } String tokenUrl = "https://oauth2.tiledb.com/oauth2/token"; if (!"".equals(tokenUrl) && !URI.create(tokenUrl).isAbsolute()) { @@ -177,12 +295,12 @@ public ApiClient(String basePath, String clientId, String clientSecret, MapsingletonList(retryingOAuth)); - // Setup authentications (key: authentication name, value: authentication). - authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); - authentications.put("BasicAuth", new HttpBasicAuth()); - // Prevent the authentications from being modified. - authentications = Collections.unmodifiableMap(authentications); + //setup all credentials either from the json file or from the login object. + setupCredentials(login); + + //create the authentication by using the credentials + createAuthentications(); } private void initHttpClient() { @@ -200,8 +318,6 @@ private void initHttpClient(List interceptors) { } private void init() { - verifyingSsl = true; - json = new JSON(); // Set default User-Agent. @@ -1534,7 +1650,7 @@ private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityExcepti /** * Convert the HTTP request body to a string. * - * @param request The HTTP request object + * @param requestBody The HTTP request object * @return The string representation of the HTTP request body * @throws ApiException If fail to serialize the request body object into a string */ diff --git a/src/main/java/io/tiledb/cloud/rest_api/Login.java b/src/main/java/io/tiledb/cloud/rest_api/Login.java new file mode 100644 index 0000000..f969802 --- /dev/null +++ b/src/main/java/io/tiledb/cloud/rest_api/Login.java @@ -0,0 +1,73 @@ +package io.tiledb.cloud.rest_api; + +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); + } +} From 2e949d8a31915ec04415d296947eb8ea1c27c81a Mon Sep 17 00:00:00 2001 From: dimitrisstaratzis Date: Thu, 6 Oct 2022 14:30:59 +0100 Subject: [PATCH 2/3] wrap ApiClient with TileDBClient --- .openapi-generator-ignore | 2 +- src/main/java/examples/Examples.java | 15 +- .../java/io/tiledb/cloud/TileDBClient.java | 234 +++++++++++++++++ .../io/tiledb/cloud/rest_api/ApiClient.java | 246 +++++------------- 4 files changed, 307 insertions(+), 190 deletions(-) create mode 100644 src/main/java/io/tiledb/cloud/TileDBClient.java diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index d77ba9e..b1d4393 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -29,5 +29,5 @@ README.md settings.gradle #the api client contains the custom code for static initialization from the json file -src/main/java/io/tiledb/cloud/rest_api/ApiClient.java +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 c55d28a..79d856d 100644 --- a/src/main/java/examples/Examples.java +++ b/src/main/java/examples/Examples.java @@ -1,12 +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.rest_api.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; @@ -31,20 +30,20 @@ public class Examples public static void main(String[] args) { // if using cloud for the first time create the client with a Login object to pass your credentials. - ApiClient apiClient = new ApiClient( + TileDBClient tileDBClient = new TileDBClient( new Login(null, null, "https://api.tiledb.com/v1", "", true, true, - false)); + true)); // 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: -// ApiClient apiClient = new ApiClient(); +// TileDBClient tileDBClient = new TileDBClient(); - ArrayApi apiInstance = new ArrayApi(apiClient); + ArrayApi apiInstance = new ArrayApi(tileDBClient.getApiClient()); // Uncomment to run whichever example you want // getArraySchema(apiInstance); @@ -147,8 +146,8 @@ 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 = ""; // String | name/uri of array that is url-encoded + String namespace = "TileDB-Inc"; // String | namespace array is in (an organization name or user's username) + String array = "quickstart_sparse"; // 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/TileDBClient.java b/src/main/java/io/tiledb/cloud/TileDBClient.java new file mode 100644 index 0000000..fa1e667 --- /dev/null +++ b/src/main/java/io/tiledb/cloud/TileDBClient.java @@ -0,0 +1,234 @@ +package io.tiledb.cloud; + +import io.tiledb.cloud.rest_api.ApiClient; +import io.tiledb.cloud.rest_api.Login; +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 c41994f..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 @@ -24,7 +24,10 @@ import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; import javax.net.ssl.*; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.net.URI; import java.net.URLConnection; @@ -53,14 +56,13 @@ import io.tiledb.cloud.rest_api.auth.OAuth; import io.tiledb.cloud.rest_api.auth.RetryingOAuth; import io.tiledb.cloud.rest_api.auth.OAuthFlow; -import org.json.JSONObject; -import org.json.JSONTokener; /** *

ApiClient class.

*/ public class ApiClient { + private String basePath = "/v1"; private boolean debugging = false; private Map defaultHeaderMap = new HashMap(); private Map defaultCookieMap = new HashMap(); @@ -74,217 +76,97 @@ public class ApiClient { private int dateLength; private InputStream sslCaCert; - private static boolean verifyingSsl = true; + private boolean verifyingSsl; private KeyManager[] keyManagers; private OkHttpClient httpClient; private JSON json; - private static String apiKey; - private static String username; - private static String password; - private static String basePath; - private HttpLoggingInterceptor loggingInterceptor; - private static boolean loginInfoIsInJSONFile; - - private static final String homeDir = System.getProperty("user.home"); - - /** - * 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 + * Basic constructor for ApiClient */ - 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; - } + public ApiClient() { + init(); + initHttpClient(); - /** - * 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 setupCredentials(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); - } + // Setup authentications (key: authentication name, value: authentication). + authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); + authentications.put("BasicAuth", new HttpBasicAuth()); + authentications.put("OAuth2", new OAuth()); + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); } /** - * Saves the data from the Login object. - * @param login The Login object + * Basic constructor with custom OkHttpClient + * + * @param client a {@link okhttp3.OkHttpClient} 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(); - } - } + public ApiClient(OkHttpClient client) { + init(); - /** - * 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(); - } - } + httpClient = client; - /** - * Uses all authentication data to create an authentications map - */ - private void createAuthentications() { // Setup authentications (key: authentication name, value: authentication). - ApiKeyAuth apiKeyAuth = new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY"); - apiKeyAuth.setApiKey(apiKey); - authentications.put("ApiKeyAuth", apiKeyAuth); - - HttpBasicAuth httpBasicAuth = new HttpBasicAuth(); - httpBasicAuth.setUsername(username); - httpBasicAuth.setPassword(password); - authentications.put("BasicAuth", httpBasicAuth); - + authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); + authentications.put("BasicAuth", new HttpBasicAuth()); authentications.put("OAuth2", new OAuth()); - // Prevent the authentications from being modified. authentications = Collections.unmodifiableMap(authentications); } /** - * Empty constructor + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID + * + * @param clientId client ID */ - public ApiClient(){ - this(new Login()); + public ApiClient(String clientId) { + this(clientId, null, null); } /** - * Basic constructor for ApiClient + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID and additional parameters + * + * @param clientId client ID + * @param parameters a {@link java.util.Map} of parameters */ - public ApiClient(Login login) { - init(); - initHttpClient(); - - //setup all credentials either from the json file or from the login object. - setupCredentials(login); - - //create the authentication by using the credentials - createAuthentications(); + public ApiClient(String clientId, Map parameters) { + this(clientId, null, parameters); } /** - * Basic constructor with custom OkHttpClient + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID, secret, and additional parameters * - * @param client a {@link okhttp3.OkHttpClient} object + * @param clientId client ID + * @param clientSecret client secret + * @param parameters a {@link java.util.Map} of parameters */ - public ApiClient(OkHttpClient client, Login login) { - init(); - - httpClient = client; - - //setup all credentials either from the json file or from the login object. - setupCredentials(login); - - //create the authentication by using the credentials - createAuthentications(); + public ApiClient(String clientId, String clientSecret, Map parameters) { + this(null, clientId, clientSecret, parameters); } /** * Constructor for ApiClient 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 {@link java.util.Map} of parameters */ - public ApiClient(String clientId, String clientSecret, Map parameters, Login login) { + public ApiClient(String basePath, String clientId, String clientSecret, Map parameters) { init(); + if (basePath != null) { + this.basePath = basePath; + } String tokenUrl = "https://oauth2.tiledb.com/oauth2/token"; if (!"".equals(tokenUrl) && !URI.create(tokenUrl).isAbsolute()) { URI uri = URI.create(getBasePath()); tokenUrl = uri.getScheme() + ":" + - (uri.getAuthority() != null ? "//" + uri.getAuthority() : "") + - tokenUrl; + (uri.getAuthority() != null ? "//" + uri.getAuthority() : "") + + tokenUrl; if (!URI.create(tokenUrl).isAbsolute()) { throw new IllegalArgumentException("OAuth2 token URL must be an absolute URL"); } @@ -295,12 +177,12 @@ public ApiClient(String clientId, String clientSecret, Map param retryingOAuth ); initHttpClient(Collections.singletonList(retryingOAuth)); + // Setup authentications (key: authentication name, value: authentication). + authentications.put("ApiKeyAuth", new ApiKeyAuth("header", "X-TILEDB-REST-API-KEY")); + authentications.put("BasicAuth", new HttpBasicAuth()); - //setup all credentials either from the json file or from the login object. - setupCredentials(login); - - //create the authentication by using the credentials - createAuthentications(); + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); } private void initHttpClient() { @@ -318,6 +200,8 @@ private void initHttpClient(List interceptors) { } private void init() { + verifyingSsl = true; + json = new JSON(); // Set default User-Agent. @@ -1540,10 +1424,10 @@ public String guessContentTypeFromFile(File file) { /** * Add a Content-Disposition Header for the given key and file to the MultipartBody Builder. * - * @param mpBuilder MultipartBody.Builder + * @param mpBuilder MultipartBody.Builder * @param key The key of the Header element * @param file The file to add to the Header - */ + */ private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, File file) { Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\""); MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file)); @@ -1563,8 +1447,8 @@ public Response intercept(Interceptor.Chain chain) throws IOException { if (request.tag() instanceof ApiCallback) { final ApiCallback callback = (ApiCallback) request.tag(); return originalResponse.newBuilder() - .body(new ProgressResponseBody(originalResponse.body(), callback)) - .build(); + .body(new ProgressResponseBody(originalResponse.body(), callback)) + .build(); } return originalResponse; } @@ -1629,9 +1513,9 @@ public boolean verify(String hostname, SSLSession session) { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, trustManagers, new SecureRandom()); httpClient = httpClient.newBuilder() - .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]) - .hostnameVerifier(hostnameVerifier) - .build(); + .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]) + .hostnameVerifier(hostnameVerifier) + .build(); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } @@ -1650,7 +1534,7 @@ private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityExcepti /** * Convert the HTTP request body to a string. * - * @param requestBody The HTTP request object + * @param request The HTTP request object * @return The string representation of the HTTP request body * @throws ApiException If fail to serialize the request body object into a string */ @@ -1668,4 +1552,4 @@ private String requestBodyToString(RequestBody requestBody) throws ApiException // empty http request body return ""; } -} +} \ No newline at end of file From 6175f1537b5cdbcb004b65706cdb058e5dd4d5f3 Mon Sep 17 00:00:00 2001 From: dimitrisstaratzis Date: Fri, 7 Oct 2022 12:25:42 +0100 Subject: [PATCH 3/3] move Login.java from rest_api to login package --- src/main/java/examples/Examples.java | 6 +++--- src/main/java/io/tiledb/cloud/{rest_api => }/Login.java | 2 +- src/main/java/io/tiledb/cloud/TileDBClient.java | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) rename src/main/java/io/tiledb/cloud/{rest_api => }/Login.java (98%) diff --git a/src/main/java/examples/Examples.java b/src/main/java/examples/Examples.java index 79d856d..15a9b82 100644 --- a/src/main/java/examples/Examples.java +++ b/src/main/java/examples/Examples.java @@ -4,7 +4,7 @@ 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.Login; +import io.tiledb.cloud.Login; import io.tiledb.cloud.rest_api.api.GroupsApi; import io.tiledb.cloud.rest_api.api.ArrayApi; import io.tiledb.cloud.rest_api.model.ArrayInfo; @@ -146,8 +146,8 @@ private static void listArrays(ArrayApi apiInstance) private static void getArraySchema(ArrayApi arrayApi){ - String namespace = "TileDB-Inc"; // String | namespace array is in (an organization name or user's username) - String array = "quickstart_sparse"; // String | name/uri of array that is url-encoded + String namespace = ""; // String | namespace array is in (an organization name or user's username) + 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/rest_api/Login.java b/src/main/java/io/tiledb/cloud/Login.java similarity index 98% rename from src/main/java/io/tiledb/cloud/rest_api/Login.java rename to src/main/java/io/tiledb/cloud/Login.java index f969802..08621c0 100644 --- a/src/main/java/io/tiledb/cloud/rest_api/Login.java +++ b/src/main/java/io/tiledb/cloud/Login.java @@ -1,4 +1,4 @@ -package io.tiledb.cloud.rest_api; +package io.tiledb.cloud; import java.util.Objects; diff --git a/src/main/java/io/tiledb/cloud/TileDBClient.java b/src/main/java/io/tiledb/cloud/TileDBClient.java index fa1e667..ab46744 100644 --- a/src/main/java/io/tiledb/cloud/TileDBClient.java +++ b/src/main/java/io/tiledb/cloud/TileDBClient.java @@ -1,7 +1,6 @@ package io.tiledb.cloud; import io.tiledb.cloud.rest_api.ApiClient; -import io.tiledb.cloud.rest_api.Login; import okhttp3.OkHttpClient; import org.json.JSONObject; import org.json.JSONTokener;