From 8ea42b6184f05f9447d06e268ba422433ac0f517 Mon Sep 17 00:00:00 2001 From: Brad Nicholes Date: Fri, 10 Feb 2023 13:48:29 -0700 Subject: [PATCH 1/2] Add support for retrieval of an account API key using A2A. Add interface classes for IA2ARetrievableAccount, IApiKeySecret and IBrokeredAccessRequest --- .../safeguardjava/ISafeguardA2AContext.java | 16 +++- .../safeguardjava/SafeguardA2AContext.java | 74 +++++++++++++++++-- .../data/A2ARetrievableAccount.java | 16 +++- .../safeguardjava/data/ApiKeySecret.java | 28 +++++++ .../safeguardjava/data/ApiKeySecretBase.java | 67 +++++++++++++++++ .../data/ApiKeySecretInternal.java | 26 +++++++ .../data/BrokeredAccessRequest.java | 3 +- .../data/CertificateContext.java | 6 -- .../safeguardclient/SafeguardJavaClient.java | 42 ++++++----- .../safeguardclient/SafeguardTests.java | 57 ++++++++++++-- 10 files changed, 293 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecret.java create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretBase.java create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretInternal.java diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardA2AContext.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardA2AContext.java index dfad908..574d3a2 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardA2AContext.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/ISafeguardA2AContext.java @@ -1,6 +1,7 @@ package com.oneidentity.safeguard.safeguardjava; import com.oneidentity.safeguard.safeguardjava.data.A2ARetrievableAccount; +import com.oneidentity.safeguard.safeguardjava.data.ApiKeySecret; import com.oneidentity.safeguard.safeguardjava.data.BrokeredAccessRequest; import com.oneidentity.safeguard.safeguardjava.data.KeyFormat; import com.oneidentity.safeguard.safeguardjava.event.ISafeguardEventListener; @@ -24,7 +25,7 @@ public interface ISafeguardA2AContext * @throws ObjectDisposedException Object has already been disposed. * @throws SafeguardForJavaException General Safeguard for Java exception. */ - List getRetrievableAccounts() throws ObjectDisposedException, SafeguardForJavaException; + List getRetrievableAccounts() throws ObjectDisposedException, SafeguardForJavaException; /** * Retrieves a password using Safeguard A2A. @@ -49,6 +50,17 @@ public interface ISafeguardA2AContext */ char[] retrievePrivateKey(char[] apiKey, KeyFormat keyFormat) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; + /** + * Retrieves an API key secret using Safeguard A2A. + * + * @param apiKey API key corresponding to the configured account. + * @return A list of API key secrets. + * @throws ObjectDisposedException Object has already been disposed. + * @throws SafeguardForJavaException General Safeguard for Java exception. + * @throws ArgumentException Invalid argument. + */ + List retrieveApiKeySecret(char[] apiKey) throws ObjectDisposedException, ArgumentException, SafeguardForJavaException; + /** * Gets an A2A event listener. The handler passed in will be registered for the AssetAccountPasswordUpdated * event, which is the only one supported in A2A. You just have to call Start(). The event listener returned @@ -117,7 +129,7 @@ public interface ISafeguardA2AContext * @throws SafeguardForJavaException General Safeguard for Java exception. * @throws ArgumentException Invalid argument */ - String brokerAccessRequest(char[] apiKey, BrokeredAccessRequest accessRequest) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; + String brokerAccessRequest(char[] apiKey, IBrokeredAccessRequest accessRequest) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException; /** * Dispose of an object diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java index 9576c97..f73bf24 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/SafeguardA2AContext.java @@ -5,6 +5,8 @@ import com.oneidentity.safeguard.safeguardjava.data.A2ARegistration; import com.oneidentity.safeguard.safeguardjava.data.A2ARetrievableAccount; import com.oneidentity.safeguard.safeguardjava.data.A2ARetrievableAccountInternal; +import com.oneidentity.safeguard.safeguardjava.data.ApiKeySecret; +import com.oneidentity.safeguard.safeguardjava.data.ApiKeySecretInternal; import com.oneidentity.safeguard.safeguardjava.data.BrokeredAccessRequest; import com.oneidentity.safeguard.safeguardjava.data.CertificateContext; import com.oneidentity.safeguard.safeguardjava.data.KeyFormat; @@ -80,13 +82,13 @@ public SafeguardA2AContext(String networkAddress, byte[] certificateData, char[] } @Override - public List getRetrievableAccounts() throws ObjectDisposedException, SafeguardForJavaException { + public List getRetrievableAccounts() throws ObjectDisposedException, SafeguardForJavaException { if (disposed) { throw new ObjectDisposedException("SafeguardA2AContext"); } - List list = new ArrayList<>(); + List list = new ArrayList<>(); Map headers = new HashMap<>(); headers.put(HttpHeaders.ACCEPT, "application/json"); @@ -218,6 +220,52 @@ public char[] retrievePrivateKey(char[] apiKey, KeyFormat keyFormat) throws Obje return privateKey; } + @Override + public List retrieveApiKeySecret(char[] apiKey) throws ObjectDisposedException, ArgumentException, SafeguardForJavaException { + if (disposed) { + throw new ObjectDisposedException("SafeguardA2AContext"); + } + + if (apiKey == null) + throw new ArgumentException("The apiKey parameter may not be null."); + + List list = new ArrayList<>(); + + Map headers = new HashMap<>(); + headers.put(HttpHeaders.AUTHORIZATION, String.format("A2A %s", new String(apiKey))); + + Map parameters = new HashMap<>(); + parameters.put("type", "ApiKey"); + + CloseableHttpResponse response = a2AClient.execGET("Credentials", parameters, headers, null, clientCertificate); + + if (response == null) { + throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); + } + + String reply = Utils.getResponse(response); + if (!Utils.isSuccessful(response.getStatusLine().getStatusCode())) { + throw new SafeguardForJavaException("Error returned from Safeguard API, Error: " + + String.format("%s %s", response.getStatusLine().getStatusCode(), reply)); + } + + List apiKeySecretsInternal = parseApiKeySecretResponse(reply); + + for (ApiKeySecretInternal apiKeySecretInternal : apiKeySecretsInternal) { + ApiKeySecret apiKeySecret = new ApiKeySecret(); + apiKeySecret.setId(apiKeySecretInternal.getId()); + apiKeySecret.setName(apiKeySecretInternal.getName()); + apiKeySecret.setDescription(apiKeySecretInternal.getDescription()); + apiKeySecret.setClientId(apiKeySecretInternal.getClientId()); + apiKeySecret.setClientSecret(apiKeySecretInternal.getClientSecret().toCharArray()); + apiKeySecret.setClientSecretId(apiKeySecretInternal.getClientSecretId()); + + list.add(apiKeySecret); + } + + return list; + } + @Override public ISafeguardEventListener getA2AEventListener(char[] apiKey, ISafeguardEventHandler handler) throws ObjectDisposedException, ArgumentException { @@ -283,7 +331,7 @@ public ISafeguardEventListener getPersistentA2AEventListener(List apiKey } @Override - public String brokerAccessRequest(char[] apiKey, BrokeredAccessRequest accessRequest) + public String brokerAccessRequest(char[] apiKey, IBrokeredAccessRequest accessRequest) throws ObjectDisposedException, SafeguardForJavaException, ArgumentException { if (disposed) { @@ -301,7 +349,9 @@ public String brokerAccessRequest(char[] apiKey, BrokeredAccessRequest accessReq if (accessRequest.getAssetId() == null && accessRequest.getAssetName() == null) { throw new SafeguardForJavaException("You must specify an asset to create an access request for"); } - accessRequest.setVersion(apiVersion); + + BrokeredAccessRequest brokeredAccessRequest = (BrokeredAccessRequest)accessRequest; + brokeredAccessRequest.setVersion(apiVersion); Map headers = new HashMap<>(); headers.put(HttpHeaders.ACCEPT, "application/json"); @@ -309,7 +359,7 @@ public String brokerAccessRequest(char[] apiKey, BrokeredAccessRequest accessReq Map parameters = new HashMap<>(); - CloseableHttpResponse response = a2AClient.execPOST("AccessRequests", parameters, headers, null, accessRequest, clientCertificate); + CloseableHttpResponse response = a2AClient.execPOST("AccessRequests", parameters, headers, null, brokeredAccessRequest, clientCertificate); if (response == null) { throw new SafeguardForJavaException(String.format("Unable to connect to web service %s", a2AClient.getBaseURL())); @@ -374,4 +424,18 @@ private List parseA2ARetrievableAccountResponse(S return null; } + private List parseApiKeySecretResponse(String response) { + + ObjectMapper mapper = new ObjectMapper(); + + try { + ApiKeySecretInternal[] apiKeySecrets = mapper.readValue(response, ApiKeySecretInternal[].class); + return Arrays.asList(apiKeySecrets); + } catch (IOException ex) { + Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); + } + + return null; + } + } diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/A2ARetrievableAccount.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/A2ARetrievableAccount.java index d241e9a..9a03cba 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/A2ARetrievableAccount.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/A2ARetrievableAccount.java @@ -2,13 +2,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.oneidentity.safeguard.safeguardjava.IA2ARetrievableAccount; import java.util.Arrays; /** * This class is used to get the retrievable accounts for an A2A registration. */ @JsonIgnoreProperties -public class A2ARetrievableAccount { +public class A2ARetrievableAccount implements IA2ARetrievableAccount { private boolean disposed; private String applicationName; @@ -36,6 +37,7 @@ public class A2ARetrievableAccount { @JsonProperty("AccountDescription") private String accountDescription; + @Override public String getApplicationName() { return applicationName; } @@ -44,6 +46,7 @@ public void setApplicationName(String applicationName) { this.applicationName = applicationName; } + @Override public String getDescription() { return description; } @@ -52,6 +55,7 @@ public void setDescription(String description) { this.description = description; } + @Override public boolean isDisabled() { return disabled; } @@ -60,6 +64,7 @@ public void setDisabled(boolean disabled) { this.disabled = disabled; } + @Override public char[] getApiKey() { return apiKey; } @@ -68,6 +73,7 @@ public void setApiKey(char[] apiKey) { this.apiKey = apiKey; } + @Override public int getAssetId() { return assetId; } @@ -76,6 +82,7 @@ public void setAssetId(int assetId) { this.assetId = assetId; } + @Override public String getAssetName() { return assetName; } @@ -84,6 +91,7 @@ public void setAssetName(String assetName) { this.assetName = assetName; } + @Override public String getAssetNetworkAddress() { return assetNetworkAddress; } @@ -92,6 +100,7 @@ public void setAssetNetworkAddress(String assetNetworkAddress) { this.assetNetworkAddress = assetNetworkAddress; } + @Override public int getAccountId() { return accountId; } @@ -100,6 +109,7 @@ public void setAccountId(int accountId) { this.accountId = accountId; } + @Override public String getAccountName() { return accountName; } @@ -108,6 +118,7 @@ public void setAccountName(String accountName) { this.accountName = accountName; } + @Override public String getDomainName() { return domainName; } @@ -116,6 +127,7 @@ public void setDomainName(String domainName) { this.domainName = domainName; } + @Override public String getAccountType() { return accountType; } @@ -124,6 +136,7 @@ public void setAccountType(String accountType) { this.accountType = accountType; } + @Override public String getAssetDescription() { return assetDescription; } @@ -132,6 +145,7 @@ public void setAssetDescription(String assetDescription) { this.assetDescription = assetDescription; } + @Override public String getAccountDescription() { return accountDescription; } diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecret.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecret.java new file mode 100644 index 0000000..fb0383d --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecret.java @@ -0,0 +1,28 @@ +package com.oneidentity.safeguard.safeguardjava.data; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.oneidentity.safeguard.safeguardjava.IApiKeySecret; + + +/** + * This class is used to get the API key secret. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApiKeySecret extends ApiKeySecretBase implements IApiKeySecret { + + @JsonProperty("ClientSecret") + private char[] clientSecret; + + public ApiKeySecret() { + } + + @Override + public char[] getClientSecret() { + return clientSecret; + } + + public void setClientSecret(char[] clientSecret) { + this.clientSecret = clientSecret; + } +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretBase.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretBase.java new file mode 100644 index 0000000..7303500 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretBase.java @@ -0,0 +1,67 @@ +package com.oneidentity.safeguard.safeguardjava.data; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + + +/** + * This class is used to get the API key secret. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +class ApiKeySecretBase { + + @JsonProperty("Id") + private Integer id; + @JsonProperty("Name") + private String name; + @JsonProperty("Description") + private String description; + @JsonProperty("ClientId") + private String clientId; + @JsonProperty("ClientSecretId") + private String clientSecretId; + + public ApiKeySecretBase() { + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecretId() { + return clientSecretId; + } + + public void setClientSecretId(String clientSecretId) { + this.clientSecretId = clientSecretId; + } + +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretInternal.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretInternal.java new file mode 100644 index 0000000..f2de700 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/ApiKeySecretInternal.java @@ -0,0 +1,26 @@ +package com.oneidentity.safeguard.safeguardjava.data; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + + +/** + * This class is used to get the API key secret. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApiKeySecretInternal extends ApiKeySecretBase { + + @JsonProperty("ClientSecret") + private String clientSecret; + + public ApiKeySecretInternal() { + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/BrokeredAccessRequest.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/BrokeredAccessRequest.java index fe9a7e7..223ec68 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/BrokeredAccessRequest.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/BrokeredAccessRequest.java @@ -1,12 +1,13 @@ package com.oneidentity.safeguard.safeguardjava.data; +import com.oneidentity.safeguard.safeguardjava.IBrokeredAccessRequest; import com.oneidentity.safeguard.safeguardjava.Utils; import java.time.Instant; /** * This class is used to define a brokered access request. */ -public class BrokeredAccessRequest implements JsonObject +public class BrokeredAccessRequest implements JsonObject, IBrokeredAccessRequest { private int version; diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/CertificateContext.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/CertificateContext.java index 65502cc..6daa5a4 100644 --- a/src/main/java/com/oneidentity/safeguard/safeguardjava/data/CertificateContext.java +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/data/CertificateContext.java @@ -3,14 +3,8 @@ import com.oneidentity.safeguard.safeguardjava.CertificateUtilities; import com.oneidentity.safeguard.safeguardjava.Utils; import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException; -import java.security.cert.X509Certificate; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; import java.util.Arrays; -import java.util.logging.Level; -import java.util.logging.Logger; public class CertificateContext { diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java index abe87ce..417a199 100644 --- a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardJavaClient.java @@ -100,33 +100,36 @@ public static void main(String[] args) { eventListener = tests.safeguardDisconnectEventListener(eventListener); break; case 20: - tests.safeguardTestBackupDownload(connection); + tests.safeguardListBackups(connection); break; case 21: - tests.safeguardTestBackupUpload(connection); + tests.safeguardTestBackupDownload(connection); break; case 22: - sessionConnection = tests.safeguardSessionsConnection(); + tests.safeguardTestBackupUpload(connection); break; case 23: - tests.safeguardSessionsApi(sessionConnection); + sessionConnection = tests.safeguardSessionsConnection(); break; case 24: - tests.safeguardSessionsFileUpload(sessionConnection); + tests.safeguardSessionsApi(sessionConnection); break; case 25: - tests.safeguardSessionsStreamUpload(sessionConnection); + tests.safeguardSessionsFileUpload(sessionConnection); break; case 26: - tests.safeguardSessionTestRecordingDownload(sessionConnection); + tests.safeguardSessionsStreamUpload(sessionConnection); break; case 27: - tests.safeguardTestJoinSps(connection, sessionConnection); + tests.safeguardSessionTestRecordingDownload(sessionConnection); break; case 28: - tests.safeguardTestManagementConnection(connection); + tests.safeguardTestJoinSps(connection, sessionConnection); break; case 29: + tests.safeguardTestManagementConnection(connection); + break; + case 30: tests.safeguardTestAnonymousConnection(connection); break; default: @@ -166,16 +169,17 @@ private static Integer displayMenu() { System.out.println ("\t17. Event Listener by thumbprint"); System.out.println ("\t18. Test Event Listener"); System.out.println ("\t19. Disconnect Event Listener"); - System.out.println ("\t20. Test Download Backup File"); - System.out.println ("\t21. Test Upload Backup File"); - System.out.println ("\t22. Test SPS Connection"); - System.out.println ("\t23. Test SPS API"); - System.out.println ("\t24. Test SPS Firmware Upload"); - System.out.println ("\t25. Test Stream Upload"); - System.out.println ("\t26. Test Session Recording Download"); - System.out.println ("\t27. Test Join SPS"); - System.out.println ("\t28. Test Management Interface API"); - System.out.println ("\t29. Test Anonymous Connection"); + System.out.println ("\t20. Test List Backups"); + System.out.println ("\t21. Test Download Backup File"); + System.out.println ("\t22. Test Upload Backup File"); + System.out.println ("\t23. Test SPS Connection"); + System.out.println ("\t24. Test SPS API"); + System.out.println ("\t25. Test SPS Firmware Upload"); + System.out.println ("\t26. Test Stream Upload"); + System.out.println ("\t27. Test Session Recording Download"); + System.out.println ("\t28. Test Join SPS"); + System.out.println ("\t29. Test Management Interface API"); + System.out.println ("\t30. Test Anonymous Connection"); System.out.println ("\t99. Exit"); diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java index dd9c9dc..505379a 100644 --- a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/SafeguardTests.java @@ -3,18 +3,22 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; import static com.oneidentity.safeguard.safeguardclient.SafeguardJavaClient.readLine; import com.oneidentity.safeguard.safeguardclient.data.SafeguardAppliance; import com.oneidentity.safeguard.safeguardclient.data.SafeguardApplianceStatus; +import com.oneidentity.safeguard.safeguardclient.data.SafeguardBackup; import com.oneidentity.safeguard.safeguardclient.data.SafeguardSslCertificate; import com.oneidentity.safeguard.safeguardclient.data.SessionRecordings; +import com.oneidentity.safeguard.safeguardjava.IA2ARetrievableAccount; +import com.oneidentity.safeguard.safeguardjava.IApiKeySecret; +import com.oneidentity.safeguard.safeguardjava.IBrokeredAccessRequest; import com.oneidentity.safeguard.safeguardjava.IProgressCallback; import com.oneidentity.safeguard.safeguardjava.ISafeguardA2AContext; import com.oneidentity.safeguard.safeguardjava.ISafeguardConnection; import com.oneidentity.safeguard.safeguardjava.ISafeguardSessionsConnection; import com.oneidentity.safeguard.safeguardjava.Safeguard; import com.oneidentity.safeguard.safeguardjava.SafeguardForPrivilegedSessions; -import com.oneidentity.safeguard.safeguardjava.data.A2ARetrievableAccount; import com.oneidentity.safeguard.safeguardjava.data.BrokeredAccessRequest; import com.oneidentity.safeguard.safeguardjava.data.BrokeredAccessRequestType; import com.oneidentity.safeguard.safeguardjava.data.FullResponse; @@ -314,27 +318,43 @@ ISafeguardA2AContext safeguardGetA2AContextByThumbprint() { public void safeguardTestA2AContext(ISafeguardA2AContext a2aContext) { if (a2aContext == null) { - System.out.println(String.format("Missing Safeguard A2A context")); + System.out.println(String.format("Missing Safeguard A2A context.")); return; } if (readLine("Test Credential Retrieval(y/n): ", "y").equalsIgnoreCase("y")) { - boolean passwordRelease = readLine("Password or Private Key(p/k): ", "p").equalsIgnoreCase("p"); + String typeOfRelease = readLine("Password, Private Key or API Key Secret (p/k/a): ", "p"); String apiKey = readLine("API Key: ", null); try { - if (passwordRelease) { + if (typeOfRelease.equalsIgnoreCase("p")) { String password = new String(a2aContext.retrievePassword(apiKey.toCharArray())); System.out.println(String.format("\tSuccessful password release")); } - else { + else if (typeOfRelease.equalsIgnoreCase("k")) { String key = new String(a2aContext.retrievePrivateKey(apiKey.toCharArray(), KeyFormat.OpenSsh)); System.out.println(String.format("\tSuccessful private key release")); } + else if (typeOfRelease.equalsIgnoreCase("a")) { + List apiKeySecrets = a2aContext.retrieveApiKeySecret(apiKey.toCharArray()); + if (!apiKeySecrets.isEmpty()) { + for (IApiKeySecret key : apiKeySecrets) { + System.out.println(String.format("\tKey Id: %d Key Name: %s", key.getId(), key.getName())); + } + System.out.println(String.format("\tSuccessful api key secret release")); + } + else { + System.out.println(String.format("\tNo api key secrets found")); + } + } + else { + System.out.println(String.format("Invalid credential release type.")); + return; + } - List registrations = a2aContext.getRetrievableAccounts(); + List registrations = a2aContext.getRetrievableAccounts(); System.out.println(String.format("\tRetrievable accounts:")); - for (A2ARetrievableAccount reg : registrations) { + for (IA2ARetrievableAccount reg : registrations) { System.out.println(String.format("\t\tAssetId: %d AssetName: %s AccountId: %d AccountName: %s AccountDescription: %s", reg.getAssetId(), reg.getAssetName(), reg.getAccountId(), reg.getAccountName(), reg.getAccountDescription())); } @@ -351,7 +371,7 @@ public void safeguardTestA2AContext(ISafeguardA2AContext a2aContext) { String apiKey = readLine("Api Key: ", null); try { - BrokeredAccessRequest accessRequest = new BrokeredAccessRequest(); + IBrokeredAccessRequest accessRequest = new BrokeredAccessRequest(); accessRequest.setAccountId(Integer.parseInt(accountId)); accessRequest.setForUserId(Integer.parseInt(forUserId)); accessRequest.setAssetId(Integer.parseInt(assetId)); @@ -558,6 +578,27 @@ public void safeguardTestBackupDownload(ISafeguardConnection connection) { } } + public void safeguardListBackups(ISafeguardConnection connection) { + + if (connection == null) { + System.out.println(String.format("Safeguard not connected")); + return; + } + + try { + String response = connection.invokeMethod(Service.Appliance, Method.Get, "Backups", null, null, null, null); + + SafeguardBackup[] backups = new Gson().fromJson(response, SafeguardBackup[].class); + + System.out.println(String.format("\t\\Backups response:")); + for (SafeguardBackup backup : backups) { + System.out.println(String.format("Id: %s - File Name: %s", backup.getId(), backup.getFilename())); + } + } catch (ArgumentException | ObjectDisposedException | SafeguardForJavaException ex) { + System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage()); + } + } + public void safeguardTestBackupUpload(ISafeguardConnection connection) { if (connection == null) { From 475293e3460e12e2ddc1314036611960026841bc Mon Sep 17 00:00:00 2001 From: Brad Nicholes Date: Fri, 10 Feb 2023 14:35:23 -0700 Subject: [PATCH 2/2] Add missing files --- .../safeguardjava/IA2ARetrievableAccount.java | 85 ++++++ .../safeguardjava/IApiKeySecret.java | 43 +++ .../safeguardjava/IBrokeredAccessRequest.java | 252 ++++++++++++++++++ .../safeguardclient/data/SafeguardBackup.java | 26 ++ 4 files changed, 406 insertions(+) create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/IA2ARetrievableAccount.java create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/IApiKeySecret.java create mode 100644 src/main/java/com/oneidentity/safeguard/safeguardjava/IBrokeredAccessRequest.java create mode 100644 tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/data/SafeguardBackup.java diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/IA2ARetrievableAccount.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/IA2ARetrievableAccount.java new file mode 100644 index 0000000..62c610a --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/IA2ARetrievableAccount.java @@ -0,0 +1,85 @@ +package com.oneidentity.safeguard.safeguardjava; + +/** + * Represents an A2A retrievable account + */ +public interface IA2ARetrievableAccount { + + /** + * Get the application name + * @return String + */ + String getApplicationName(); + + /** + * Get the description + * @return String + */ + String getDescription(); + + /** + * Is the account disabled + * @return boolean + */ + boolean isDisabled(); + + /** + * Get the A2A API key + * @return char[] + */ + char[] getApiKey(); + + /** + * Get the asset Id + * @return int + */ + int getAssetId(); + + /** + * Get the asset name + * @return String + */ + String getAssetName(); + + /** + * Get the asset network address + * @return String + */ + String getAssetNetworkAddress(); + + /** + * Get the account Id + * @return int + */ + int getAccountId(); + + /** + * Get the account name + * @return String + */ + String getAccountName(); + + /** + * Get the domain name + * @return String + */ + String getDomainName(); + + /** + * Get the account type + * @return String + */ + String getAccountType(); + + /** + * Get the asset description + * @return String + */ + String getAssetDescription(); + + /** + * Get the account description + * @return String + */ + String getAccountDescription(); +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/IApiKeySecret.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/IApiKeySecret.java new file mode 100644 index 0000000..5d0b94a --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/IApiKeySecret.java @@ -0,0 +1,43 @@ +package com.oneidentity.safeguard.safeguardjava; + +/** + * Represents the Api key secret + */ +public interface IApiKeySecret { + + /** + * Get the API key Id + * @return Integer + */ + Integer getId(); + + /** + * Get the API key name + * @return String + */ + String getName(); + + /** + * Get the API key description + * @return String + */ + String getDescription(); + + /** + * Get the API key client Id + * @return String + */ + String getClientId(); + + /** + * Get the API key client secret + * @return char[] + */ + char[] getClientSecret(); + + /** + * Get the API key client secret Id + * @return String + */ + String getClientSecretId(); +} diff --git a/src/main/java/com/oneidentity/safeguard/safeguardjava/IBrokeredAccessRequest.java b/src/main/java/com/oneidentity/safeguard/safeguardjava/IBrokeredAccessRequest.java new file mode 100644 index 0000000..3ffcda1 --- /dev/null +++ b/src/main/java/com/oneidentity/safeguard/safeguardjava/IBrokeredAccessRequest.java @@ -0,0 +1,252 @@ +package com.oneidentity.safeguard.safeguardjava; + +import com.oneidentity.safeguard.safeguardjava.data.BrokeredAccessRequestType; +import java.time.Instant; + +/** + * Represents a brokered access request + */ +public interface IBrokeredAccessRequest { + + /** + * Get the type of access request to create. + * @return BrokeredAccessRequestType + */ + BrokeredAccessRequestType getAccessType(); + + /** + * Set the type of access request to create. + * @param AccessType BrokeredAccessRequestType + */ + void setAccessType(BrokeredAccessRequestType AccessType); + + /** + * Get the name of the user to create the access request for. If the ForUserId property is + * set, then this property will be ignored. + * @return String + */ + String getForUserName(); + + /** + * Set the name of the user to create the access request for. If the ForUserId property is + * set, then this property will be ignored. + * @param ForUserName For user name + */ + void setForUserName(String ForUserName); + + /** + * Get the name of the identity provider to create the access request for. If the ForUserId + * property is set, then this property will be ignored. + * @return String + */ + String getForUserIdentityProvider(); + + /** + * Set the name of the identity provider to create the access request for. If the ForUserId + * property is set, then this property will be ignored. + * @param ForUserIdentityProvider Identity provider + */ + void setForUserIdentityProvider(String ForUserIdentityProvider); + + /** + * Get the ID of the user to create the access request for. + * @return Integer + */ + Integer getForUserId(); + + /** + * Set the ID of the user to create the access request for. + * @param ForUserId For user id. + */ + void setForUserId(Integer ForUserId); + + /** + * Get the name of the asset to create the access request for. If the AssetId property is + * set, then this property will be ignored. + * @return String + */ + String getAssetName(); + + /** + * Set the name of the asset to create the access request for. If the AssetId property is + * set, then this property will be ignored. + * @param AssetName Asset name. + */ + void setAssetName(String AssetName); + + /** + * Get the ID of the asset to create the access request for. + * @return Integer + */ + Integer getAssetId(); + + /** + * Set the ID of the asset to create the access request for. + * @param AssetId Asset id. + */ + void setAssetId(Integer AssetId); + + /** + * Get the name of the account to create the access request for. If the AccountId property is + * set, then this property will be ignored. + * @return String + */ + String getAccountName(); + + /** + * Set the name of the account to create the access request for. If the AccountId property is + * set, then this property will be ignored. + * @param AccountName Account name. + */ + void setAccountName(String AccountName); + + /** + * Get the ID of the account to create the access request for. + * @return Integer + */ + Integer getAccountId(); + + /** + * Set the ID of the account to create the access request for. + * @param AccountId Account id. + */ + void setAccountId(Integer AccountId); + + /** + * Get the name of the asset the account is from to create the access request for. If the + * AccountAssetId property is set, then this property will be ignored. + * @return String + */ + String getAccountAssetName(); + + /** + * Set the name of the asset the account is from to create the access request for. If the + * AccountAssetId property is set, then this property will be ignored. + * @param AccountAssetName Account asset name. + */ + void setAccountAssetName(String AccountAssetName); + + /** + * Get the ID of the asset the account is from to create the access request for. + * @return Integer + */ + Integer getAccountAssetId(); + + /** + * Set the ID of the asset the account is from to create the access request for. + * @param AccountAssetId Account asset id. + */ + void setAccountAssetId(Integer AccountAssetId); + + /** + * Whether or not this is an emergency access request. + * @return boolean + */ + boolean getIsEmergency(); + + /** + * Set whether or not this is an emergency access request. + * @param IsEmergency Is emergency + */ + void setIsEmergency(boolean IsEmergency); + + /** + * Get the name of the pre-defined reason code to include in the access request. If the ReasonCodeId + * property is set, then this property will be ignored. + * @return String + */ + String getReasonCode(); + + /** + * Set the name of the pre-defined reason code to include in the access request. If the ReasonCodeId + * property is set, then this property will be ignored. + * @param ReasonCode Reason code. + */ + void setReasonCode(String ReasonCode); + + /** + * Get the ID of the pre-defined reason code to include in the access request. + * @return Integer + */ + Integer getReasonCodeId(); + + /** + * Set the ID of the pre-defined reason code to include in the access request. + * @param ReasonCodeId Reason code id. + */ + void setReasonCodeId(Integer ReasonCodeId); + + /** + * Get a reason comment to include in the access request. + * @return String + */ + String getReasonComment(); + + /** + * Set a reason comment to include in the access request. + * @param ReasonComment Reason comment. + */ + void setReasonComment(String ReasonComment); + + /** + * Get a ticket number associated with the new access request. + * @return String + */ + String getTicketNumber(); + + /** + * Set a ticket number associated with the new access request. + * @param TicketNumber Ticket number. + */ + void setTicketNumber(String TicketNumber); + + /** + * Get the time when the access request should be requested for. All values will be converted to UTC date and time + * before being sent to the server. + * @return Instant + */ + Instant getRequestedFor(); + + /** + * Set the time when the access request should be requested for. All values will be converted to UTC date and time + * before being sent to the server. + * @param RequestedFor Requested for. + */ + void setRequestedFor(Instant RequestedFor); + + /** + * Get the number of days the access request should be requested for. + * @return Long + */ + Long getRequestedDurationDays(); + + /** + * Set the number of days the access request should be requested for. + * @param RequestedDurationDays Requested duration days + */ + void setRequestedDurationDays(Long RequestedDurationDays); + + /** + * Get the number of hours the access request should be requested for. + * @return Long + */ + Long getRequestedDurationHours(); + + /** + * Set the number of hours the access request should be requested for. + * @param RequestedDurationHours Requested duration hours + */ + void setRequestedDurationHours(Long RequestedDurationHours); + + /** + * Get the number of minutes the access request should be requested for. + * @return Long + */ + Long getRequestedDurationMinutes(); + + /** + * Set the number of minutes the access request should be requested for. + * @param RequestedDurationMinutes Requested duration minutes + */ + void setRequestedDurationMinutes(Long RequestedDurationMinutes); +} diff --git a/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/data/SafeguardBackup.java b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/data/SafeguardBackup.java new file mode 100644 index 0000000..6bbc250 --- /dev/null +++ b/tests/safeguardjavaclient/src/main/java/com/oneidentity/safeguard/safeguardclient/data/SafeguardBackup.java @@ -0,0 +1,26 @@ +package com.oneidentity.safeguard.safeguardclient.data; + +public class SafeguardBackup { + + private String Id; + private String Filename; + + public SafeguardBackup() { + } + + public String getId() { + return Id; + } + + public void setId(String Id) { + this.Id = Id; + } + + public String getFilename() { + return Filename; + } + + public void setFilename(String Filename) { + this.Filename = Filename; + } +}