From 630f4459c171d37453049a2841149b024e26d0c5 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Thu, 23 May 2024 19:35:19 +0530 Subject: [PATCH 01/10] Add database and API level changes to save keyType of a client certificate --- .../wso2/carbon/apimgt/api/APIProvider.java | 6 +++-- .../apimgt/api/dto/ClientCertificateDTO.java | 21 ++++++++++++++++ .../carbon/apimgt/impl/APIProviderImpl.java | 12 +++++---- .../apimgt/impl/UserAwareAPIProvider.java | 11 +++++--- .../certificatemgt/CertificateManager.java | 8 +++--- .../CertificateManagerImpl.java | 11 ++++---- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 16 +++++++++--- .../apimgt/impl/dao/CertificateMgtDAO.java | 20 ++++++++++----- .../impl/dao/constants/SQLConstants.java | 25 ++++++++++--------- .../src/main/resources/publisher-api.yaml | 11 ++++++++ .../v1/dto/ClientCertMetadataDTO.java | 24 ++++++++++++++++-- .../mappings/CertificateRestApiUtils.java | 1 + .../v1/common/mappings/ImportUtils.java | 6 ++--- .../apimgt/rest/api/publisher/v1/ApisApi.java | 8 +++--- .../rest/api/publisher/v1/ApisApiService.java | 4 +-- .../publisher/v1/impl/ApisApiServiceImpl.java | 19 +++++++++++--- .../src/main/resources/publisher-api.yaml | 11 ++++++++ 17 files changed, 158 insertions(+), 56 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java index bd7768f3b3b7..74097d691639 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java @@ -805,6 +805,7 @@ String addBlockCondition(String conditionType, String conditionValue, boolean co * @param apiTypeWrapper : API Type Wrapper. * @param certificate : Relevant public certificate. * @param alias : Alias of the certificate. + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param organization : Organization * @return SUCCESS : If operation succeeded, * INTERNAL_SERVER_ERROR : If any internal error occurred, @@ -813,7 +814,7 @@ String addBlockCondition(String conditionType, String conditionValue, boolean co * @throws APIManagementException API Management Exception. */ int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String certificate, String alias, - String tierName, String organization) throws APIManagementException; + String tierName, String keyType, String organization) throws APIManagementException; /** * Method to remove the certificate which mapped to the given alias, endpoint from publisher and gateway nodes. @@ -967,6 +968,7 @@ ClientCertificateDTO getClientCertificate(String alias, ApiTypeWrapper apiTypeWr * @param alias : Alias of the certificate. * @param apiTypeWrapper : API Identifier of the certificate. * @param tier : tier name. + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param tenantId : Id of tenant. * @param organization : organization * @return : 1 : If client certificate update is successful, @@ -976,7 +978,7 @@ ClientCertificateDTO getClientCertificate(String alias, ApiTypeWrapper apiTypeWr * @throws APIManagementException API Management Exception. */ int updateClientCertificate(String certificate, String alias, ApiTypeWrapper apiTypeWrapper, String tier, - int tenantId, String organization) throws APIManagementException; + String keyType, int tenantId, String organization) throws APIManagementException; /** * Retrieve the certificate which matches the given alias. diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java index 0d6313f93904..a08923d0b7fa 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java @@ -28,8 +28,12 @@ public class ClientCertificateDTO { private String certificate; private String uniqueId; private String tierName; + private String keyType; private APIIdentifier apiIdentifier; + public ClientCertificateDTO() { + } + /** * To get the identifier of the API related with client certificate. * @@ -65,6 +69,23 @@ public void setTierName(String tierName) { this.tierName = tierName; } + /** + * To get the endpoint type of the certificate. + * @return endpoint type. + */ + public String getKeyType() { + return keyType; + } + + /** + * To set the endpoint type for the current certificate. + * + * @param keyType endpoint type (whether PRODUCTION or SANDBOX). + */ + public void setKeyType(String keyType) { + this.keyType = keyType; + } + /** * To get the alias of the certificate. * diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java index 1fa259d8148d..abe716263cf5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java @@ -3985,14 +3985,15 @@ public int addCertificate(String userName, String certificate, String alias, Str @Override public int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String certificate, String alias, - String tierName, String organization) throws APIManagementException { + String tierName, String keyType, String organization) + throws APIManagementException { checkAccessControlPermission(userNameWithoutChange, apiTypeWrapper.getAccessControl(), apiTypeWrapper.getAccessControlRoles()); ResponseCode responseCode = ResponseCode.INTERNAL_SERVER_ERROR; int tenantId = APIUtil.getInternalOrganizationId(organization); - responseCode = certificateManager - .addClientCertificate(apiTypeWrapper.getId(), certificate, alias, tierName, tenantId, organization); + responseCode = certificateManager.addClientCertificate(apiTypeWrapper.getId(), certificate, + alias, tierName, keyType, tenantId, organization); return responseCode.getResponseCode(); } @@ -4136,11 +4137,12 @@ public int updateCertificate(String certificateString, String alias) throws APIM @Override public int updateClientCertificate(String certificate, String alias, ApiTypeWrapper apiTypeWrapper, - String tier, int tenantId, String organization) throws APIManagementException { + String tier, String keyType, int tenantId, String organization) + throws APIManagementException { checkAccessControlPermission(userNameWithoutChange, apiTypeWrapper.getAccessControl(), apiTypeWrapper.getAccessControlRoles()); ResponseCode responseCode = certificateManager - .updateClientCertificate(certificate, alias, tier, tenantId, organization); + .updateClientCertificate(certificate, alias, tier, keyType, tenantId, organization); return responseCode != null ? responseCode.getResponseCode() : ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java index 0b654fdd81b8..f408ec12e175 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java @@ -102,8 +102,9 @@ public SubscribedAPI getSubscriptionByUUID(String uuid) throws APIManagementExce @Override public int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String certificate, String alias, - String tierName, String organization) throws APIManagementException { - return super.addClientCertificate(userName, apiTypeWrapper, certificate, alias, tierName, organization); + String tierName, String keyType, String organization) throws APIManagementException { + return super.addClientCertificate(userName, apiTypeWrapper, certificate, alias, tierName, keyType, + organization); } @Override @@ -156,8 +157,10 @@ public int updateCertificate(String certificateString, String alias) throws APIM @Override public int updateClientCertificate(String certificate, String alias, ApiTypeWrapper apiIdentifier, - String tier, int tenantId, String organization) throws APIManagementException { - return super.updateClientCertificate(certificate, alias, apiIdentifier, tier, tenantId, organization); + String tier, String keyType, int tenantId, String organization) + throws APIManagementException { + return super.updateClientCertificate(certificate, alias, apiIdentifier, tier, keyType, + tenantId, organization); } @Override diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java index e0b1f571cccb..1a93c464345b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java @@ -175,6 +175,7 @@ public interface CertificateManager { * @param apiIdentifier : Identifier of the relevant API, which the client certificate is added against. * @param certificate : Base64 encoded certificate string. * @param alias : Alias of the certificate. + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param tenantId : The tenant which the client certificate is added against * @param organization : Organization * @return SUCCESS : If Operation succeeded, INTERNAL_SERVER_ERROR : If any internal error occurred, @@ -182,7 +183,7 @@ public interface CertificateManager { * certificate is expired. */ ResponseCode addClientCertificate(Identifier apiIdentifier, String certificate, String alias, String tierName, - int tenantId, String organization); + String keyType, int tenantId, String organization); /** * Method to delete the client certificate from publisher node. @@ -233,11 +234,12 @@ List searchClientCertificates(int tenantId, String alias, * @param alias : The alias of the certificate that should be updated. * @param tenantId : Id of the tenant. * @param tier : Name of the tier + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param organization : Organization * @return : true if update succeeds, false if fails */ - ResponseCode updateClientCertificate(String certificate, String alias, String tier, int tenantId, - String organization) throws APIManagementException; + ResponseCode updateClientCertificate(String certificate, String alias, String tier, String keyType, + int tenantId, String organization) throws APIManagementException; /** * To get the count of the client certificates updated for the particular tenant. diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java index 72628214e74e..172e9a281506 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java @@ -114,7 +114,7 @@ public ResponseCode addCertificateToParentNode(String certificate, String alias, @Override public ResponseCode addClientCertificate(Identifier apiIdentifier, String certificate, String alias, - String tierName, int tenantId, String organization) { + String tierName, String keyType, int tenantId, String organization) { ResponseCode responseCode; try { @@ -124,7 +124,8 @@ public ResponseCode addClientCertificate(Identifier apiIdentifier, String certif responseCode = ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE; } else { certificateMgtDAO - .addClientCertificate(certificate, apiIdentifier, alias, tierName, tenantId, organization); + .addClientCertificate(certificate, apiIdentifier, alias, tierName, keyType, + tenantId, organization); } } } catch (CertificateManagementException e) { @@ -454,8 +455,8 @@ public ResponseCode updateCertificate(String certificate, String alias) throws A } @Override - public ResponseCode updateClientCertificate(String certificate, String alias, String tier, int tenantId, - String organization) throws APIManagementException { + public ResponseCode updateClientCertificate(String certificate, String alias, String tier, String keyType, + int tenantId, String organization) throws APIManagementException { ResponseCode responseCode = ResponseCode.SUCCESS; if (StringUtils.isNotEmpty(certificate)) { @@ -464,7 +465,7 @@ public ResponseCode updateClientCertificate(String certificate, String alias, St try { if (responseCode.getResponseCode() == ResponseCode.SUCCESS.getResponseCode()) { boolean isSuccess = certificateMgtDAO - .updateClientCertificate(certificate, alias, tier, tenantId, organization); + .updateClientCertificate(certificate, alias, tier, keyType, tenantId, organization); if (isSuccess) { responseCode = ResponseCode.SUCCESS; } else { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index 46487e01080e..139319fef8e0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -17046,6 +17046,7 @@ public void addAPIRevision(APIRevision apiRevision) throws APIManagementExceptio clientCertificateDTO.setAlias(rs.getString(1)); clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTO.setKeyType(rs.getString(4)); clientCertificateDTOS.add(clientCertificateDTO); } } @@ -17059,7 +17060,8 @@ public void addAPIRevision(APIRevision apiRevision) throws APIManagementExceptio getInputStream(clientCertificateDTO.getCertificate())); insertClientCertificateStatement.setBoolean(5, false); insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, apiRevision.getRevisionUUID()); + insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); + insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); insertClientCertificateStatement.addBatch(); } insertClientCertificateStatement.executeBatch(); @@ -17964,6 +17966,7 @@ public void restoreAPIRevision(APIRevision apiRevision) throws APIManagementExce clientCertificateDTO.setAlias(rs.getString(1)); clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTO.setKeyType(rs.getString(4)); clientCertificateDTOS.add(clientCertificateDTO); } } @@ -17977,7 +17980,8 @@ public void restoreAPIRevision(APIRevision apiRevision) throws APIManagementExce getInputStream(clientCertificateDTO.getCertificate())); insertClientCertificateStatement.setBoolean(5, false); insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, "Current API"); + insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); + insertClientCertificateStatement.setString(8, "Current API"); insertClientCertificateStatement.addBatch(); } insertClientCertificateStatement.executeBatch(); @@ -18282,6 +18286,7 @@ public void addAPIProductRevision(APIRevision apiRevision) throws APIManagementE clientCertificateDTO.setAlias(rs.getString(1)); clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTO.setKeyType(rs.getString(4)); clientCertificateDTOS.add(clientCertificateDTO); } } @@ -18295,7 +18300,8 @@ public void addAPIProductRevision(APIRevision apiRevision) throws APIManagementE getInputStream(clientCertificateDTO.getCertificate())); insertClientCertificateStatement.setBoolean(5, false); insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, apiRevision.getRevisionUUID()); + insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); + insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); insertClientCertificateStatement.addBatch(); } insertClientCertificateStatement.executeBatch(); @@ -18522,6 +18528,7 @@ public void restoreAPIProductRevision(APIRevision apiRevision) throws APIManagem clientCertificateDTO.setAlias(rs.getString(1)); clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTO.setKeyType(rs.getString(4)); clientCertificateDTOS.add(clientCertificateDTO); } } @@ -18535,7 +18542,8 @@ public void restoreAPIProductRevision(APIRevision apiRevision) throws APIManagem getInputStream(clientCertificateDTO.getCertificate())); insertClientCertificateStatement.setBoolean(5, false); insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, "Current API"); + insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); + insertClientCertificateStatement.setString(8, "Current API"); insertClientCertificateStatement.addBatch(); } insertClientCertificateStatement.executeBatch(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java index b295526bf04b..6a96343e6897 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java @@ -73,7 +73,7 @@ public static CertificateMgtDAO getInstance() { private boolean addClientCertificate(Connection connection, String certificate, Identifier apiIdentifier, - String alias, String tierName, + String alias, String tierName, String keyType, int tenantId, String organization) throws SQLException { boolean result; @@ -87,6 +87,7 @@ private boolean addClientCertificate(Connection connection, String certificate, preparedStatement.setString(6, apiIdentifier.getVersion()); preparedStatement.setString(7, organization); preparedStatement.setString(8, tierName); + preparedStatement.setString(9, keyType); result = preparedStatement.executeUpdate() >= 1; } return result; @@ -98,13 +99,14 @@ private boolean addClientCertificate(Connection connection, String certificate, * @param certificate : Specific certificate. * @param alias : Alias of the certificate. * @param tier : Name of tier related with the certificate. + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param tenantId : ID of the tenant. * @param organization : Organization * @return true if the update succeeds, unless false. * @throws CertificateManagementException Certificate Management Exception. */ - public boolean updateClientCertificate(String certificate, String alias, String tier, int tenantId, - String organization) throws CertificateManagementException { + public boolean updateClientCertificate(String certificate, String alias, String tier, String keyType, + int tenantId, String organization) throws CertificateManagementException { List clientCertificateDTOList = getClientCertificates(tenantId, alias, null, organization); @@ -124,13 +126,16 @@ public boolean updateClientCertificate(String certificate, String alias, String if (StringUtils.isNotEmpty(tier)) { clientCertificateDTO.setTierName(tier); } + if (StringUtils.isNotEmpty(tier)) { + clientCertificateDTO.setKeyType(keyType); + } try (Connection connection = APIMgtDBUtil.getConnection()) { try { connection.setAutoCommit(false); deleteClientCertificate(connection, null, alias, tenantId); addClientCertificate(connection, clientCertificateDTO.getCertificate(), clientCertificateDTO.getApiIdentifier(), alias, clientCertificateDTO.getTierName(), - tenantId, organization); + clientCertificateDTO.getKeyType(), tenantId, organization); connection.commit(); } catch (SQLException e) { handleConnectionRollBack(connection); @@ -296,6 +301,7 @@ public List getClientCertificates(int tenantId, String ali alias = resultSet.getString("ALIAS"); ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); clientCertificateDTO.setTierName(resultSet.getString("TIER_NAME")); + clientCertificateDTO.setKeyType(resultSet.getString("KEY_TYPE")); clientCertificateDTO.setAlias(alias); clientCertificateDTO.setCertificate( APIMgtDBUtil.getStringFromInputStream(resultSet.getBinaryStream("CERTIFICATE"))); @@ -742,19 +748,21 @@ private void handleException(String message, Throwable e) throws CertificateMana * @param certificate : Client certificate that need to be added. * @param apiIdentifier : API which the client certificate is uploaded against. * @param alias : Alias for the new certificate. + * @param keyType : Key type for the certificate (PRODUCTION or SANDBOX). * @param tenantId : The Id of the tenant who uploaded the certificate. * @param organization : Organization * @return : True if the information is added successfully, false otherwise. * @throws CertificateManagementException if existing entry is found for the given endpoint or alias. */ public boolean addClientCertificate(String certificate, Identifier apiIdentifier, String alias, String tierName, - int tenantId, String organization) throws CertificateManagementException { + String keyType, int tenantId, String organization) + throws CertificateManagementException { try (Connection connection = APIMgtDBUtil.getConnection()) { try { connection.setAutoCommit(false); boolean status = addClientCertificate(connection, certificate, apiIdentifier, alias, tierName, - tenantId, organization); + keyType, tenantId, organization); connection.commit(); return status; } catch (SQLException e) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java index 063d16f7093b..daf89df31ade 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java @@ -3389,8 +3389,9 @@ public static class CertificateConstants { public static class ClientCertificateConstants{ public static final String INSERT_CERTIFICATE = "INSERT INTO AM_API_CLIENT_CERTIFICATE " + - "(CERTIFICATE, TENANT_ID, ALIAS, API_ID, TIER_NAME) VALUES(?, ?, ?, (SELECT API_ID FROM AM_API WHERE " + - "API_PROVIDER = ? AND API_NAME = ? AND API_VERSION = ? AND ORGANIZATION = ? ), ?)"; + "(CERTIFICATE, TENANT_ID, ALIAS, API_ID, TIER_NAME, KEY_TYPE) " + + "VALUES(?, ?, ?, (SELECT API_ID FROM AM_API WHERE " + + "API_PROVIDER = ? AND API_NAME = ? AND API_VERSION = ? AND ORGANIZATION = ? ), ?, ?)"; public static final String GET_CERTIFICATES_FOR_API = "SELECT ALIAS FROM AM_API_CLIENT_CERTIFICATE WHERE " + "TENANT_ID=? and API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND API_NAME = ? AND " + @@ -3404,21 +3405,21 @@ public static class ClientCertificateConstants{ + "WHERE ALIAS=? AND REMOVED=? AND TENANT_ID =? and REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AA.API_PROVIDER, AA.API_NAME, " + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE, AA.API_PROVIDER, AA.API_NAME, " + "AA.API_VERSION FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA " + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_ALIAS = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AA.API_PROVIDER, AA.API_NAME, AA.API_VERSION " + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE, AA.API_PROVIDER, AA.API_NAME, AA.API_VERSION " + "FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA " + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.ALIAS=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_ALIAS_APIID = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME FROM AM_API_CLIENT_CERTIFICATE AC " + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE AC " + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.ALIAS=? AND AC.API_ID = ? AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_APIID = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME FROM AM_API_CLIENT_CERTIFICATE AC " + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE AC " + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.API_ID=? AND AC.REVISION_UUID ='Current API'"; public static final String PRE_DELETE_CERTIFICATES = "DELETE FROM AM_API_CLIENT_CERTIFICATE " @@ -3803,15 +3804,15 @@ public static class APIRevisionSqlConstants { public static final String INSERT_URL_MAPPINGS = "INSERT INTO AM_API_URL_MAPPING(API_ID, HTTP_METHOD," + " AUTH_SCHEME, URL_PATTERN, THROTTLING_TIER, REVISION_UUID) VALUES(?,?,?,?,?,?)"; public static final String GET_CLIENT_CERTIFICATES = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=FALSE"; + " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=FALSE"; public static final String GET_CLIENT_CERTIFICATES_MSSQL = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; + " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; public static final String GET_CLIENT_CERTIFICATES_ORACLE_SQL = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; + " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; public static final String INSERT_CLIENT_CERTIFICATES = "INSERT INTO AM_API_CLIENT_CERTIFICATE(TENANT_ID, " + - "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, REVISION_UUID) VALUES(?,?,?,?,?,?,?)"; + "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, KEY_TYPE, REVISION_UUID) VALUES(?,?,?,?,?,?,?,?)"; public static final String GET_GRAPHQL_COMPLEXITY = "SELECT TYPE, FIELD, COMPLEXITY_VALUE " + "FROM AM_GRAPHQL_COMPLEXITY WHERE API_ID = ? AND REVISION_UUID IS NULL"; public static final String INSERT_GRAPHQL_COMPLEXITY = "INSERT INTO AM_GRAPHQL_COMPLEXITY(UUID, API_ID, TYPE," + @@ -3921,9 +3922,9 @@ public static class APIRevisionSqlConstants { public static final String REMOVE_CURRENT_API_ENTRIES_IN_AM_API_CLIENT_CERTIFICATE_BY_API_ID = "DELETE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API'"; public static final String GET_CLIENT_CERTIFICATES_BY_REVISION_UUID = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID = ?"; + " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID = ?"; public static final String INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API = "INSERT INTO AM_API_CLIENT_CERTIFICATE(TENANT_ID, " + - "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, REVISION_UUID) VALUES(?,?,?,?,?,?,?)"; + "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, KEY_TYPE, REVISION_UUID) VALUES(?,?,?,?,?,?,?,?)"; public static final String REMOVE_CURRENT_API_ENTRIES_IN_AM_GRAPHQL_COMPLEXITY_BY_API_ID = "DELETE FROM AM_GRAPHQL_COMPLEXITY WHERE API_ID = ? AND REVISION_UUID IS NULL"; public static final String GET_GRAPHQL_COMPLEXITY_BY_REVISION_UUID = "SELECT TYPE, FIELD, COMPLEXITY_VALUE " + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index b7ba04b85b54..2139dec5d7ce 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4629,6 +4629,10 @@ paths: tier: type: string description: API tier to which the certificate should be applied. + keyType: + type: string + description: Whether the endpoint is production or sandbox + default: PRODUCTION required: true responses: 200: @@ -4741,6 +4745,10 @@ paths: tier: type: string description: The tier of the certificate + keyType: + type: string + description: Whether the endpoint is production or sandbox + default: PRODUCTION responses: 200: description: | @@ -11331,6 +11339,9 @@ components: tier: type: string example: Gold + keyType: + type: string + example: PRODUCTION description: Meta data of certificate LifecycleState: title: Lifecycle State diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java index 7a58d442b036..b0ef195efde1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java @@ -26,6 +26,7 @@ public class ClientCertMetadataDTO { private String alias = null; private String apiId = null; private String tier = null; + private String keyType = null; /** **/ @@ -78,6 +79,23 @@ public void setTier(String tier) { this.tier = tier; } + /** + **/ + public ClientCertMetadataDTO keyType(String keyType) { + this.keyType = keyType; + return this; + } + + + @ApiModelProperty(example = "PRODUCTION", value = "") + @JsonProperty("keyType") + public String getKeyType() { + return keyType; + } + public void setKeyType(String keyType) { + this.keyType = keyType; + } + @Override public boolean equals(java.lang.Object o) { @@ -90,12 +108,13 @@ public boolean equals(java.lang.Object o) { ClientCertMetadataDTO clientCertMetadata = (ClientCertMetadataDTO) o; return Objects.equals(alias, clientCertMetadata.alias) && Objects.equals(apiId, clientCertMetadata.apiId) && - Objects.equals(tier, clientCertMetadata.tier); + Objects.equals(tier, clientCertMetadata.tier) && + Objects.equals(keyType, clientCertMetadata.keyType); } @Override public int hashCode() { - return Objects.hash(alias, apiId, tier); + return Objects.hash(alias, apiId, tier, keyType); } @Override @@ -106,6 +125,7 @@ public String toString() { sb.append(" alias: ").append(toIndentedString(alias)).append("\n"); sb.append(" apiId: ").append(toIndentedString(apiId)).append("\n"); sb.append(" tier: ").append(toIndentedString(tier)).append("\n"); + sb.append(" keyType: ").append(toIndentedString(keyType)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java index b8eafcafdfff..e965c8d3afb2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java @@ -195,6 +195,7 @@ public static ClientCertificatesDTO getPaginatedClientCertificates( clientCertMetadataDTO.setAlias(clientCertificateDTO.getAlias()); clientCertMetadataDTO.setApiId(clientCertificateDTO.getApiIdentifier().toString()); clientCertMetadataDTO.setTier(clientCertificateDTO.getTierName()); + clientCertMetadataDTO.setKeyType(clientCertificateDTO.getKeyType()); clientCertificateList.add(clientCertMetadataDTO); } Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, certCount); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java index 6767bef2e955..b3d30ed6e1f8 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java @@ -2263,10 +2263,10 @@ private static void addClientCertificates(String pathToArchive, APIProvider apiP for (ClientCertificateDTO certDTO : certificateMetadataDTOS) { if (ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode() == (apiProvider.addClientCertificate( APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName()), apiTypeWrapper, - certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(), organization)) - && isOverwrite) { + certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(),certDTO.getKeyType(), + organization)) && isOverwrite) { apiProvider.updateClientCertificate(certDTO.getCertificate(), certDTO.getAlias(), apiTypeWrapper, - certDTO.getTierName(), tenantId, organization); + certDTO.getTierName(), certDTO.getKeyType(), tenantId, organization); } } } catch (APIManagementException e) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index ed7d69ed0f06..fff5a1bc18b3 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -95,8 +95,8 @@ public class ApisApi { @ApiResponse(code = 200, message = "OK. The Certificate added successfully. ", response = ClientCertMetadataDTO.class), @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) - public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate") InputStream certificateInputStream, @Multipart(value = "certificate" ) Attachment certificateDetail, @Multipart(value = "alias") String alias, @Multipart(value = "tier") String tier) throws APIManagementException{ - return delegate.addAPIClientCertificate(apiId, certificateInputStream, certificateDetail, alias, tier, securityContext); + public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate") InputStream certificateInputStream, @Multipart(value = "certificate" ) Attachment certificateDetail, @Multipart(value = "alias") String alias, @Multipart(value = "tier") String tier, @Multipart(value = "keyType", required = false) String keyType) throws APIManagementException{ + return delegate.addAPIClientCertificate(apiId, certificateInputStream, certificateDetail, alias, tier, keyType, securityContext); } @POST @@ -1547,8 +1547,8 @@ public Response undeployAPIRevision(@ApiParam(value = "**API ID** consisting of @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) - public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam(value = "Alias for the certificate",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate", required = false) InputStream certificateInputStream, @Multipart(value = "certificate" , required = false) Attachment certificateDetail, @Multipart(value = "tier", required = false) String tier) throws APIManagementException{ - return delegate.updateAPIClientCertificateByAlias(alias, apiId, certificateInputStream, certificateDetail, tier, securityContext); + public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam(value = "Alias for the certificate",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate", required = false) InputStream certificateInputStream, @Multipart(value = "certificate" , required = false) Attachment certificateDetail, @Multipart(value = "tier", required = false) String tier, @Multipart(value = "keyType", required = false) String keyType) throws APIManagementException{ + return delegate.updateAPIClientCertificateByAlias(alias, apiId, certificateInputStream, certificateDetail, tier, keyType, securityContext); } @PUT diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java index 10f13b24633d..1b43f8b5b327 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java @@ -64,7 +64,7 @@ public interface ApisApiService { - public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, MessageContext messageContext) throws APIManagementException; + public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, String keyType, MessageContext messageContext) throws APIManagementException; public Response addAPIDocument(String apiId, DocumentDTO documentDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response addAPIDocumentContent(String apiId, String documentId, String ifMatch, InputStream fileInputStream, Attachment fileDetail, String inlineContent, MessageContext messageContext) throws APIManagementException; public Response addAPIMonetization(String apiId, APIMonetizationInfoDTO apIMonetizationInfoDTO, MessageContext messageContext) throws APIManagementException; @@ -138,7 +138,7 @@ public interface ApisApiService { public Response restoreAPIRevision(String apiId, String revisionId, MessageContext messageContext) throws APIManagementException; public Response undeployAPIRevision(String apiId, String revisionId, String revisionNumber, Boolean allEnvironments, List apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPI(String apiId, APIDTO APIDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; - public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) throws APIManagementException; + public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, String keyType, MessageContext messageContext) throws APIManagementException; public Response updateAPIDeployment(String apiId, String deploymentId, APIRevisionDeploymentDTO apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPIDocument(String apiId, String documentId, DocumentDTO documentDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response updateAPIGraphQLSchema(String apiId, String schemaDefinition, String ifMatch, MessageContext messageContext) throws APIManagementException; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java index 3d4e3ba1e684..fdff880b467c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java @@ -964,7 +964,7 @@ public Response getAPIClientCertificateByAlias(String alias, String apiId, public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, - MessageContext messageContext) { + String keyType, MessageContext messageContext) { try { //validate if api exists CommonUtils.validateAPIExistence(apiId); @@ -991,13 +991,18 @@ public Response updateAPIClientCertificateByAlias(String alias, String apiId, if (StringUtils.isEmpty(base64EncodedCert) && StringUtils.isEmpty(tier)) { return Response.ok().entity("Client Certificate is not updated for alias " + alias).build(); } + // to make the API consistent + if (StringUtils.isEmpty(keyType)) { + keyType = APIConstants.API_KEY_TYPE_PRODUCTION; + } int responseCode = apiProvider - .updateClientCertificate(base64EncodedCert, alias, apiTypeWrapper, tier, + .updateClientCertificate(base64EncodedCert, alias, apiTypeWrapper, tier, keyType.toUpperCase(), tenantId, organization); if (ResponseCode.SUCCESS.getResponseCode() == responseCode) { ClientCertMetadataDTO clientCertMetadataDTO = new ClientCertMetadataDTO(); clientCertMetadataDTO.setAlias(alias); + clientCertMetadataDTO.setKeyType(keyType.toUpperCase()); clientCertMetadataDTO.setApiId(apiTypeWrapper.getUuid()); clientCertMetadataDTO.setTier(clientCertificateDTO.getTierName()); URI updatedCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + "?alias=" + alias); @@ -1068,7 +1073,7 @@ public Response getAPIClientCertificates(String apiId, Integer limit, Integer of @Override public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, - MessageContext messageContext) { + String keyType, MessageContext messageContext) { try { APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); ContentDisposition contentDisposition = certificateDetail.getContentDisposition(); @@ -1081,6 +1086,10 @@ public Response addAPIClientCertificate(String apiId, InputStream certificateInp RestApiUtil.handleBadRequest( "Certificate addition failed. Proper Certificate file should be provided", log); } + // to make the API consistent + if (StringUtils.isBlank(keyType)) { + keyType = APIConstants.API_KEY_TYPE_PRODUCTION; + } //validate if api exists CommonUtils.validateAPIExistence(apiId); @@ -1092,7 +1101,8 @@ public Response addAPIClientCertificate(String apiId, InputStream certificateInp String userName = RestApiCommonUtil.getLoggedInUsername(); String base64EncodedCert = CertificateRestApiUtils.generateEncodedCertificate(certificateInputStream); int responseCode = apiProvider - .addClientCertificate(userName, apiTypeWrapper, base64EncodedCert, alias, tier, organization); + .addClientCertificate(userName, apiTypeWrapper, base64EncodedCert, alias, tier, + keyType.toUpperCase(), organization); if (log.isDebugEnabled()) { log.debug(String.format("Add certificate operation response code : %d", responseCode)); } @@ -1101,6 +1111,7 @@ public Response addAPIClientCertificate(String apiId, InputStream certificateInp certificateDTO.setAlias(alias); certificateDTO.setApiId(apiId); certificateDTO.setTier(tier); + certificateDTO.setKeyType(keyType.toUpperCase()); URI createdCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + "?alias=" + alias); return Response.created(createdCertUri).entity(certificateDTO).build(); } else if (ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode() == responseCode) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index b7ba04b85b54..2139dec5d7ce 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4629,6 +4629,10 @@ paths: tier: type: string description: API tier to which the certificate should be applied. + keyType: + type: string + description: Whether the endpoint is production or sandbox + default: PRODUCTION required: true responses: 200: @@ -4741,6 +4745,10 @@ paths: tier: type: string description: The tier of the certificate + keyType: + type: string + description: Whether the endpoint is production or sandbox + default: PRODUCTION responses: 200: description: | @@ -11331,6 +11339,9 @@ components: tier: type: string example: Gold + keyType: + type: string + example: PRODUCTION description: Meta data of certificate LifecycleState: title: Lifecycle State From bb8a0347b4dec5fa31f8f651cdc03344c3dbe4f3 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Wed, 29 May 2024 20:57:00 +0530 Subject: [PATCH 02/10] Append key type to clientCertificateObject in TemplateBuilder and access the keyType to set in authContext at MutualSSLAuthenticator --- .../apimgt/api/dto/ClientCertificateDTO.java | 8 +- .../security/APIAuthenticationHandler.java | 20 +++++ .../authenticator/MutualSSLAuthenticator.java | 87 ++++++++++++++----- .../wso2/carbon/apimgt/impl/APIConstants.java | 3 + .../apimgt/impl/dao/CertificateMgtDAO.java | 2 +- .../importexport/ImportExportConstants.java | 1 + .../src/main/resources/publisher-api.yaml | 4 +- .../v1/common/TemplateBuilderUtil.java | 15 +++- .../v1/common/mappings/APIControllerUtil.java | 1 + .../src/main/resources/publisher-api.yaml | 4 +- 10 files changed, 110 insertions(+), 35 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java index a08923d0b7fa..a641f650f8e5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java @@ -70,17 +70,17 @@ public void setTierName(String tierName) { } /** - * To get the endpoint type of the certificate. - * @return endpoint type. + * To get the key type of the certificate. + * @return key type. */ public String getKeyType() { return keyType; } /** - * To set the endpoint type for the current certificate. + * To set the key type for the current certificate. * - * @param keyType endpoint type (whether PRODUCTION or SANDBOX). + * @param keyType key type (whether PRODUCTION or SANDBOX). */ public void setKeyType(String keyType) { this.keyType = keyType; diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java index e68aca00112d..95b5ba332b05 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java @@ -97,6 +97,7 @@ public class APIAuthenticationHandler extends AbstractHandler implements Managed private String apiKeyHeader; private String apiSecurity; private String apiLevelPolicy; + private String environmentType; private String certificateInformation; private String apiUUID; private String apiType = String.valueOf(APIConstants.ApiTypes.API); // Default API Type @@ -151,6 +152,24 @@ public void setAPILevelPolicy(String apiLevelPolicy) { this.apiLevelPolicy = apiLevelPolicy; } + /** + * To get the environment type (whether production or sandbox). + * + * @return the environment type. + */ + public String getEnvironmentType() { + return environmentType; + } + + /** + * To set the environment type (whether production or sandbox). + * + * @param environmentType the environment type. + */ + public void setEnvironmentType(String environmentType) { + this.environmentType = environmentType; + } + /** * Get type of the API * @return API Type @@ -525,6 +544,7 @@ private void handleNoAuthentication(MessageContext messageContext){ authContext.setStopOnQuotaReach(true); //Requests are throttled by the ApiKey that is set here. In an unauthenticated scenario, we will use the client's IP address for throttling. authContext.setApiKey(clientIP); + //TODO: verify the key type authContext.setKeyType(APIConstants.API_KEY_TYPE_PRODUCTION); //This name is hardcoded as anonymous because there is no associated user token authContext.setUsername(APIConstants.END_USER_ANONYMOUS); diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java index fa1afaa84c24..17603224f53a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java @@ -60,7 +60,7 @@ public class MutualSSLAuthenticator implements Authenticator { private boolean isMandatory; // -Format - private HashMap certificates; + private HashMap> certificates; /** * Initialized the mutual SSL authenticator. @@ -71,14 +71,18 @@ public class MutualSSLAuthenticator implements Authenticator { public MutualSSLAuthenticator(String apiLevelPolicy, boolean isMandatory, String certificateDetails) { this.apiLevelPolicy = apiLevelPolicy; certificates = new HashMap<>(); + HashMap certificateData = new HashMap<>(); if (StringUtils.isNotEmpty(certificateDetails)) { String[] certificateParts = certificateDetails.substring(1, certificateDetails.length() - 1).split(","); for (String certificatePart : certificateParts) { int tierDivisionIndex = certificatePart.lastIndexOf("="); if (tierDivisionIndex > 0) { String uniqueIdentifier = certificatePart.substring(0, tierDivisionIndex).trim(); - String tier = certificatePart.substring(tierDivisionIndex + 1); - certificates.put(uniqueIdentifier, tier); + String tierAndKeyTypeString = certificatePart.substring(tierDivisionIndex + 1); + String[] tierAndKeyType = tierAndKeyTypeString.split(APIConstants.DELEM_COLON); + certificateData.put(APIConstants.CLIENT_CERTIFICATE_TIER, tierAndKeyType[0]); + certificateData.put(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE, tierAndKeyType[1]); + certificates.put(uniqueIdentifier, certificateData); } } } @@ -177,11 +181,12 @@ private void setAuthContext(MessageContext messageContext, Certificate certifica String subjectDN = x509Certificate.getSubjectDN().getName(); String uniqueIdentifier = (x509Certificate.getSerialNumber() + "_" + x509Certificate.getSubjectDN()).replaceAll(",", "#").replaceAll("\"", "'").trim(); - String tier = certificates.get(uniqueIdentifier); + String tier = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_TIER); + String keyType = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); if (StringUtils.isEmpty(tier)) { handleCertificateNotAssociatedToAPIFailure(messageContext); } - setAuthenticationContext(messageContext, subjectDN, uniqueIdentifier, tier); + setAuthenticationContext(messageContext, subjectDN, uniqueIdentifier, tier, keyType); } /** @@ -195,6 +200,7 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi throws APISecurityException, APIManagementException { String tier = null; + String keyType = null; List x509Certificates = Utils.convertCertificatesToX509Certificates(certificatesArray); String subjectDN = x509Certificates.get(0).getSubjectDN().getName(); String issuerDNIdentifier = x509Certificates.get(x509Certificates.size() - 1).getIssuerDN().getName() @@ -205,11 +211,12 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi String subjectDNIdentifier = (x509Certificate.getSerialNumber() + "_" + x509Certificate.getSubjectDN()).replaceAll(",", "#").replaceAll("\"", "'").trim(); subjectDNIdentifiers.add(subjectDNIdentifier); - for (Map.Entry entry : certificates.entrySet()) { + for (Map.Entry> entry : certificates.entrySet()) { String key = entry.getKey(); if (StringUtils.equals(subjectDNIdentifier, key)) { uniqueIdentifier = key; - tier = entry.getValue(); + tier = entry.getValue().get(APIConstants.CLIENT_CERTIFICATE_TIER); + keyType = entry.getValue().get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); break; } } @@ -218,36 +225,41 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi } } if (StringUtils.isEmpty(tier)) { - for (Map.Entry entry : certificates.entrySet()) { + for (Map.Entry> entry : certificates.entrySet()) { String key = entry.getKey(); if (key.contains(issuerDNIdentifier)) { uniqueIdentifier = key; - tier = entry.getValue(); + tier = entry.getValue().get(APIConstants.CLIENT_CERTIFICATE_TIER); + keyType = entry.getValue().get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); } } } - if (StringUtils.isEmpty(tier)) { - tier = getTierFromCompleteCertificateChain(x509Certificates, subjectDNIdentifiers); + if (StringUtils.isEmpty(tier) || StringUtils.isEmpty(keyType)) { + subjectDNIdentifiers = getUniqueIdentifierFromCompleteCertificateChain(x509Certificates, subjectDNIdentifiers); } if (StringUtils.isEmpty(tier)) { + tier = getTierFromCompleteCertificateChain(subjectDNIdentifiers); + } + if (StringUtils.isEmpty(keyType)) { + keyType = getKeyTypeFromCompleteCertificateChain(subjectDNIdentifiers); + } + if (StringUtils.isEmpty(tier) || StringUtils.isEmpty(keyType)) { handleCertificateNotAssociatedToAPIFailure(messageContext); } - setAuthenticationContext(messageContext, subjectDN, uniqueIdentifier, tier); + setAuthenticationContext(messageContext, subjectDN, uniqueIdentifier, tier, keyType); } /** - * Fetches tier assigned to the client certificate after making the complete certificate chain using certificates - * in truststore. + * Fetches the list of uniqueIdentifiers for complete certificate chain using certificates in truststore. * - * @param x509Certificates Client certificate chain + * @param x509Certificates client certificates chain * @param uniqueIdentifiers Unique identifiers list for client certificate chain - * @return Tier + * @return uniqueIdentifiers * @throws APIManagementException */ - private String getTierFromCompleteCertificateChain(List x509Certificates, - List uniqueIdentifiers) throws APIManagementException { + private List getUniqueIdentifierFromCompleteCertificateChain(List x509Certificates, + List uniqueIdentifiers) throws APIManagementException { - String tier = null; X509Certificate certificate = x509Certificates.get(x509Certificates.size() - 1); String subjectDN = certificate.getSubjectDN().getName(); String issuerDN = certificate.getIssuerDN().getName(); @@ -266,9 +278,21 @@ private String getTierFromCompleteCertificateChain(List x509Cer isIssuerCertificateUpdated = !StringUtils.equals(subjectDN, issuerDN); } } + return uniqueIdentifiers; + } + /** + * Fetches tier assigned to the client certificate after making the complete certificate chain using certificates + * in truststore. + * + * @param uniqueIdentifiers Unique identifiers list for client certificate chain + * @return Tier + */ + private String getTierFromCompleteCertificateChain(List uniqueIdentifiers) { + + String tier = null; for (String uniqueIdentifier : uniqueIdentifiers) { - tier = certificates.get(uniqueIdentifier); + tier = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_TIER); if (StringUtils.isNotEmpty(tier)) { break; } @@ -276,6 +300,25 @@ private String getTierFromCompleteCertificateChain(List x509Cer return tier; } + /** + * Fetches keyType assigned to the client certificate after making the complete certificate chain using certificates + * in truststore. + * + * @param uniqueIdentifiers Unique identifiers list for client certificate chain + * @return keyType + */ + private String getKeyTypeFromCompleteCertificateChain(List uniqueIdentifiers) { + + String keyType = null; + for (String uniqueIdentifier : uniqueIdentifiers) { + keyType = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); + if (StringUtils.isNotEmpty(keyType)) { + break; + } + } + return keyType; + } + /** * Handles failures where message context does not contain client certificates. * @param messageContext Relevant message context @@ -321,7 +364,7 @@ private void handleCertificateNotAssociatedToAPIFailure(MessageContext messageCo * @param tier Throttling policy tier */ private void setAuthenticationContext(MessageContext messageContext, String subjectDN, String uniqueIdentifier, - String tier) { + String tier, String keyType) { AuthenticationContext authContext = new AuthenticationContext(); authContext.setAuthenticated(true); @@ -340,7 +383,7 @@ private void setAuthenticationContext(MessageContext messageContext, String subj } authContext.setApiTier(apiLevelPolicy); APIIdentifier apiIdentifier = getAPIIdentifier(messageContext); - authContext.setKeyType(APIConstants.API_KEY_TYPE_PRODUCTION); + authContext.setKeyType(keyType); authContext.setStopOnQuotaReach(true); authContext.setApiKey(uniqueIdentifier + "_" + apiIdentifier.toString()); authContext.setTier(tier); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 337f3491f7ab..7f000ecce241 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -792,6 +792,9 @@ private Permissions() { public static final String API_KEY_VALIDATOR_URL = API_KEY_VALIDATOR + "ServerURL"; public static final String API_KEY_VALIDATOR_USERNAME = API_KEY_VALIDATOR + "Username"; public static final String API_KEY_VALIDATOR_PASSWORD = API_KEY_VALIDATOR + "Password"; + public static final String CLIENT_CERTIFICATE_TIER = "TIER"; + public static final String CLIENT_CERTIFICATE_KEY_TYPE = "KEY_TYPE"; + public static final String ENABLE_DEFAULT_KEY_MANAGER_REGISTRATION = API_KEY_VALIDATOR + "EnableDefaultKeyManagerRegistration"; public static final String ENABLE_KEY_MANAGER_RETRIVAL = API_KEY_VALIDATOR + diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java index 6a96343e6897..0b60c8c05891 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java @@ -126,7 +126,7 @@ public boolean updateClientCertificate(String certificate, String alias, String if (StringUtils.isNotEmpty(tier)) { clientCertificateDTO.setTierName(tier); } - if (StringUtils.isNotEmpty(tier)) { + if (StringUtils.isNotEmpty(keyType)) { clientCertificateDTO.setKeyType(keyType); } try (Connection connection = APIMgtDBUtil.getConnection()) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java index 213266db14a7..778b058c2424 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java @@ -166,6 +166,7 @@ public final class ImportExportConstants { public static final String ALIAS_JSON_KEY = "alias"; public static final String ENDPOINT_JSON_KEY = "endpoint"; + public static final String KEY_TYPE_JSON_KEY = "keyType"; public static final int REFER_REQUIRE_RE_SUBSCRIPTION_CHECK_ITEM = 1; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index 2139dec5d7ce..88bb780dfcd9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4631,7 +4631,7 @@ paths: description: API tier to which the certificate should be applied. keyType: type: string - description: Whether the endpoint is production or sandbox + description: Whether the key type is PRODUCTION or SANDBOX default: PRODUCTION required: true responses: @@ -4747,7 +4747,7 @@ paths: description: The tier of the certificate keyType: type: string - description: Whether the endpoint is production or sandbox + description: Whether the key type is PRODUCTION or SANDBOX default: PRODUCTION responses: 200: diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java index a89467883bb1..ca7e89fe370f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java @@ -184,9 +184,12 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenan if (clientCertificateDTOS != null) { clientCertificateObject = new HashMap<>(); for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + /* appending the values without using a data structure to store them separately to avoid conflicts + when reading from certificatesDetails string at MutualSSLAuthenticator */ clientCertificateObject.put(certificateMgtUtils .getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), - clientCertificateDTO.getTierName()); + clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) + .concat(clientCertificateDTO.getKeyType())); } } @@ -369,9 +372,13 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(APIProduct apiProduct if (clientCertificateDTOS != null) { clientCertificateObject = new HashMap<>(); for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { - clientCertificateObject.put(certificateMgtUtils - .getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), - clientCertificateDTO.getTierName()); + /* appending the values without using a data structure to store them separately to avoid conflicts + when reading from certificatesDetails string at MutualSSLAuthenticator */ + clientCertificateObject.put(certificateMgtUtils. + getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), + clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) + .concat(clientCertificateDTO.getKeyType())); + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java index 5fe30674411f..0b20f1bd49dc 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java @@ -991,6 +991,7 @@ private static void handleClientCertificates(JsonArray certificates, Identifier ClientCertificateDTO cert = new ClientCertificateDTO(); cert.setApiIdentifier(apiIdentifier); cert.setAlias(alias); + cert.setKeyType(certObject.get(ImportExportConstants.KEY_TYPE_JSON_KEY).getAsString()); cert.setTierName(certObject.get(ImportExportConstants.CERTIFICATE_TIER_NAME_PROPERTY).getAsString()); String certName = certObject.get(ImportExportConstants.CERTIFICATE_PATH_PROPERTY).getAsString(); cert.setCertificate(certName); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index 2139dec5d7ce..88bb780dfcd9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4631,7 +4631,7 @@ paths: description: API tier to which the certificate should be applied. keyType: type: string - description: Whether the endpoint is production or sandbox + description: Whether the key type is PRODUCTION or SANDBOX default: PRODUCTION required: true responses: @@ -4747,7 +4747,7 @@ paths: description: The tier of the certificate keyType: type: string - description: Whether the endpoint is production or sandbox + description: Whether the key type is PRODUCTION or SANDBOX default: PRODUCTION responses: 200: From a711cc28a618cabcc441f021f00b2766f6957f76 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Wed, 29 May 2024 22:01:31 +0530 Subject: [PATCH 03/10] Add new column to AM_API_CLIENT_CERTIFICATE in DB Scripts --- .../src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql | 1 + .../src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql | 1 + .../main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql | 1 + .../src/main/resources/sql/db2.sql | 1 + .../src/main/resources/sql/mssql.sql | 1 + .../src/main/resources/sql/oracle.sql | 1 + .../src/main/resources/sql/oracle_23c.sql | 1 + .../src/main/resources/sql/oracle_rac.sql | 1 + .../src/main/resources/sql/postgresql.sql | 1 + 9 files changed, 9 insertions(+) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql index 5f596fd05e30..d4ecf1e2cdd9 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql @@ -1890,6 +1890,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED INTEGER DEFAULT 0 NOT NULL, TIER_NAME VARCHAR2 (512), + KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql index 7fc03a02f84a..e9904030fcfb 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql @@ -1890,6 +1890,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED INTEGER DEFAULT 0 NOT NULL, TIER_NAME VARCHAR2 (512), + KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql index db674b207a8f..62f3f9a3db41 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql @@ -2226,6 +2226,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE VARBINARY(MAX) NOT NULL, REMOVED BIT NOT NULL DEFAULT 0, TIER_NAME VARCHAR(512), + KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql index f2d25cc9370d..e9eafa9c76c1 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql @@ -2769,6 +2769,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED SMALLINT NOT NULL DEFAULT 0, TIER_NAME VARCHAR (512), + KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql index 7ccf9e4bb3d2..aec49edb4cae 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql @@ -2237,6 +2237,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE VARBINARY(MAX) NOT NULL, REMOVED BIT NOT NULL DEFAULT 0, TIER_NAME VARCHAR(512), + KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql index d4e87d8f85ce..56341ff12206 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql @@ -3221,6 +3221,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED INTEGER DEFAULT 0 NOT NULL, TIER_NAME VARCHAR2 (512), + KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql index a04316907f90..a8ff64669dd2 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql @@ -3221,6 +3221,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED INTEGER DEFAULT 0 NOT NULL, TIER_NAME VARCHAR2 (512), + KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql index d91dc23057d2..e42e1dccc9d4 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql @@ -3195,6 +3195,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED INTEGER DEFAULT 0 NOT NULL, TIER_NAME VARCHAR2(512), + KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql index f3a6e5ab6804..4b68cf809a39 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql @@ -2327,6 +2327,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BYTEA NOT NULL, REMOVED BOOLEAN NOT NULL DEFAULT '0', TIER_NAME VARCHAR(512), + KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) From 4f9c5b163a0f1964c33b3f72caa70aa174d7732f Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Thu, 30 May 2024 10:15:31 +0530 Subject: [PATCH 04/10] Add unit tests, modify existing tests and bug fixes identified at manual tests --- .../security/APIAuthenticationHandler.java | 1 - .../authenticator/MutualSSLAuthenticator.java | 19 ++++++++------ .../CertificateManagerImplTest.java | 19 ++++++++------ .../impl/dao/test/CertificateMgtDaoTest.java | 25 ++++++++++++++++--- .../src/test/resources/dbscripts/h2.sql | 1 + .../v1/common/mappings/ImportUtils.java | 2 +- .../src/main/resources/sql/h2.sql | 1 + .../src/main/resources/sql/mysql.sql | 1 + .../src/main/resources/sql/mysql_cluster.sql | 1 + .../src/main/resources/sql/h2.sql | 1 + 10 files changed, 52 insertions(+), 19 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java index 95b5ba332b05..4676a5b6b075 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java @@ -544,7 +544,6 @@ private void handleNoAuthentication(MessageContext messageContext){ authContext.setStopOnQuotaReach(true); //Requests are throttled by the ApiKey that is set here. In an unauthenticated scenario, we will use the client's IP address for throttling. authContext.setApiKey(clientIP); - //TODO: verify the key type authContext.setKeyType(APIConstants.API_KEY_TYPE_PRODUCTION); //This name is hardcoded as anonymous because there is no associated user token authContext.setUsername(APIConstants.END_USER_ANONYMOUS); diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java index 17603224f53a..3a5a9a96016b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java @@ -71,10 +71,10 @@ public class MutualSSLAuthenticator implements Authenticator { public MutualSSLAuthenticator(String apiLevelPolicy, boolean isMandatory, String certificateDetails) { this.apiLevelPolicy = apiLevelPolicy; certificates = new HashMap<>(); - HashMap certificateData = new HashMap<>(); if (StringUtils.isNotEmpty(certificateDetails)) { String[] certificateParts = certificateDetails.substring(1, certificateDetails.length() - 1).split(","); for (String certificatePart : certificateParts) { + HashMap certificateData = new HashMap<>(); int tierDivisionIndex = certificatePart.lastIndexOf("="); if (tierDivisionIndex > 0) { String uniqueIdentifier = certificatePart.substring(0, tierDivisionIndex).trim(); @@ -181,6 +181,12 @@ private void setAuthContext(MessageContext messageContext, Certificate certifica String subjectDN = x509Certificate.getSubjectDN().getName(); String uniqueIdentifier = (x509Certificate.getSerialNumber() + "_" + x509Certificate.getSubjectDN()).replaceAll(",", "#").replaceAll("\"", "'").trim(); + /* Since there can be previously deleted certificates persisted in the trust store that matches with the + certificate object but not in the certificates list for the particular API. + */ + if (certificates.get(uniqueIdentifier) == null ) { + handleCertificateNotAssociatedToAPIFailure(messageContext); + } String tier = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_TIER); String keyType = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); if (StringUtils.isEmpty(tier)) { @@ -236,13 +242,10 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi } if (StringUtils.isEmpty(tier) || StringUtils.isEmpty(keyType)) { subjectDNIdentifiers = getUniqueIdentifierFromCompleteCertificateChain(x509Certificates, subjectDNIdentifiers); - } - if (StringUtils.isEmpty(tier)) { tier = getTierFromCompleteCertificateChain(subjectDNIdentifiers); - } - if (StringUtils.isEmpty(keyType)) { keyType = getKeyTypeFromCompleteCertificateChain(subjectDNIdentifiers); } + if (StringUtils.isEmpty(tier) || StringUtils.isEmpty(keyType)) { handleCertificateNotAssociatedToAPIFailure(messageContext); } @@ -292,7 +295,8 @@ private String getTierFromCompleteCertificateChain(List uniqueIdentifier String tier = null; for (String uniqueIdentifier : uniqueIdentifiers) { - tier = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_TIER); + tier = certificates.get(uniqueIdentifier) == null ? null : + certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_TIER); if (StringUtils.isNotEmpty(tier)) { break; } @@ -311,7 +315,8 @@ private String getKeyTypeFromCompleteCertificateChain(List uniqueIdentif String keyType = null; for (String uniqueIdentifier : uniqueIdentifiers) { - keyType = certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); + keyType = certificates.get(uniqueIdentifier) == null ? null : + certificates.get(uniqueIdentifier).get(APIConstants.CLIENT_CERTIFICATE_KEY_TYPE); if (StringUtils.isNotEmpty(keyType)) { break; } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java index 5c7ef946fed1..0e344573486d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java @@ -30,6 +30,7 @@ import org.wso2.carbon.apimgt.api.dto.CertificateInformationDTO; import org.wso2.carbon.apimgt.api.dto.CertificateMetadataDTO; import org.wso2.carbon.apimgt.api.dto.ClientCertificateDTO; +import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.TestUtils; import org.wso2.carbon.apimgt.impl.certificatemgt.exceptions.CertificateAliasExistsException; import org.wso2.carbon.apimgt.impl.certificatemgt.exceptions.CertificateManagementException; @@ -421,7 +422,8 @@ public void testAddClientCertificate() throws CertificateManagementException { .stub(PowerMockito.method(CertificateMgtUtils.class, "validateCertificate")) .toReturn(ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE); ResponseCode responseCode = certificateManager - .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, MultitenantConstants.SUPER_TENANT_ID, "org1"); + .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, + APIConstants.API_KEY_TYPE_PRODUCTION, MultitenantConstants.SUPER_TENANT_ID, "org1"); Assert.assertEquals("Response code was wrong while trying add a client certificate with an existing alias", ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode(), responseCode.getResponseCode()); PowerMockito @@ -429,15 +431,17 @@ public void testAddClientCertificate() throws CertificateManagementException { .toReturn(ResponseCode.SUCCESS); Mockito.when(certificateMgtDAO.checkWhetherAliasExist(ALIAS, TENANT_ID)).thenReturn(true); responseCode = certificateManager - .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, MultitenantConstants.SUPER_TENANT_ID, "org1"); + .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, + APIConstants.API_KEY_TYPE_PRODUCTION, MultitenantConstants.SUPER_TENANT_ID, "org1"); Assert.assertEquals("Response code was wrong while trying add a client certificate with an existing alias", ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode(), responseCode.getResponseCode()); Mockito.when(certificateMgtDAO.checkWhetherAliasExist(ALIAS, TENANT_ID)).thenReturn(false); Mockito.when(certificateMgtDAO .addClientCertificate(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.anyString(), - Mockito.anyInt(), Mockito.anyString())).thenReturn(true); + Mockito.anyString(), Mockito.anyInt(), Mockito.anyString())).thenReturn(true); responseCode = certificateManager - .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, MultitenantConstants.SUPER_TENANT_ID, "org1"); + .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, + APIConstants.API_KEY_TYPE_PRODUCTION, MultitenantConstants.SUPER_TENANT_ID, "org1"); Assert.assertEquals("Response code was wrong while trying add a client certificate", ResponseCode.SUCCESS.getResponseCode(), responseCode.getResponseCode()); } @@ -452,8 +456,8 @@ public void testUpdateClientCertificate() throws APIManagementException { .stub(PowerMockito.method(CertificateMgtUtils.class, "validateCertificate")) .toReturn(ResponseCode.CERTIFICATE_EXPIRED); ResponseCode responseCode = certificateManager - .updateClientCertificate(BASE64_ENCODED_CERT, ALIAS, null, MultitenantConstants.SUPER_TENANT_ID, - organization); + .updateClientCertificate(BASE64_ENCODED_CERT, ALIAS, null, + APIConstants.API_KEY_TYPE_PRODUCTION, MultitenantConstants.SUPER_TENANT_ID, organization); Assert.assertEquals("Response code was wrong while trying add a expired client certificate", ResponseCode.CERTIFICATE_EXPIRED.getResponseCode(), responseCode.getResponseCode()); PowerMockito @@ -461,7 +465,8 @@ public void testUpdateClientCertificate() throws APIManagementException { .toReturn(ResponseCode.SUCCESS); PowerMockito.stub(PowerMockito.method(CertificateMgtDAO.class, "updateClientCertificate")).toReturn(false); responseCode = certificateManager - .updateClientCertificate(BASE64_ENCODED_CERT, ALIAS, null, MultitenantConstants.SUPER_TENANT_ID, + .updateClientCertificate(BASE64_ENCODED_CERT, ALIAS, null, APIConstants.API_KEY_TYPE_PRODUCTION, + MultitenantConstants.SUPER_TENANT_ID, organization); Assert.assertEquals("Response code was wrong, for a failure in update", ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode(), responseCode.getResponseCode()); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java index 786e9c43adec..9855e4bceeeb 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java @@ -31,6 +31,7 @@ import org.wso2.carbon.apimgt.api.dto.CertificateMetadataDTO; import org.wso2.carbon.apimgt.api.dto.ClientCertificateDTO; import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.APIManagerConfigurationServiceImpl; import org.wso2.carbon.apimgt.impl.certificatemgt.exceptions.CertificateAliasExistsException; @@ -208,7 +209,21 @@ public void testAddClientCertificate() throws CertificateManagementException { @Test public void testUpdateClientCertificateOfNonExistingAlias() throws CertificateManagementException { Assert.assertFalse("Update of client certificate for a non existing alias succeeded", - certificateMgtDAO.updateClientCertificate(certificate, "test1", "test", TENANT_ID, "org1")); + certificateMgtDAO.updateClientCertificate(certificate, "test1", "test", + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID, "org1")); + } + + /** + * This method tests the behaviour of updateClientCertificate method when trying to update keyType of an + * existing client certificate entry. + * + * @throws CertificateManagementException Certificate Management Exception. + */ + @Test + public void testUpdateKeyTypeOfExistingAlias() throws CertificateManagementException { + Assert.assertFalse("Update of key type for an existing client certificate entry succeeded", + certificateMgtDAO.updateClientCertificate(certificate, "test1", "test", + APIConstants.API_KEY_TYPE_SANDBOX, TENANT_ID, "org1")); } /** @@ -221,7 +236,8 @@ public void testUpdateClientCertificateOfExistingAlias() throws CertificateManag try { addClientCertificate(); Assert.assertTrue("Update of client certificate for an existing alias failed", - certificateMgtDAO.updateClientCertificate(null, "test", "test", TENANT_ID, "org1")); + certificateMgtDAO.updateClientCertificate(null, "test", "test", + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID, "org1")); } finally { deleteClientCertificate(); } @@ -293,6 +309,8 @@ public void testGetClientCertificates() throws CertificateManagementException { clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test", apiIdentifier, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); + Assert.assertNotNull("The key type of a client certificate cannot be null", + clientCertificateDTOS.get(0).getKeyType()); clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, null, apiIdentifier, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); @@ -324,7 +342,8 @@ public void testGetDeletedClientCertificates() throws CertificateManagementExcep * @throws CertificateManagementException Certificate Management Exception. */ private boolean addClientCertificate() throws CertificateManagementException { - return certificateMgtDAO.addClientCertificate(certificate, apiIdentifier, "test", "Gold", TENANT_ID, "org1"); + return certificateMgtDAO.addClientCertificate(certificate, apiIdentifier, "test", "Gold", + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID, "org1"); } /** diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql index 1c6cf07d5aae..6ba0ae41c324 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql @@ -1715,6 +1715,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `CERTIFICATE` BLOB NOT NULL, `REMOVED` BOOLEAN NOT NULL DEFAULT 0, `TIER_NAME` VARCHAR (512), + `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY (`ALIAS`,`TENANT_ID`, `REMOVED`) ); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java index b3d30ed6e1f8..6c19ea325cfe 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java @@ -2263,7 +2263,7 @@ private static void addClientCertificates(String pathToArchive, APIProvider apiP for (ClientCertificateDTO certDTO : certificateMetadataDTOS) { if (ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode() == (apiProvider.addClientCertificate( APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName()), apiTypeWrapper, - certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(),certDTO.getKeyType(), + certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(), certDTO.getKeyType(), organization)) && isOverwrite) { apiProvider.updateClientCertificate(certDTO.getCertificate(), certDTO.getAlias(), apiTypeWrapper, certDTO.getTierName(), certDTO.getKeyType(), tenantId, organization); diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql index ec4d4d9cb886..98402e27a516 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql @@ -2014,6 +2014,7 @@ CREATE TABLE IF NOT EXISTS AM_API_CLIENT_CERTIFICATE ( CERTIFICATE BLOB NOT NULL, REMOVED BOOLEAN NOT NULL DEFAULT 0, TIER_NAME VARCHAR (512), + KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY (ALIAS,TENANT_ID, REMOVED, REVISION_UUID) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql index 9638f78a38e5..931dd31cacbf 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql @@ -1961,6 +1961,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `CERTIFICATE` BLOB NOT NULL, `REMOVED` BOOLEAN NOT NULL DEFAULT 0, `TIER_NAME` VARCHAR (512), + `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', `REVISION_UUID` VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY (`ALIAS`, `TENANT_ID`, `REMOVED`, `REVISION_UUID`) diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql index 64f9a447abe1..fcf364b58b4c 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql @@ -2141,6 +2141,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `CERTIFICATE` BLOB NOT NULL, `REMOVED` BOOLEAN NOT NULL DEFAULT 0, `TIER_NAME` VARCHAR (512), + `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', `REVISION_UUID` VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID), PRIMARY KEY (`ALIAS`, `TENANT_ID`, `REMOVED`, `REVISION_UUID`) diff --git a/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql b/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql index ec96d9913a98..ea536e316628 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql @@ -1701,6 +1701,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `CERTIFICATE` BLOB NOT NULL, `REMOVED` BOOLEAN NOT NULL DEFAULT 0, `TIER_NAME` VARCHAR (512), + `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY (`ALIAS`,`TENANT_ID`, `REMOVED`) ); From 42ab173744d5b925a2b9648e7af0c0c97649bd37 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Mon, 1 Jul 2024 02:22:33 +0530 Subject: [PATCH 05/10] Modify the design introducing new REST API and deprecate the existing --- .../apimgt/rest/api/publisher/v1/ApisApi.java | 127 ++++++- .../rest/api/publisher/v1/ApisApiService.java | 8 +- .../publisher/v1/impl/ApisApiServiceImpl.java | 50 ++- .../src/main/resources/publisher-api.yaml | 347 +++++++++++++++++- 4 files changed, 519 insertions(+), 13 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index fff5a1bc18b3..0b7e3574d60c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -95,8 +95,28 @@ public class ApisApi { @ApiResponse(code = 200, message = "OK. The Certificate added successfully. ", response = ClientCertMetadataDTO.class), @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) - public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate") InputStream certificateInputStream, @Multipart(value = "certificate" ) Attachment certificateDetail, @Multipart(value = "alias") String alias, @Multipart(value = "tier") String tier, @Multipart(value = "keyType", required = false) String keyType) throws APIManagementException{ - return delegate.addAPIClientCertificate(apiId, certificateInputStream, certificateDetail, alias, tier, keyType, securityContext); + public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate") InputStream certificateInputStream, @Multipart(value = "certificate" ) Attachment certificateDetail, @Multipart(value = "alias") String alias, @Multipart(value = "tier") String tier) throws APIManagementException{ + return delegate.addAPIClientCertificate(apiId, certificateInputStream, certificateDetail, alias, tier, securityContext); + } + + @POST + @Path("/{apiId}/client-certificates/{keyType}") + @Consumes({ "multipart/form-data" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Upload a New Certificate of the given key type", notes = "This operation can be used to upload a new certificate for an endpoint of the given type. ", response = ClientCertMetadataDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_create", description = "Create API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_add", description = "Add client certificates"), + @AuthorizationScope(scope = "apim:client_certificates_manage", description = "View, create, update and remove client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. The Certificate added successfully. ", response = ClientCertMetadataDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response addAPIClientCertificateOfGivenKeyType(@ApiParam(value = "Key type for the certificate",required=true) @PathParam("keyType") String keyType, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate") InputStream certificateInputStream, @Multipart(value = "certificate" ) Attachment certificateDetail, @Multipart(value = "alias") String alias, @Multipart(value = "tier") String tier) throws APIManagementException{ + return delegate.addAPIClientCertificateOfGivenKeyType(keyType, apiId, certificateInputStream, certificateDetail, alias, tier, securityContext); } @POST @@ -398,6 +418,26 @@ public Response deleteAPIClientCertificateByAlias(@ApiParam(value = "The alias o return delegate.deleteAPIClientCertificateByAlias(alias, apiId, securityContext); } + @DELETE + @Path("/{apiId}/client-certificates/{keyType}/{alias}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Delete a Certificate of a Given Key Type", notes = "This operation can be used to delete an uploaded certificate of a given key type. ", response = Void.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_create", description = "Create API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_update", description = "Update and delete client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. The Certificate deleted successfully. ", response = Void.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response deleteAPIClientCertificateByKeyTypeAndAlias(@ApiParam(value = "Key type for the certificate",required=true) @PathParam("keyType") String keyType, @ApiParam(value = "The alias of the certificate that should be deleted. ",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId) throws APIManagementException{ + return delegate.deleteAPIClientCertificateByKeyTypeAndAlias(keyType, alias, apiId, securityContext); + } + @DELETE @Path("/{apiId}/documents/{documentId}") @@ -658,6 +698,27 @@ public Response getAPIClientCertificateByAlias(@ApiParam(value = "",required=tru return delegate.getAPIClientCertificateByAlias(alias, apiId, securityContext); } + @GET + @Path("/{apiId}/client-certificates/{keyType}/{alias}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Get the Certificate Information of a Given Key Type", notes = "This operation can be used to get the information about a certificate of a given key type. ", response = CertificateInfoDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_view", description = "View API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_view", description = "View client certificates"), + @AuthorizationScope(scope = "apim:client_certificates_manage", description = "View, create, update and remove client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. ", response = CertificateInfoDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response getAPIClientCertificateByKeyTypeAndAlias(@ApiParam(value = "Key type for the certificate",required=true) @PathParam("keyType") String keyType, @ApiParam(value = "",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId) throws APIManagementException{ + return delegate.getAPIClientCertificateByKeyTypeAndAlias(keyType, alias, apiId, securityContext); + } + @GET @Path("/{apiId}/client-certificates/{alias}/content") @@ -679,6 +740,27 @@ public Response getAPIClientCertificateContentByAlias(@ApiParam(value = "**API I return delegate.getAPIClientCertificateContentByAlias(apiId, alias, securityContext); } + @GET + @Path("/{apiId}/client-certificates/{keyType}/{alias}/content") + + @Produces({ "application/json" }) + @ApiOperation(value = "Download a Certificate of Given Key Type", notes = "This operation can be used to download a certificate which matches the given alias and key type. ", response = Void.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_view", description = "View API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_view", description = "View client certificates"), + @AuthorizationScope(scope = "apim:client_certificates_manage", description = "View, create, update and remove client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. ", response = Void.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response getAPIClientCertificateContentByKeyTypeAndAlias(@ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "",required=true) @PathParam("alias") String alias, @ApiParam(value = "The key type of the certificate that should be deleted. ",required=true) @PathParam("keyType") String keyType) throws APIManagementException{ + return delegate.getAPIClientCertificateContentByKeyTypeAndAlias(apiId, alias, keyType, securityContext); + } + @GET @Path("/{apiId}/client-certificates") @@ -699,6 +781,26 @@ public Response getAPIClientCertificates(@ApiParam(value = "**API ID** consistin return delegate.getAPIClientCertificates(apiId, limit, offset, alias, securityContext); } + @GET + @Path("/{apiId}/client-certificates/{keyType}") + + @Produces({ "application/json" }) + @ApiOperation(value = "Retrieve/ Search Uploaded Client Certificates of a given key type", notes = "This operation can be used to retrieve and search the uploaded client certificates of a given key type. ", response = ClientCertificatesDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_view", description = "View API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_view", description = "View client certificates"), + @AuthorizationScope(scope = "apim:client_certificates_manage", description = "View, create, update and remove client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. Successful response with the list of matching certificate information in the body. ", response = ClientCertificatesDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response getAPIClientCertificatesByKeyType(@ApiParam(value = "Key type for the certificate",required=true) @PathParam("keyType") String keyType, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @ApiParam(value = "Maximum size of resource array to return. ", defaultValue="25") @DefaultValue("25") @QueryParam("limit") Integer limit, @ApiParam(value = "Starting point within the complete list of items qualified. ", defaultValue="0") @DefaultValue("0") @QueryParam("offset") Integer offset, @ApiParam(value = "Alias for the client certificate") @QueryParam("alias") String alias) throws APIManagementException{ + return delegate.getAPIClientCertificatesByKeyType(keyType, apiId, limit, offset, alias, securityContext); + } + @GET @Path("/{apiId}/documents/{documentId}") @@ -1551,6 +1653,27 @@ public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam( return delegate.updateAPIClientCertificateByAlias(alias, apiId, certificateInputStream, certificateDetail, tier, keyType, securityContext); } + @PUT + @Path("/{apiId}/client-certificates/{keyType}/{alias}") + @Consumes({ "multipart/form-data" }) + @Produces({ "application/json" }) + @ApiOperation(value = "Update a Certificate of a Given Key Type", notes = "This operation can be used to update an uploaded certificate of a given key type. ", response = ClientCertMetadataDTO.class, authorizations = { + @Authorization(value = "OAuth2Security", scopes = { + @AuthorizationScope(scope = "apim:api_create", description = "Create API"), + @AuthorizationScope(scope = "apim:api_manage", description = "Manage all API related operations"), + @AuthorizationScope(scope = "apim:client_certificates_update", description = "Update and delete client certificates"), + @AuthorizationScope(scope = "apim:client_certificates_manage", description = "View, create, update and remove client certificates") + }) + }, tags={ "Client Certificates", }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. The Certificate updated successfully. ", response = ClientCertMetadataDTO.class), + @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), + @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), + @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) + public Response updateAPIClientCertificateByKeyTypeAndAlias(@ApiParam(value = "Key type for the certificate",required=true) @PathParam("keyType") String keyType, @Size(min=1,max=30)@ApiParam(value = "Alias for the certificate",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate", required = false) InputStream certificateInputStream, @Multipart(value = "certificate" , required = false) Attachment certificateDetail, @Multipart(value = "tier", required = false) String tier) throws APIManagementException{ + return delegate.updateAPIClientCertificateByKeyTypeAndAlias(keyType, alias, apiId, certificateInputStream, certificateDetail, tier, securityContext); + } + @PUT @Path("/{apiId}/deployments/{deploymentId}") @Consumes({ "application/json" }) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java index 1b43f8b5b327..ebf276ef28e4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java @@ -64,7 +64,8 @@ public interface ApisApiService { - public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, String keyType, MessageContext messageContext) throws APIManagementException; + public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, MessageContext messageContext) throws APIManagementException; + public Response addAPIClientCertificateOfGivenKeyType(String keyType, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, MessageContext messageContext) throws APIManagementException; public Response addAPIDocument(String apiId, DocumentDTO documentDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response addAPIDocumentContent(String apiId, String documentId, String ifMatch, InputStream fileInputStream, Attachment fileDetail, String inlineContent, MessageContext messageContext) throws APIManagementException; public Response addAPIMonetization(String apiId, APIMonetizationInfoDTO apIMonetizationInfoDTO, MessageContext messageContext) throws APIManagementException; @@ -80,6 +81,7 @@ public interface ApisApiService { public Response createNewAPIVersion(String newVersion, String apiId, Boolean defaultVersion, String serviceVersion, MessageContext messageContext) throws APIManagementException; public Response deleteAPI(String apiId, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response deleteAPIClientCertificateByAlias(String alias, String apiId, MessageContext messageContext) throws APIManagementException; + public Response deleteAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, MessageContext messageContext) throws APIManagementException; public Response deleteAPIDocument(String apiId, String documentId, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response deleteAPILifecycleStatePendingTasks(String apiId, MessageContext messageContext) throws APIManagementException; public Response deleteAPIRevision(String apiId, String revisionId, MessageContext messageContext) throws APIManagementException; @@ -93,8 +95,11 @@ public interface ApisApiService { public Response generateMockScripts(String apiId, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; public Response getAPI(String apiId, String xWSO2Tenant, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; public Response getAPIClientCertificateByAlias(String alias, String apiId, MessageContext messageContext) throws APIManagementException; + public Response getAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, MessageContext messageContext) throws APIManagementException; public Response getAPIClientCertificateContentByAlias(String apiId, String alias, MessageContext messageContext) throws APIManagementException; + public Response getAPIClientCertificateContentByKeyTypeAndAlias(String apiId, String alias, String keyType, MessageContext messageContext) throws APIManagementException; public Response getAPIClientCertificates(String apiId, Integer limit, Integer offset, String alias, MessageContext messageContext) throws APIManagementException; + public Response getAPIClientCertificatesByKeyType(String keyType, String apiId, Integer limit, Integer offset, String alias, MessageContext messageContext) throws APIManagementException; public Response getAPIDocumentByDocumentId(String apiId, String documentId, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; public Response getAPIDocumentContentByDocumentId(String apiId, String documentId, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; public Response getAPIDocuments(String apiId, Integer limit, Integer offset, String ifNoneMatch, MessageContext messageContext) throws APIManagementException; @@ -139,6 +144,7 @@ public interface ApisApiService { public Response undeployAPIRevision(String apiId, String revisionId, String revisionNumber, Boolean allEnvironments, List apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPI(String apiId, APIDTO APIDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, String keyType, MessageContext messageContext) throws APIManagementException; + public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) throws APIManagementException; public Response updateAPIDeployment(String apiId, String deploymentId, APIRevisionDeploymentDTO apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPIDocument(String apiId, String documentId, DocumentDTO documentDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; public Response updateAPIGraphQLSchema(String apiId, String schemaDefinition, String ifMatch, MessageContext messageContext) throws APIManagementException; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java index fdff880b467c..078f284e8d12 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java @@ -865,6 +865,14 @@ public Response getAuditReportOfAPI(String apiId, String accept, MessageContext @Override public Response getAPIClientCertificateContentByAlias(String apiId, String alias, MessageContext messageContext) { + return getAPIClientCertificateContentByKeyTypeAndAlias(apiId, alias, APIConstants.API_KEY_TYPE_PRODUCTION, + messageContext); + } + + @Override + public Response getAPIClientCertificateContentByKeyTypeAndAlias(String apiId, String alias, String keyType, + MessageContext messageContext) { + String organization = null; String certFileName = alias + ".crt"; try { @@ -893,6 +901,13 @@ public Response getAPIClientCertificateContentByAlias(String apiId, String alias @Override public Response deleteAPIClientCertificateByAlias(String alias, String apiId, MessageContext messageContext) { + return deleteAPIClientCertificateByKeyTypeAndAlias(APIConstants.API_KEY_TYPE_PRODUCTION, alias, apiId, + messageContext); + } + + @Override + public Response deleteAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, + MessageContext messageContext) { String organization = null; try { organization = RestApiUtil.getValidatedOrganization(messageContext); @@ -935,6 +950,13 @@ public Response deleteAPIClientCertificateByAlias(String alias, String apiId, @Override public Response getAPIClientCertificateByAlias(String alias, String apiId, MessageContext messageContext) { + return getAPIClientCertificateByKeyTypeAndAlias(APIConstants.API_KEY_TYPE_PRODUCTION, alias, apiId, + messageContext); + } + + @Override + public Response getAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, + MessageContext messageContext) { String organization = null; CertificateMgtUtils certificateMgtUtils = CertificateMgtUtils.getInstance(); try { @@ -965,6 +987,13 @@ public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, String keyType, MessageContext messageContext) { + return updateAPIClientCertificateByKeyTypeAndAlias(APIConstants.API_KEY_TYPE_PRODUCTION, alias, apiId, + certificateInputStream, certificateDetail, tier, messageContext); + } + + @Override + public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, + InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) { try { //validate if api exists CommonUtils.validateAPIExistence(apiId); @@ -1037,6 +1066,13 @@ public Response updateAPIClientCertificateByAlias(String alias, String apiId, @Override public Response getAPIClientCertificates(String apiId, Integer limit, Integer offset, String alias, MessageContext messageContext) { + return getAPIClientCertificatesByKeyType(APIConstants.API_KEY_TYPE_PRODUCTION, apiId, limit,offset, alias, + messageContext); + } + + @Override + public Response getAPIClientCertificatesByKeyType(String keyType, String apiId, Integer limit, Integer offset, + String alias, MessageContext messageContext) { limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; List certificates = new ArrayList<>(); @@ -1071,9 +1107,17 @@ public Response getAPIClientCertificates(String apiId, Integer limit, Integer of } @Override - public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, - Attachment certificateDetail, String alias, String tier, - String keyType, MessageContext messageContext) { + public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, + Attachment certificateDetail, String alias, String tier, + MessageContext messageContext) { + return addAPIClientCertificateOfGivenKeyType(APIConstants.API_KEY_TYPE_PRODUCTION, apiId, + certificateInputStream, certificateDetail, alias, tier, messageContext); + } + + @Override + public Response addAPIClientCertificateOfGivenKeyType(String keyType, String apiId, + InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, + MessageContext messageContext) { try { APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); ContentDisposition contentDisposition = certificateDetail.getContentDisposition(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index 88bb780dfcd9..2cd878390958 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4559,6 +4559,7 @@ paths: tags: - Client Certificates summary: Retrieve/ Search Uploaded Client Certificates + deprecated: true description: | This operation can be used to retrieve and search the uploaded client certificates. parameters: @@ -4604,6 +4605,7 @@ paths: tags: - Client Certificates summary: Upload a New Certificate + deprecated: true description: | This operation can be used to upload a new certificate for an endpoint. parameters: @@ -4629,10 +4631,6 @@ paths: tier: type: string description: API tier to which the certificate should be applied. - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION required: true responses: 200: @@ -4671,8 +4669,128 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate + /apis/{apiId}/client-certificates/{keyType}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: + tags: + - Client Certificates + summary: Retrieve/ Search Uploaded Client Certificates of a given key type + description: | + This operation can be used to retrieve and search the uploaded client certificates of a given key type. + parameters: + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' + - name: alias + in: query + description: Alias for the client certificate + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. Successful response with the list of matching certificate information in the body. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertificates' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates?alias=wso2carbon"' + operationId: getAPIClientCertificatesByKeyType + post: + tags: + - Client Certificates + summary: Upload a New Certificate of the given key type + description: | + This operation can be used to upload a new certificate for an endpoint of the given type. + parameters: + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + required: + - alias + - certificate + - tier + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + alias: + maxLength: 30 + minLength: 1 + type: string + description: Alias for the certificate + tier: + type: string + description: API tier to which the certificate should be applied. + required: true + responses: + 200: + description: | + OK. + The Certificate added successfully. + headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_add + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' + operationId: addAPIClientCertificateOfGivenKeyType + /apis/{apiId}/client-certificates/{alias}: get: + deprecated: true tags: - Client Certificates summary: Get the Certificate Information @@ -4718,6 +4836,7 @@ paths: operationId: getAPIClientCertificateByAlias put: + deprecated: true tags: - Client Certificates summary: Update a Certificate @@ -4789,6 +4908,7 @@ paths: operationId: updateAPIClientCertificateByAlias delete: + deprecated: true tags: - Client Certificates summary: Delete a Certificate @@ -4831,9 +4951,174 @@ paths: source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByAlias + /apis/{apiId}/client-certificates/{keyType}/{alias}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: + tags: + - Client Certificates + summary: Get the Certificate Information of a Given Key Type + description: | + This operation can be used to get the information about a certificate of a given key type. + parameters: + - name: alias + in: path + required: true + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/CertificateInfo' + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: getAPIClientCertificateByKeyTypeAndAlias + + put: + tags: + - Client Certificates + summary: Update a Certificate of a Given Key Type + description: | + This operation can be used to update an uploaded certificate of a given key type. + parameters: + - name: alias + in: path + description: Alias for the certificate + required: true + schema: + maxLength: 30 + minLength: 1 + type: string + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + tier: + type: string + description: The tier of the certificate + responses: + 200: + description: | + OK. + The Certificate updated successfully. + headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_update + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: updateAPIClientCertificateByKeyTypeAndAlias + + delete: + tags: + - Client Certificates + summary: Delete a Certificate of a Given Key Type + description: | + This operation can be used to delete an uploaded certificate of a given key type. + parameters: + - name: alias + in: path + description: | + The alias of the certificate that should be deleted. + required: true + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. + The Certificate deleted successfully. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: { } + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_update + x-code-samples: + - lang: Curl + source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: deleteAPIClientCertificateByKeyTypeAndAlias + /apis/{apiId}/client-certificates/{alias}/content: get: + deprecated: true tags: - Client Certificates summary: Download a Certificate @@ -4875,6 +5160,57 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByAlias + /apis/{apiId}/client-certificates/{keyType}/{alias}/content: + get: + tags: + - Client Certificates + summary: Download a Certificate of Given Key Type + description: | + This operation can be used to download a certificate which matches the given alias and key type. + parameters: + - $ref: '#/components/parameters/apiId' + - name: alias + in: path + required: true + schema: + type: string + - name: keyType + in: path + description: | + The key type of the certificate that should be deleted. + required: true + schema: + type: string + responses: + 200: + description: | + OK. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: {} + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + operationId: getAPIClientCertificateContentByKeyTypeAndAlias + + ###################################################### # The "Certificate Management" resource APIs ###################################################### @@ -11339,9 +11675,6 @@ components: tier: type: string example: Gold - keyType: - type: string - example: PRODUCTION description: Meta data of certificate LifecycleState: title: Lifecycle State From 9efc7e9bb30f838064dc6da9e93a42f8ce47dc3a Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Mon, 1 Jul 2024 18:44:18 +0530 Subject: [PATCH 06/10] Add database and DAO level changes --- .../wso2/carbon/apimgt/api/APIProvider.java | 13 +- .../carbon/apimgt/api/ExceptionCodes.java | 2 +- .../apimgt/api/dto/ClientCertificateDTO.java | 18 - .../carbon/apimgt/impl/APIProviderImpl.java | 25 +- .../apimgt/impl/UserAwareAPIProvider.java | 10 +- .../certificatemgt/CertificateManager.java | 8 +- .../CertificateManagerImpl.java | 19 +- .../carbon/apimgt/impl/dao/ApiMgtDAO.java | 246 +++++++------ .../apimgt/impl/dao/CertificateMgtDAO.java | 86 +++-- .../impl/dao/constants/SQLConstants.java | 59 +-- .../CertificateManagerImplTest.java | 20 +- .../impl/dao/test/CertificateMgtDaoTest.java | 44 ++- .../swagger.json | 4 +- .../rest/api/common/RestApiConstants.java | 5 +- .../src/main/resources/admin-api.yaml | 12 + .../src/main/resources/publisher-api.yaml | 347 +++++++++++++++++- .../v1/dto/ClientCertMetadataDTO.java | 24 +- .../mappings/CertificateRestApiUtils.java | 43 ++- .../v1/common/mappings/ExportUtils.java | 6 +- .../publisher/v1/impl/ApisApiServiceImpl.java | 81 ++-- .../multi-dc/OGG/oracle/apimgt/tables.sql | 2 +- .../multi-dc/OGG/oracle/apimgt/tables_23c.sql | 2 +- .../SQLServer/mssql/apimgt/tables.sql | 2 +- .../src/main/resources/sql/db2.sql | 2 +- .../src/main/resources/sql/mssql.sql | 2 +- .../src/main/resources/sql/oracle.sql | 2 +- .../src/main/resources/sql/oracle_23c.sql | 2 +- .../src/main/resources/sql/oracle_rac.sql | 2 +- .../src/main/resources/sql/postgresql.sql | 2 +- 29 files changed, 751 insertions(+), 339 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java index 74097d691639..796ae0126323 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java @@ -836,7 +836,7 @@ int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String * 4 : If certificate is not found in the trust store. * @throws APIManagementException API Management Exception. */ - int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias) + int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias, String keyTye) throws APIManagementException; /** @@ -883,8 +883,8 @@ List searchCertificates(int tenantId, String alias, Stri * @return list of client certificates that match search criteria. * @throws APIManagementException API Management Exception. */ - List searchClientCertificates(int tenantId, String alias, APIIdentifier apiIdentifier, - String organization) throws APIManagementException; + List searchClientCertificates(int tenantId, String alias, String keyType, + APIIdentifier apiIdentifier, String organization) throws APIManagementException; /** * Method to search the client certificates for the provided tenant id, alias and api product identifier. @@ -896,7 +896,7 @@ List searchClientCertificates(int tenantId, String alias, * @return list of client certificates that match search criteria. * @throws APIManagementException API Management Exception. */ - List searchClientCertificates(int tenantId, String alias, + List searchClientCertificates(int tenantId, String alias, String keyType, APIProductIdentifier apiProductIdentifier, String organization) throws APIManagementException; /** @@ -914,7 +914,7 @@ List searchClientCertificates(int tenantId, String alias, * @return count of client certificates that exists for a particular tenant. * @throws APIManagementException API Management Exception. */ - int getClientCertificateCount(int tenantId) throws APIManagementException; + int getClientCertificateCount(int tenantId, String keyType) throws APIManagementException; /** * Method to check whether an certificate for the given alias is present in the trust store and the database. @@ -930,13 +930,14 @@ List searchClientCertificates(int tenantId, String alias, * be modified by current user. * * @param alias : Relevant alias. + * @param keyType : Key type of the certificate * @param apiTypeWrapper : The identifier of the api. * @param organization : Organization * @return Instance of {@link ClientCertificateDTO} if the client certificate is present and * modifiable by current user. * @throws APIManagementException API Management Exception. */ - ClientCertificateDTO getClientCertificate(String alias, ApiTypeWrapper apiTypeWrapper, + ClientCertificateDTO getClientCertificate(String alias, String keyType, ApiTypeWrapper apiTypeWrapper, String organization) throws APIManagementException; diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java index 6bd53129acaa..70c79fe280b6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/ExceptionCodes.java @@ -476,7 +476,7 @@ public enum ExceptionCodes implements ErrorHandler { "{apiName}#{apiVersion}#{tenantDomain}"), INVALID_API_NAME(900854, "Invalid API Name",400 ,"Invalid API Name"), ALIAS_CANNOT_BE_EMPTY(900855, "The alias cannot be empty", 400, "The alias cannot be empty"), - + KEY_TYPE_CANNOT_BE_EMPTY(900856, "The key type cannot be empty", 400, "The key type cannot be empty"), // API import/export related codes ERROR_READING_META_DATA(900907, "Error while reading meta information from the definition", 400, "Error while reading meta information from the definition"), diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java index a641f650f8e5..41f86b34e05e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java @@ -28,7 +28,6 @@ public class ClientCertificateDTO { private String certificate; private String uniqueId; private String tierName; - private String keyType; private APIIdentifier apiIdentifier; public ClientCertificateDTO() { @@ -69,23 +68,6 @@ public void setTierName(String tierName) { this.tierName = tierName; } - /** - * To get the key type of the certificate. - * @return key type. - */ - public String getKeyType() { - return keyType; - } - - /** - * To set the key type for the current certificate. - * - * @param keyType key type (whether PRODUCTION or SANDBOX). - */ - public void setKeyType(String keyType) { - this.keyType = keyType; - } - /** * To get the alias of the certificate. * diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java index abe716263cf5..a25a91f13045 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java @@ -4018,7 +4018,7 @@ public int deleteCertificate(String userName, String alias, String endpoint) thr } @Override - public int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias) + public int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias, String keyType) throws APIManagementException { checkAccessControlPermission(userNameWithoutChange, apiTypeWrapper.getAccessControl(), apiTypeWrapper.getAccessControlRoles()); @@ -4026,7 +4026,8 @@ public int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrappe ResponseCode responseCode = ResponseCode.INTERNAL_SERVER_ERROR; int tenantId = APIUtil.getInternalOrganizationId(apiTypeWrapper.getOrganization()); - responseCode = certificateManager.deleteClientCertificateFromParentNode(apiTypeWrapper.getId(), alias, tenantId); + responseCode = certificateManager.deleteClientCertificateFromParentNode(apiTypeWrapper.getId(), alias, keyType, + tenantId); return responseCode.getResponseCode(); } @@ -4067,18 +4068,18 @@ public List searchCertificates(int tenantId, String alia } @Override - public List searchClientCertificates(int tenantId, String alias, + public List searchClientCertificates(int tenantId, String alias, String keyType, APIIdentifier apiIdentifier, String organization) throws APIManagementException { - return certificateManager.searchClientCertificates(tenantId, alias, apiIdentifier, organization); + return certificateManager.searchClientCertificates(tenantId, alias, keyType, apiIdentifier, organization); } @Override - public List searchClientCertificates(int tenantId, String alias, + public List searchClientCertificates(int tenantId, String alias, String keyType, APIProductIdentifier apiProductIdentifier, String organization) throws APIManagementException { APIIdentifier apiIdentifier = new APIIdentifier(apiProductIdentifier.getProviderName(), apiProductIdentifier.getName(), apiProductIdentifier.getVersion()); apiIdentifier.setUuid(apiMgtDAO.getUUIDFromIdentifier(apiIdentifier)); - return certificateManager.searchClientCertificates(tenantId, alias, apiIdentifier, organization); + return certificateManager.searchClientCertificates(tenantId, alias, keyType, apiIdentifier, organization); } @Override @@ -4086,10 +4087,10 @@ public boolean isCertificatePresent(int tenantId, String alias) throws APIManage return certificateManager.isCertificatePresent(tenantId, alias); } - public ClientCertificateDTO getClientCertificate(int tenantId, String alias, String organization) + public ClientCertificateDTO getClientCertificate(int tenantId, String alias, String keyType, String organization) throws APIManagementException { List clientCertificateDTOS = certificateManager - .searchClientCertificates(tenantId, alias, null, organization); + .searchClientCertificates(tenantId, alias, keyType, null, organization); if (clientCertificateDTOS != null && clientCertificateDTOS.size() > 0) { return clientCertificateDTOS.get(0); } @@ -4097,13 +4098,13 @@ public ClientCertificateDTO getClientCertificate(int tenantId, String alias, Str } @Override - public ClientCertificateDTO getClientCertificate(String alias, ApiTypeWrapper apiTypeWrapper, + public ClientCertificateDTO getClientCertificate(String alias, String keyType, ApiTypeWrapper apiTypeWrapper, String organization) throws APIManagementException { checkAccessControlPermission(userNameWithoutChange, apiTypeWrapper.getAccessControl(), apiTypeWrapper.getAccessControlRoles()); int tenantId = APIUtil.getInternalOrganizationId(organization); List clientCertificateDTOS = certificateManager - .searchClientCertificates(tenantId, alias, apiTypeWrapper.getId(), organization); + .searchClientCertificates(tenantId, alias, keyType, apiTypeWrapper.getId(), organization); if (clientCertificateDTOS != null && clientCertificateDTOS.size() > 0) { return clientCertificateDTOS.get(0); } @@ -4154,8 +4155,8 @@ public int getCertificateCountPerTenant(int tenantId) throws APIManagementExcept } @Override - public int getClientCertificateCount(int tenantId) throws APIManagementException { - return certificateManager.getClientCertificateCount(tenantId); + public int getClientCertificateCount(int tenantId, String keyType) throws APIManagementException { + return certificateManager.getClientCertificateCount(tenantId, keyType); } @Override diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java index f408ec12e175..5ed09b4def51 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIProvider.java @@ -108,9 +108,9 @@ public int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, } @Override - public int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias) + public int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias, String keyType) throws APIManagementException { - return super.deleteClientCertificate(userName, apiTypeWrapper, alias); + return super.deleteClientCertificate(userName, apiTypeWrapper, alias, keyType); } @Override @@ -140,9 +140,9 @@ public boolean isCertificatePresent(int tenantId, String alias) throws APIManage } @Override - public ClientCertificateDTO getClientCertificate(String alias, ApiTypeWrapper apiTypeWrapper, String organization) - throws APIManagementException { - return super.getClientCertificate(alias,apiTypeWrapper, organization); + public ClientCertificateDTO getClientCertificate(String alias, String keyType, ApiTypeWrapper apiTypeWrapper, + String organization) throws APIManagementException { + return super.getClientCertificate(alias, keyType, apiTypeWrapper, organization); } @Override diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java index 1a93c464345b..b8ebbe6f0982 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java @@ -190,12 +190,14 @@ ResponseCode addClientCertificate(Identifier apiIdentifier, String certificate, * * @param apiIdentifier : Identifier of the API which particular client certificate is added against. * @param alias : Alias of the certificate which needs to be removed. + * @param keyType : Key type of the certificate * @param tenantId : The owner tenant id. * @return : SUCCESS: If operation success * INTERNAL_SERVER_ERROR: If any internal error occurred * CERTIFICATE_NOT_FOUND : If Certificate is not found in the trust store. */ - ResponseCode deleteClientCertificateFromParentNode(Identifier apiIdentifier, String alias, int tenantId); + ResponseCode deleteClientCertificateFromParentNode(Identifier apiIdentifier, String alias, String keyType, + int tenantId); /** * Method to add client certificate to gateway nodes. @@ -224,7 +226,7 @@ ResponseCode addClientCertificate(Identifier apiIdentifier, String certificate, * @return List of certificates that match the criteria. * @throws APIManagementException API Management Exception. */ - List searchClientCertificates(int tenantId, String alias, Identifier apiIdentifier, + List searchClientCertificates(int tenantId, String alias, String keyType, Identifier apiIdentifier, String organization) throws APIManagementException; /** @@ -248,7 +250,7 @@ ResponseCode updateClientCertificate(String certificate, String alias, String ti * @return count of client certificates. * @throws APIManagementException API Management Exception. */ - int getClientCertificateCount(int tenantId) throws APIManagementException; + int getClientCertificateCount(int tenantId, String keyType) throws APIManagementException; /** * Method to add the certificate to gateway nodes. diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java index 172e9a281506..8480540dedf6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImpl.java @@ -120,7 +120,7 @@ public ResponseCode addClientCertificate(Identifier apiIdentifier, String certif try { responseCode = certificateMgtUtils.validateCertificate(alias, tenantId, certificate); if (responseCode == ResponseCode.SUCCESS) { - if (certificateMgtDAO.checkWhetherAliasExist(alias, tenantId)) { + if (certificateMgtDAO.checkWhetherAliasExist(keyType, alias, tenantId)) { responseCode = ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE; } else { certificateMgtDAO @@ -175,10 +175,11 @@ public ResponseCode deleteCertificateFromParentNode(String alias, String endpoin } @Override - public ResponseCode deleteClientCertificateFromParentNode(Identifier apiIdentifier, String alias, int tenantId) { + public ResponseCode deleteClientCertificateFromParentNode(Identifier apiIdentifier, String alias, String keyType, + int tenantId) { try { - boolean removeFromDB = certificateMgtDAO.deleteClientCertificate(apiIdentifier, alias, tenantId); + boolean removeFromDB = certificateMgtDAO.deleteClientCertificate(apiIdentifier, alias, keyType, tenantId); if (removeFromDB) { return ResponseCode.SUCCESS; } else { @@ -402,12 +403,12 @@ public List getCertificates(int tenantId, String alias, } @Override - public List searchClientCertificates(int tenantId, String alias, + public List searchClientCertificates(int tenantId, String alias, String keyType, Identifier apiIdentifier, String organization) throws APIManagementException { try { - return CertificateMgtDAO.getInstance().getClientCertificates(tenantId, alias, apiIdentifier, organization); + return CertificateMgtDAO.getInstance().getClientCertificates(tenantId, alias, keyType, apiIdentifier, organization); } catch (CertificateManagementException e) { throw new APIManagementException( "Error while retrieving client certificate information for the tenant : " + tenantId, e); @@ -494,14 +495,14 @@ public int getCertificateCount(int tenantId) throws APIManagementException { } @Override - public int getClientCertificateCount(int tenantId) throws APIManagementException { + public int getClientCertificateCount(int tenantId, String keyType) throws APIManagementException { try { - return certificateMgtDAO.getClientCertificateCount(tenantId); + return certificateMgtDAO.getClientCertificateCount(tenantId, keyType); } catch (CertificateManagementException e) { throw new APIManagementException( - "Certificate management exception while getting count of client certificates of the tenant " - + tenantId, e); + "Certificate management exception while getting count of " + keyType + + " type client certificates of the tenant " + tenantId, e); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java index 139319fef8e0..060e0c3fe806 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/ApiMgtDAO.java @@ -178,6 +178,8 @@ public class ApiMgtDAO { private boolean forceCaseInsensitiveComparisons = false; private boolean multiGroupAppSharingEnabled = false; private String KeyManagerAccessPublic = "PUBLIC"; + private static final String[] keyTypes = + new String[]{APIConstants.API_KEY_TYPE_PRODUCTION, APIConstants.API_KEY_TYPE_SANDBOX}; String migrationEnabled = System.getProperty(APIConstants.MIGRATE); private ApiMgtDAO() { @@ -17029,42 +17031,45 @@ public void addAPIRevision(APIRevision apiRevision) throws APIManagementExceptio revisionAPIPolicies(apiRevision, tenantDomain, uriTemplateMap, connection); // Adding to AM_API_CLIENT_CERTIFICATE - String getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES; + String getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE; String driverName = connection.getMetaData().getDriverName(); if (driverName.contains("Oracle")) { - getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_ORACLE_SQL; + getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_ORACLE_SQL; } else if (driverName.contains("MS SQL") || driverName.contains("Microsoft")) { - getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_MSSQL; + getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_MSSQL; } - PreparedStatement getClientCertificatesStatement = connection.prepareStatement(getClientCertificatesQuery); - getClientCertificatesStatement.setInt(1, apiId); - List clientCertificateDTOS = new ArrayList<>(); - try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { - while (rs.next()) { - ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); - clientCertificateDTO.setAlias(rs.getString(1)); - clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); - clientCertificateDTO.setTierName(rs.getString(3)); - clientCertificateDTO.setKeyType(rs.getString(4)); - clientCertificateDTOS.add(clientCertificateDTO); + //get production and sandbox certificates lists separately + for (String keyType : keyTypes) { + PreparedStatement getClientCertificatesStatement = connection.prepareStatement(getClientCertificatesQuery); + getClientCertificatesStatement.setInt(1, apiId); + getClientCertificatesStatement.setString(2, keyType); + List clientCertificateDTOS = new ArrayList<>(); + try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { + while (rs.next()) { + ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); + clientCertificateDTO.setAlias(rs.getString(1)); + clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); + clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTOS.add(clientCertificateDTO); + } + } + PreparedStatement insertClientCertificateStatement = connection + .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES); + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + insertClientCertificateStatement.setInt(1, tenantId); + insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); + insertClientCertificateStatement.setInt(3, apiId); + insertClientCertificateStatement.setBinaryStream(4, + getInputStream(clientCertificateDTO.getCertificate())); + insertClientCertificateStatement.setBoolean(5, false); + insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); + insertClientCertificateStatement.setString(7, keyType); + insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); + insertClientCertificateStatement.addBatch(); } + insertClientCertificateStatement.executeBatch(); } - PreparedStatement insertClientCertificateStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { - insertClientCertificateStatement.setInt(1, tenantId); - insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); - insertClientCertificateStatement.setInt(3, apiId); - insertClientCertificateStatement.setBinaryStream(4, - getInputStream(clientCertificateDTO.getCertificate())); - insertClientCertificateStatement.setBoolean(5, false); - insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); - insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); - insertClientCertificateStatement.addBatch(); - } - insertClientCertificateStatement.executeBatch(); // Adding to AM_GRAPHQL_COMPLEXITY table PreparedStatement getGraphQLComplexityStatement = connection @@ -17954,37 +17959,40 @@ public void restoreAPIRevision(APIRevision apiRevision) throws APIManagementExce .APIRevisionSqlConstants.REMOVE_CURRENT_API_ENTRIES_IN_AM_API_CLIENT_CERTIFICATE_BY_API_ID); removeClientCertificatesStatement.setInt(1, apiId); removeClientCertificatesStatement.executeUpdate(); - - PreparedStatement getClientCertificatesStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_BY_REVISION_UUID); - getClientCertificatesStatement.setInt(1, apiId); - getClientCertificatesStatement.setString(2, apiRevision.getRevisionUUID()); - List clientCertificateDTOS = new ArrayList<>(); - try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { - while (rs.next()) { - ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); - clientCertificateDTO.setAlias(rs.getString(1)); - clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); - clientCertificateDTO.setTierName(rs.getString(3)); - clientCertificateDTO.setKeyType(rs.getString(4)); - clientCertificateDTOS.add(clientCertificateDTO); + PreparedStatement getClientCertificatesStatement = connection.prepareStatement(SQLConstants. + APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_BY_REVISION_UUID_AND_KEY_TYPE); + + //get production and sandbox certificates lists separately + for (String keyType : keyTypes) { + getClientCertificatesStatement.setInt(1, apiId); + getClientCertificatesStatement.setString(2, apiRevision.getRevisionUUID()); + getClientCertificatesStatement.setString(3, keyType); + List clientCertificateDTOS = new ArrayList<>(); + try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { + while (rs.next()) { + ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); + clientCertificateDTO.setAlias(rs.getString(1)); + clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); + clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTOS.add(clientCertificateDTO); + } } + PreparedStatement insertClientCertificateStatement = connection + .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API); + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + insertClientCertificateStatement.setInt(1, tenantId); + insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); + insertClientCertificateStatement.setInt(3, apiId); + insertClientCertificateStatement.setBinaryStream(4, + getInputStream(clientCertificateDTO.getCertificate())); + insertClientCertificateStatement.setBoolean(5, false); + insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); + insertClientCertificateStatement.setString(7, keyType); + insertClientCertificateStatement.setString(8, "Current API"); + insertClientCertificateStatement.addBatch(); + } + insertClientCertificateStatement.executeBatch(); } - PreparedStatement insertClientCertificateStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { - insertClientCertificateStatement.setInt(1, tenantId); - insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); - insertClientCertificateStatement.setInt(3, apiId); - insertClientCertificateStatement.setBinaryStream(4, - getInputStream(clientCertificateDTO.getCertificate())); - insertClientCertificateStatement.setBoolean(5, false); - insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); - insertClientCertificateStatement.setString(8, "Current API"); - insertClientCertificateStatement.addBatch(); - } - insertClientCertificateStatement.executeBatch(); // Restoring AM_GRAPHQL_COMPLEXITY table PreparedStatement removeGraphQLComplexityStatement = connection.prepareStatement(SQLConstants @@ -18269,42 +18277,48 @@ public void addAPIProductRevision(APIRevision apiRevision) throws APIManagementE insertOperationPolicyMappingStatement.executeBatch(); // Adding to AM_API_CLIENT_CERTIFICATE - String getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES; + String getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE; String driverName = connection.getMetaData().getDriverName(); if (driverName.contains("Oracle")) { - getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_ORACLE_SQL; + getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_ORACLE_SQL; } else if (driverName.contains("MS SQL") || driverName.contains("Microsoft")) { - getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_MSSQL; + getClientCertificatesQuery = SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_MSSQL; } PreparedStatement getClientCertificatesStatement = connection.prepareStatement(getClientCertificatesQuery); - getClientCertificatesStatement.setInt(1, apiId); - List clientCertificateDTOS = new ArrayList<>(); - try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { - while (rs.next()) { - ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); - clientCertificateDTO.setAlias(rs.getString(1)); - clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); - clientCertificateDTO.setTierName(rs.getString(3)); - clientCertificateDTO.setKeyType(rs.getString(4)); - clientCertificateDTOS.add(clientCertificateDTO); + + //get production and sandbox certificates lists separately + + for (String keyType : keyTypes) { + getClientCertificatesStatement.setInt(1, apiId); + getClientCertificatesStatement.setString(2, keyType); + + List clientCertificateDTOS = new ArrayList<>(); + try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { + while (rs.next()) { + ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); + clientCertificateDTO.setAlias(rs.getString(1)); + clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); + clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTOS.add(clientCertificateDTO); + } + } + PreparedStatement insertClientCertificateStatement = connection + .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES); + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + insertClientCertificateStatement.setInt(1, tenantId); + insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); + insertClientCertificateStatement.setInt(3, apiId); + insertClientCertificateStatement.setBinaryStream(4, + getInputStream(clientCertificateDTO.getCertificate())); + insertClientCertificateStatement.setBoolean(5, false); + insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); + insertClientCertificateStatement.setString(7, keyType); + insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); + insertClientCertificateStatement.addBatch(); } + insertClientCertificateStatement.executeBatch(); } - PreparedStatement insertClientCertificateStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { - insertClientCertificateStatement.setInt(1, tenantId); - insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); - insertClientCertificateStatement.setInt(3, apiId); - insertClientCertificateStatement.setBinaryStream(4, - getInputStream(clientCertificateDTO.getCertificate())); - insertClientCertificateStatement.setBoolean(5, false); - insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); - insertClientCertificateStatement.setString(8, apiRevision.getRevisionUUID()); - insertClientCertificateStatement.addBatch(); - } - insertClientCertificateStatement.executeBatch(); // Adding to AM_GRAPHQL_COMPLEXITY table PreparedStatement getGraphQLComplexityStatement = connection @@ -18517,36 +18531,40 @@ public void restoreAPIProductRevision(APIRevision apiRevision) throws APIManagem removeClientCertificatesStatement.setInt(1, apiId); removeClientCertificatesStatement.executeUpdate(); - PreparedStatement getClientCertificatesStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_BY_REVISION_UUID); - getClientCertificatesStatement.setInt(1, apiId); - getClientCertificatesStatement.setString(2, apiRevision.getRevisionUUID()); - List clientCertificateDTOS = new ArrayList<>(); - try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { - while (rs.next()) { - ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); - clientCertificateDTO.setAlias(rs.getString(1)); - clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); - clientCertificateDTO.setTierName(rs.getString(3)); - clientCertificateDTO.setKeyType(rs.getString(4)); - clientCertificateDTOS.add(clientCertificateDTO); + PreparedStatement getClientCertificatesStatement = connection.prepareStatement(SQLConstants + .APIRevisionSqlConstants.GET_CLIENT_CERTIFICATES_BY_REVISION_UUID_AND_KEY_TYPE); + + //get production and sandbox certificates lists separately + for (String keyType : keyTypes) { + getClientCertificatesStatement.setInt(1, apiId); + getClientCertificatesStatement.setString(2, apiRevision.getRevisionUUID()); + getClientCertificatesStatement.setString(3, keyType); + List clientCertificateDTOS = new ArrayList<>(); + try (ResultSet rs = getClientCertificatesStatement.executeQuery()) { + while (rs.next()) { + ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); + clientCertificateDTO.setAlias(rs.getString(1)); + clientCertificateDTO.setCertificate(APIMgtDBUtil.getStringFromInputStream(rs.getBinaryStream(2))); + clientCertificateDTO.setTierName(rs.getString(3)); + clientCertificateDTOS.add(clientCertificateDTO); + } + } + PreparedStatement insertClientCertificateStatement = connection + .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API); + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + insertClientCertificateStatement.setInt(1, tenantId); + insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); + insertClientCertificateStatement.setInt(3, apiId); + insertClientCertificateStatement.setBinaryStream(4, + getInputStream(clientCertificateDTO.getCertificate())); + insertClientCertificateStatement.setBoolean(5, false); + insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); + insertClientCertificateStatement.setString(7, keyType); + insertClientCertificateStatement.setString(8, "Current API"); + insertClientCertificateStatement.addBatch(); } + insertClientCertificateStatement.executeBatch(); } - PreparedStatement insertClientCertificateStatement = connection - .prepareStatement(SQLConstants.APIRevisionSqlConstants.INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { - insertClientCertificateStatement.setInt(1, tenantId); - insertClientCertificateStatement.setString(2, clientCertificateDTO.getAlias()); - insertClientCertificateStatement.setInt(3, apiId); - insertClientCertificateStatement.setBinaryStream(4, - getInputStream(clientCertificateDTO.getCertificate())); - insertClientCertificateStatement.setBoolean(5, false); - insertClientCertificateStatement.setString(6, clientCertificateDTO.getTierName()); - insertClientCertificateStatement.setString(7, clientCertificateDTO.getKeyType()); - insertClientCertificateStatement.setString(8, "Current API"); - insertClientCertificateStatement.addBatch(); - } - insertClientCertificateStatement.executeBatch(); // Restoring AM_GRAPHQL_COMPLEXITY table PreparedStatement removeGraphQLComplexityStatement = connection.prepareStatement(SQLConstants diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java index 0b60c8c05891..cbbb98c71ea7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/CertificateMgtDAO.java @@ -108,14 +108,14 @@ private boolean addClientCertificate(Connection connection, String certificate, public boolean updateClientCertificate(String certificate, String alias, String tier, String keyType, int tenantId, String organization) throws CertificateManagementException { - List clientCertificateDTOList = getClientCertificates(tenantId, alias, null, - organization); + List clientCertificateDTOList = getClientCertificates(tenantId, alias, keyType, + null, organization); ClientCertificateDTO clientCertificateDTO; if (clientCertificateDTOList.size() == 0) { if (log.isDebugEnabled()) { - log.debug("Client certificate update request is received for a non-existing alias " + alias + " of " - + "tenant " + tenantId); + log.debug("Client certificate update request is received for a non-existing alias " + alias + " in " + + keyType + " key type of tenant " + tenantId); } return false; } @@ -126,16 +126,13 @@ public boolean updateClientCertificate(String certificate, String alias, String if (StringUtils.isNotEmpty(tier)) { clientCertificateDTO.setTierName(tier); } - if (StringUtils.isNotEmpty(keyType)) { - clientCertificateDTO.setKeyType(keyType); - } try (Connection connection = APIMgtDBUtil.getConnection()) { try { connection.setAutoCommit(false); - deleteClientCertificate(connection, null, alias, tenantId); + deleteClientCertificate(connection, null, alias, keyType, tenantId); addClientCertificate(connection, clientCertificateDTO.getCertificate(), clientCertificateDTO.getApiIdentifier(), alias, clientCertificateDTO.getTierName(), - clientCertificateDTO.getKeyType(), tenantId, organization); + keyType, tenantId, organization); connection.commit(); } catch (SQLException e) { handleConnectionRollBack(connection); @@ -247,12 +244,13 @@ private boolean isCertificateExist(Connection connection, String alias,int tenan * * @param tenantId : The id of the tenant which the certificate belongs to. * @param alias : Alias for the certificate. (Optional) + * @param keyType : The key type of the certificate. * @param apiIdentifier : The API which the certificate is mapped to. (Optional) * @param organization : Organization * @return : A CertificateMetadataDTO object if the certificate is retrieved successfully, null otherwise. */ - public List getClientCertificates(int tenantId, String alias, Identifier apiIdentifier, - String organization) throws CertificateManagementException { + public List getClientCertificates(int tenantId, String alias, String keyType, + Identifier apiIdentifier, String organization) throws CertificateManagementException { Connection connection = null; PreparedStatement preparedStatement = null; @@ -285,6 +283,8 @@ public List getClientCertificates(int tenantId, String ali apiId = ApiMgtDAO.getInstance().getAPIID(apiUuid, connection); } preparedStatement = connection.prepareStatement(selectQuery); + preparedStatement.setString(index, keyType); + index++; preparedStatement.setBoolean(index, false); index++; preparedStatement.setInt(index, tenantId); @@ -301,7 +301,6 @@ public List getClientCertificates(int tenantId, String ali alias = resultSet.getString("ALIAS"); ClientCertificateDTO clientCertificateDTO = new ClientCertificateDTO(); clientCertificateDTO.setTierName(resultSet.getString("TIER_NAME")); - clientCertificateDTO.setKeyType(resultSet.getString("KEY_TYPE")); clientCertificateDTO.setAlias(alias); clientCertificateDTO.setCertificate( APIMgtDBUtil.getStringFromInputStream(resultSet.getBinaryStream("CERTIFICATE"))); @@ -313,11 +312,12 @@ public List getClientCertificates(int tenantId, String ali clientCertificateDTOS.add(clientCertificateDTO); } } catch (SQLException e) { - handleException("Error while searching client certificate details for the tenant " + tenantId, e); + handleException("Error while searching " + keyType + + " client certificate details for the tenant " + tenantId, e); } catch (APIManagementException e) { handleException( - "API Management Exception while searching client certificate details for the tenant " + tenantId, - e); + "API Management Exception while searching " + keyType + + "client certificate details for the tenant " + tenantId, e); } finally { APIMgtDBUtil.closeAllConnections(preparedStatement, connection, resultSet); } @@ -490,15 +490,17 @@ public void updateRemovedCertificatesFromGateways(APIIdentifier apiIdentifier, i } /** - * To get the set of alias of client certificates that are removed from publisher, but not removed from the gateway. + * To get the set of alias of client certificates of given type that are removed from publisher, + * but not removed from the gateway. * * @param apiIdentifier : Identifier of the API. + * @param keyType : Key type of the certificate. * @param tenantId : ID of the tenant. * @return list of alias of client certificates that need to be removed from the gateway. * @throws CertificateManagementException Certificate Management Exception. */ - public List getDeletedClientCertificateAlias(APIIdentifier apiIdentifier, int tenantId) - throws CertificateManagementException { + public List getDeletedClientCertificateAliasOfGivenKeyType(APIIdentifier apiIdentifier, String keyType, + int tenantId) throws CertificateManagementException { String getCertQuery = SQLConstants.ClientCertificateConstants.GET_CERTIFICATES_FOR_API; List aliasList = new ArrayList<>(); @@ -509,7 +511,8 @@ public List getDeletedClientCertificateAlias(APIIdentifier apiIdentifier preparedStatement.setString(2, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName())); preparedStatement.setString(3, apiIdentifier.getName()); preparedStatement.setString(4, apiIdentifier.getVersion()); - preparedStatement.setBoolean(5, true); + preparedStatement.setString(5, keyType); + preparedStatement.setBoolean(6, true); try (ResultSet resultSet = preparedStatement.executeQuery()) { while (resultSet.next()) { aliasList.add(resultSet.getString("ALIAS")); @@ -560,11 +563,12 @@ public boolean deleteCertificate(String alias, String endpoint, int tenantId) * * @param apiIdentifier : Identifier of the API. * @param alias : Alias for the certificate. + * @param keyType : Key type of the certificate. * @param tenantId : The Id of the tenant who owns the certificate. * @return : true if certificate deletion is successful, false otherwise. */ private boolean deleteClientCertificate(Connection connection, Identifier apiIdentifier, String alias, - int tenantId) throws SQLException { + String keyType, int tenantId) throws SQLException { boolean result; String deleteCertQuery = SQLConstants.ClientCertificateConstants.PRE_DELETE_CERTIFICATES; @@ -577,10 +581,11 @@ private boolean deleteClientCertificate(Connection connection, Identifier apiIde preparedStatement.setInt(1, tenantId); preparedStatement.setBoolean(2, true); preparedStatement.setString(3, alias); + preparedStatement.setString(4, keyType); if (apiIdentifier != null) { - preparedStatement.setString(4, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName())); - preparedStatement.setString(5, apiIdentifier.getName()); - preparedStatement.setString(6, apiIdentifier.getVersion()); + preparedStatement.setString(5, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName())); + preparedStatement.setString(6, apiIdentifier.getName()); + preparedStatement.setString(7, apiIdentifier.getVersion()); } preparedStatement.executeUpdate(); } @@ -592,10 +597,11 @@ private boolean deleteClientCertificate(Connection connection, Identifier apiIde preparedStatement.setBoolean(1, true); preparedStatement.setInt(2, tenantId); preparedStatement.setString(3, alias); + preparedStatement.setString(4, keyType); if (apiIdentifier != null) { - preparedStatement.setString(4, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName())); - preparedStatement.setString(5, apiIdentifier.getName()); - preparedStatement.setString(6, apiIdentifier.getVersion()); + preparedStatement.setString(5, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName())); + preparedStatement.setString(6, apiIdentifier.getName()); + preparedStatement.setString(7, apiIdentifier.getVersion()); } result = preparedStatement.executeUpdate() >= 1; } @@ -603,14 +609,14 @@ private boolean deleteClientCertificate(Connection connection, Identifier apiIde return result; } - public boolean deleteClientCertificate(Identifier apiIdentifier, String alias, int tenantId) + public boolean deleteClientCertificate(Identifier apiIdentifier, String alias, String keyType, int tenantId) throws CertificateManagementException { boolean result = false; try (Connection connection = APIMgtDBUtil.getConnection()) { try { connection.setAutoCommit(false); - result = deleteClientCertificate(connection, apiIdentifier, alias, tenantId); + result = deleteClientCertificate(connection, apiIdentifier, alias, keyType, tenantId); connection.commit(); } catch (SQLException e) { handleConnectionRollBack(connection); @@ -658,27 +664,30 @@ public int getCertificateCount(int tenantId) throws CertificateManagementExcepti } /** - * Retrieve the number of total client certificates which a tenant has uploaded. + * Retrieve the number of total client certificates of given key type which a tenant has uploaded. * * @param tenantId : The id of the tenant. + * @param keyType : The key type of the certificate * @return : The total certificate count of the tenant. * @throws CertificateManagementException : */ - public int getClientCertificateCount(int tenantId) throws CertificateManagementException { + public int getClientCertificateCount(int tenantId, String keyType) throws CertificateManagementException { String clientCertificateCountQuery = SQLConstants.ClientCertificateConstants.CERTIFICATE_COUNT_QUERY; int count = 0; try (Connection connection = APIMgtDBUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(clientCertificateCountQuery)) { preparedStatement.setInt(1, tenantId); - preparedStatement.setBoolean(2, false); + preparedStatement.setString(2, keyType); + preparedStatement.setBoolean(3, false); try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { return resultSet.getInt(1); } } } catch (SQLException e) { - handleException("Error while retrieving the client certificate count for tenantId " + tenantId + ".", e); + handleException("Error while retrieving the " + keyType + " type client certificate count for tenantId " + + tenantId + ".", e); } return count; } @@ -686,24 +695,27 @@ public int getClientCertificateCount(int tenantId) throws CertificateManagementE /** * To check whether alias with the given value exist already. * + * @param keyType Key type of the certificate * @param alias Relevant alias. * @return true if the alias exist, false if not. * @throws CertificateManagementException Certificate Management Exception. */ - public boolean checkWhetherAliasExist(String alias, int tenantId) throws CertificateManagementException { + public boolean checkWhetherAliasExist(String keyType, String alias, int tenantId) throws CertificateManagementException { String selectCertificateForAlias = SQLConstants.ClientCertificateConstants.SELECT_CERTIFICATE_FOR_ALIAS; boolean isExist = false; try (Connection connection = APIMgtDBUtil.getConnection()) { try (PreparedStatement preparedStatement = connection.prepareStatement(selectCertificateForAlias)) { - preparedStatement.setString(1, alias); - preparedStatement.setBoolean(2, false); - preparedStatement.setInt(3, tenantId); + preparedStatement.setString(1, keyType); + preparedStatement.setString(2, alias); + preparedStatement.setBoolean(3, false); + preparedStatement.setInt(4, tenantId); try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { isExist = true; if (log.isDebugEnabled()) { - log.debug("Alias " + alias + " exist already and uploaded as a client certificate"); + log.debug("Alias " + alias + " exist already under " + keyType + + " key type and uploaded as a client certificate"); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java index daf89df31ade..3ae8a9c66ece 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/dao/constants/SQLConstants.java @@ -3395,49 +3395,51 @@ public static class ClientCertificateConstants{ public static final String GET_CERTIFICATES_FOR_API = "SELECT ALIAS FROM AM_API_CLIENT_CERTIFICATE WHERE " + "TENANT_ID=? and API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND API_NAME = ? AND " + - "API_VERSION = ? ) and REMOVED=? and REVISION_UUID ='Current API'"; + "API_VERSION = ? ) and KEY_TYPE=? and REMOVED=? and REVISION_UUID ='Current API'"; public static final String DELETE_CERTIFICATES_FOR_API = "DELETE FROM AM_API_CLIENT_CERTIFICATE " + "WHERE TENANT_ID=? and API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND API_NAME = ? " + "AND API_VERSION = ? ) and REMOVED=? and REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_ALIAS = "SELECT ALIAS FROM AM_API_CLIENT_CERTIFICATE " - + "WHERE ALIAS=? AND REMOVED=? AND TENANT_ID =? and REVISION_UUID ='Current API'"; + + "WHERE KEY_TYPE=? AND ALIAS=? AND REMOVED=? AND TENANT_ID =? and REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE, AA.API_PROVIDER, AA.API_NAME, " - + "AA.API_VERSION FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA " - + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AA.API_PROVIDER, AA.API_NAME, " + + "AA.API_VERSION FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA WHERE AC.KEY_TYPE=? AND " + + "AC.REMOVED=? AND AC.TENANT_ID=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_ALIAS = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE, AA.API_PROVIDER, AA.API_NAME, AA.API_VERSION " - + "FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA " - + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.ALIAS=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AA.API_PROVIDER, AA.API_NAME, AA.API_VERSION " + + "FROM AM_API_CLIENT_CERTIFICATE AC, AM_API AA WHERE AC.KEY_TYPE=? AND AC.REMOVED=? AND " + + "AC.TENANT_ID=? AND AC.ALIAS=? AND AA.API_ID=AC.API_ID AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_ALIAS_APIID = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE AC " - + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.ALIAS=? AND AC.API_ID = ? AND AC.REVISION_UUID ='Current API'"; + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME FROM AM_API_CLIENT_CERTIFICATE AC " + + "WHERE AC.KEY_TYPE=? AND AC.REMOVED=? AND AC.TENANT_ID=? AND AC.ALIAS=? AND AC.API_ID = ? " + + "AND AC.REVISION_UUID ='Current API'"; public static final String SELECT_CERTIFICATE_FOR_TENANT_APIID = - "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME, AC.KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE AC " - + "WHERE AC.REMOVED=? AND AC.TENANT_ID=? AND AC.API_ID=? AND AC.REVISION_UUID ='Current API'"; + "SELECT AC.CERTIFICATE, AC.ALIAS, AC.TIER_NAME FROM AM_API_CLIENT_CERTIFICATE AC " + + "WHERE AC.KEY_TYPE=? AND AC.REMOVED=? AND AC.TENANT_ID=? AND AC.API_ID=? AND " + + "AC.REVISION_UUID ='Current API'"; public static final String PRE_DELETE_CERTIFICATES = "DELETE FROM AM_API_CLIENT_CERTIFICATE " - + "WHERE TENANT_ID=? AND REMOVED=? AND REVISION_UUID ='Current API' AND ALIAS=? AND API_ID=(SELECT API_ID FROM AM_API WHERE " + - "API_PROVIDER = ? AND API_NAME = ? AND API_VERSION = ? )"; + + "WHERE TENANT_ID=? AND REMOVED=? AND REVISION_UUID ='Current API' AND ALIAS=? AND KEY_TYPE=? " + + "AND API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND API_NAME = ? AND API_VERSION = ? )"; public static final String PRE_DELETE_CERTIFICATES_WITHOUT_APIID = "DELETE FROM AM_API_CLIENT_CERTIFICATE " - + "WHERE TENANT_ID=? AND REMOVED=? and ALIAS=? AND REVISION_UUID ='Current API'"; + + "WHERE TENANT_ID=? AND REMOVED=? and ALIAS=? AND KEY_TYPE=? AND REVISION_UUID ='Current API'"; public static final String DELETE_CERTIFICATES = "UPDATE AM_API_CLIENT_CERTIFICATE SET REMOVED = ? " - + "WHERE TENANT_ID=? AND REVISION_UUID ='Current API' AND ALIAS=? AND API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND " + - "API_NAME = ? AND API_VERSION = ? )"; + + "WHERE TENANT_ID=? AND REVISION_UUID ='Current API' AND ALIAS=? AND KEY_TYPE=? " + + "AND API_ID=(SELECT API_ID FROM AM_API WHERE API_PROVIDER = ? AND API_NAME = ? AND API_VERSION = ? )"; public static final String DELETE_CERTIFICATES_WITHOUT_APIID = "UPDATE AM_API_CLIENT_CERTIFICATE SET REMOVED=? " - + "WHERE TENANT_ID=? AND ALIAS=? AND REVISION_UUID ='Current API'"; + + "WHERE TENANT_ID=? AND ALIAS=? AND KEY_TYPE=? AND REVISION_UUID ='Current API'"; public static final String CERTIFICATE_COUNT_QUERY = "SELECT COUNT(*) AS count FROM AM_API_CLIENT_CERTIFICATE " + - "WHERE TENANT_ID=? AND REMOVED=? AND REVISION_UUID ='Current API'"; + "WHERE TENANT_ID=? AND KEY_TYPE=? AND REMOVED=? AND REVISION_UUID ='Current API'"; } /** @@ -3803,13 +3805,16 @@ public static class APIRevisionSqlConstants { "AND THROTTLING_TIER = ? AND REVISION_UUID = ?"; public static final String INSERT_URL_MAPPINGS = "INSERT INTO AM_API_URL_MAPPING(API_ID, HTTP_METHOD," + " AUTH_SCHEME, URL_PATTERN, THROTTLING_TIER, REVISION_UUID) VALUES(?,?,?,?,?,?)"; - public static final String GET_CLIENT_CERTIFICATES = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=FALSE"; - public static final String GET_CLIENT_CERTIFICATES_MSSQL = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; + public static final String GET_CLIENT_CERTIFICATES_OF_KEY_TYPE = "SELECT ALIAS, CERTIFICATE," + + " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND" + + " KEY_TYPE=? AND REMOVED=FALSE"; + public static final String GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_MSSQL = "SELECT ALIAS, CERTIFICATE," + + " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND" + + " KEY_TYPE=? AND REMOVED=0"; - public static final String GET_CLIENT_CERTIFICATES_ORACLE_SQL = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND REMOVED=0"; + public static final String GET_CLIENT_CERTIFICATES_OF_KEY_TYPE_ORACLE_SQL = "SELECT ALIAS, CERTIFICATE," + + " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API' AND" + + " KEY_TYPE=? AND REMOVED=0"; public static final String INSERT_CLIENT_CERTIFICATES = "INSERT INTO AM_API_CLIENT_CERTIFICATE(TENANT_ID, " + "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, KEY_TYPE, REVISION_UUID) VALUES(?,?,?,?,?,?,?,?)"; @@ -3921,8 +3926,8 @@ public static class APIRevisionSqlConstants { "AND THROTTLING_TIER = ? "; public static final String REMOVE_CURRENT_API_ENTRIES_IN_AM_API_CLIENT_CERTIFICATE_BY_API_ID = "DELETE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID='Current API'"; - public static final String GET_CLIENT_CERTIFICATES_BY_REVISION_UUID = "SELECT ALIAS, CERTIFICATE," + - " TIER_NAME, KEY_TYPE FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID = ?"; + public static final String GET_CLIENT_CERTIFICATES_BY_REVISION_UUID_AND_KEY_TYPE = "SELECT ALIAS, CERTIFICATE," + + " TIER_NAME FROM AM_API_CLIENT_CERTIFICATE WHERE API_ID = ? AND REVISION_UUID = ? AND KEY_TYPE = ?"; public static final String INSERT_CLIENT_CERTIFICATES_AS_CURRENT_API = "INSERT INTO AM_API_CLIENT_CERTIFICATE(TENANT_ID, " + "ALIAS, API_ID, CERTIFICATE, REMOVED, TIER_NAME, KEY_TYPE, REVISION_UUID) VALUES(?,?,?,?,?,?,?,?)"; public static final String REMOVE_CURRENT_API_ENTRIES_IN_AM_GRAPHQL_COMPLEXITY_BY_API_ID = diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java index 0e344573486d..e2ed78b3ef46 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManagerImplTest.java @@ -429,13 +429,15 @@ public void testAddClientCertificate() throws CertificateManagementException { PowerMockito .stub(PowerMockito.method(CertificateMgtUtils.class, "validateCertificate")) .toReturn(ResponseCode.SUCCESS); - Mockito.when(certificateMgtDAO.checkWhetherAliasExist(ALIAS, TENANT_ID)).thenReturn(true); + Mockito.when(certificateMgtDAO.checkWhetherAliasExist(APIConstants.API_KEY_TYPE_PRODUCTION, + ALIAS, TENANT_ID)).thenReturn(true); responseCode = certificateManager .addClientCertificate(null, BASE64_ENCODED_CERT, ALIAS, null, APIConstants.API_KEY_TYPE_PRODUCTION, MultitenantConstants.SUPER_TENANT_ID, "org1"); Assert.assertEquals("Response code was wrong while trying add a client certificate with an existing alias", ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode(), responseCode.getResponseCode()); - Mockito.when(certificateMgtDAO.checkWhetherAliasExist(ALIAS, TENANT_ID)).thenReturn(false); + Mockito.when(certificateMgtDAO.checkWhetherAliasExist(APIConstants.API_KEY_TYPE_PRODUCTION, + ALIAS, TENANT_ID)).thenReturn(false); Mockito.when(certificateMgtDAO .addClientCertificate(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyString())).thenReturn(true); @@ -479,14 +481,16 @@ public void testUpdateClientCertificate() throws APIManagementException { public void testDeleteClientCertificate() throws CertificateManagementException { Mockito.when(certificateMgtDAO - .deleteClientCertificate(Mockito.any(), Mockito.anyString(), Mockito.anyInt())) + .deleteClientCertificate(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyInt())) .thenReturn(false).thenReturn(true); ResponseCode responseCode = certificateManager - .deleteClientCertificateFromParentNode(null, ALIAS, MultitenantConstants.SUPER_TENANT_ID); + .deleteClientCertificateFromParentNode(null, ALIAS, APIConstants.API_KEY_TYPE_PRODUCTION, + MultitenantConstants.SUPER_TENANT_ID); Assert.assertEquals("Response code was wrong, for a failure in deletion", ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode(), responseCode.getResponseCode()); responseCode = certificateManager - .deleteClientCertificateFromParentNode(null, ALIAS, MultitenantConstants.SUPER_TENANT_ID); + .deleteClientCertificateFromParentNode(null, ALIAS, APIConstants.API_KEY_TYPE_PRODUCTION, + MultitenantConstants.SUPER_TENANT_ID); Assert.assertEquals("Response code was wrong, for a success in deletion", ResponseCode.SUCCESS.getResponseCode(), responseCode.getResponseCode()); } @@ -502,9 +506,11 @@ public void testSearchClientCertificate() throws APIManagementException { PowerMockito.stub(PowerMockito.method(CertificateMgtDAO.class, "getClientCertificates")) .toReturn(new ArrayList()); Assert.assertNotNull("Client certificate retrieval failed", certificateManager - .searchClientCertificates(MultitenantConstants.SUPER_TENANT_ID, ALIAS, null, organization)); + .searchClientCertificates(MultitenantConstants.SUPER_TENANT_ID, ALIAS, + APIConstants.API_KEY_TYPE_PRODUCTION, null, organization)); Assert.assertNotNull("Client certificate retrieval failed", certificateManager - .searchClientCertificates(MultitenantConstants.SUPER_TENANT_ID, null, null, organization)); + .searchClientCertificates(MultitenantConstants.SUPER_TENANT_ID, null, + APIConstants.API_KEY_TYPE_PRODUCTION, null, organization)); } /** diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java index 9855e4bceeeb..d5215bd6b2e1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/test/java/org/wso2/carbon/apimgt/impl/dao/test/CertificateMgtDaoTest.java @@ -25,7 +25,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.APIManagerDatabaseException; import org.wso2.carbon.apimgt.api.dto.CertificateMetadataDTO; @@ -262,10 +261,10 @@ public void testDeleteClientCertificate() throws CertificateManagementException public void testGetClientCertificateCount() throws CertificateManagementException { addClientCertificate(); Assert.assertEquals("The expected client certificate count does not match with the retrieved count", 1, - certificateMgtDAO.getClientCertificateCount(TENANT_ID)); + certificateMgtDAO.getClientCertificateCount(TENANT_ID, APIConstants.API_KEY_TYPE_PRODUCTION)); deleteClientCertificate(); Assert.assertEquals("The expected client certificate count does not match with the retrieved count", 0, - certificateMgtDAO.getClientCertificateCount(TENANT_ID)); + certificateMgtDAO.getClientCertificateCount(TENANT_ID, APIConstants.API_KEY_TYPE_PRODUCTION)); } /** @@ -276,10 +275,12 @@ public void testGetClientCertificateCount() throws CertificateManagementExceptio @Test public void testCheckWhetherAliasExist() throws CertificateManagementException { Assert.assertFalse("The non-existing alias was detected as exist", - certificateMgtDAO.checkWhetherAliasExist("test", MultitenantConstants.SUPER_TENANT_ID)); + certificateMgtDAO.checkWhetherAliasExist(APIConstants.API_KEY_TYPE_PRODUCTION, + "test", MultitenantConstants.SUPER_TENANT_ID)); addClientCertificate(); Assert.assertTrue("The existing alias was detected as notexist", - certificateMgtDAO.checkWhetherAliasExist("test", MultitenantConstants.SUPER_TENANT_ID)); + certificateMgtDAO.checkWhetherAliasExist(APIConstants.API_KEY_TYPE_PRODUCTION, + "test", MultitenantConstants.SUPER_TENANT_ID)); deleteClientCertificate(); } @@ -292,26 +293,31 @@ public void testCheckWhetherAliasExist() throws CertificateManagementException { public void testGetClientCertificates() throws CertificateManagementException { String organization = "org1"; List clientCertificateDTOS = certificateMgtDAO - .getClientCertificates(TENANT_ID, null, null, organization); + .getClientCertificates(TENANT_ID, null, APIConstants.API_KEY_TYPE_PRODUCTION, + null, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 0, clientCertificateDTOS.size()); addClientCertificate(); - clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, null, null, organization); + clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, null, + APIConstants.API_KEY_TYPE_PRODUCTION, null, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); - clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test", null, organization); + clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test", + APIConstants.API_KEY_TYPE_PRODUCTION, null, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); - clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test1", null, organization); + clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test1", + APIConstants.API_KEY_TYPE_PRODUCTION, null, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 0, clientCertificateDTOS.size()); - clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test", apiIdentifier, organization); + clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, "test", + APIConstants.API_KEY_TYPE_PRODUCTION, apiIdentifier, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); - Assert.assertNotNull("The key type of a client certificate cannot be null", - clientCertificateDTOS.get(0).getKeyType()); - clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, null, apiIdentifier, organization); + + clientCertificateDTOS = certificateMgtDAO.getClientCertificates(TENANT_ID, null, + APIConstants.API_KEY_TYPE_PRODUCTION, apiIdentifier, organization); Assert.assertEquals("The client certificate DTO list that matches the search criteria is not returned", 1, clientCertificateDTOS.size()); deleteClientCertificate(); @@ -325,13 +331,16 @@ public void testGetClientCertificates() throws CertificateManagementException { @Test public void testGetDeletedClientCertificates() throws CertificateManagementException { certificateMgtDAO.updateRemovedCertificatesFromGateways(apiIdentifier, TENANT_ID); - List aliasList = certificateMgtDAO.getDeletedClientCertificateAlias(apiIdentifier, TENANT_ID); + List aliasList = certificateMgtDAO.getDeletedClientCertificateAliasOfGivenKeyType(apiIdentifier, + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID); Assert.assertEquals("The number of deleted certificates retrieved was wrong", 0, aliasList.size()); addClientCertificate(); - aliasList = certificateMgtDAO.getDeletedClientCertificateAlias(apiIdentifier, TENANT_ID); + aliasList = certificateMgtDAO.getDeletedClientCertificateAliasOfGivenKeyType(apiIdentifier, + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID); Assert.assertEquals("The number of deleted certificates retrieved was wrong", 0, aliasList.size()); deleteClientCertificate(); - aliasList = certificateMgtDAO.getDeletedClientCertificateAlias(apiIdentifier, TENANT_ID); + aliasList = certificateMgtDAO.getDeletedClientCertificateAliasOfGivenKeyType(apiIdentifier, + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID); Assert.assertEquals("The number of deleted certificates retrieved was wrong", 1, aliasList.size()); } @@ -353,7 +362,8 @@ private boolean addClientCertificate() throws CertificateManagementException { * @throws CertificateManagementException Certificate Management Exception. */ private boolean deleteClientCertificate() throws CertificateManagementException { - return certificateMgtDAO.deleteClientCertificate(apiIdentifier, "test", TENANT_ID); + return certificateMgtDAO.deleteClientCertificate(apiIdentifier, "test", + APIConstants.API_KEY_TYPE_PRODUCTION, TENANT_ID); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json index a7fa59630d63..8040e385bd35 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json @@ -1354,8 +1354,8 @@ "type" : "string", "example" : "EXCHANGED", "description" : "The type of the tokens to be used (exchanged or without exchanged). Accepted values are EXCHANGED, DIRECT or BOTH.", - "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ], - "default" : "DIRECT" + "default" : "DIRECT", + "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ] } } }, diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java index 2de0f6b2a50b..2d39e73d6200 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java @@ -91,6 +91,7 @@ public final class RestApiConstants { public static final String ALIAS_PARAM = "{alias}"; public static final String LIMIT_PARAM = "{limit}"; public static final String OFFSET_PARAM = "{offset}"; + public static final String KEYTYPE_PARAM = "{keyType}"; public static final String SORTBY_PARAM = "{sortBy}"; public static final String SORTORDER_PARAM = "{sortOrder}"; public static final String TYPE_PARAM = "{type}"; @@ -302,11 +303,11 @@ public final class RestApiConstants { public static final String MIGRATION_MODE = "migrationMode"; public static final String CERTS_BASE_PATH = "/certificates"; - public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates"; + public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/"; public static final String CERTS_GET_PAGINATED_URL = CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String CLIENT_CERTS_GET_PAGINATED_URL = - CLIENT_CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; + CLIENT_CERTS_BASE_PATH + KEYTYPE_PARAM + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String IN_SEQUENCE = "in"; public static final String OUT_SEQUENCE = "out"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml index 9aa4db9ea6a8..8dff2ebf0c29 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml @@ -1330,6 +1330,18 @@ paths: Retrieves all existing deny policies. parameters: - $ref: '#/components/parameters/Accept' + - name: query + in: query + description: | + **Search condition**. + You can search in attributes by using **"conditionType:"** modifier and **"conditionValue:"** modifier. + Eg. + The entry "conditionType:API" will result in a match with blocking conditions only if the conditionType is "API". Similarly, "conditionValue:test/1.0.0" will result in a match with blocking conditions only if the conditionValue is "test/1.0.0". + When you use "conditionType:API & conditionValue:test/1.0.0" as a combination, it will result in a match with blocking conditions only if both the conditionType is "API" and the conditionValue is "test/1.0.0". + If query attribute is provided, this returns the blocking conditions that match the specified attributes. + Please note that you need to use encoded URL (URL encoding) if you are using a client which does not support URL encoding (such as curl) + schema: + type: string responses: 200: description: | diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index 88bb780dfcd9..2cd878390958 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4559,6 +4559,7 @@ paths: tags: - Client Certificates summary: Retrieve/ Search Uploaded Client Certificates + deprecated: true description: | This operation can be used to retrieve and search the uploaded client certificates. parameters: @@ -4604,6 +4605,7 @@ paths: tags: - Client Certificates summary: Upload a New Certificate + deprecated: true description: | This operation can be used to upload a new certificate for an endpoint. parameters: @@ -4629,10 +4631,6 @@ paths: tier: type: string description: API tier to which the certificate should be applied. - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION required: true responses: 200: @@ -4671,8 +4669,128 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate + /apis/{apiId}/client-certificates/{keyType}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: + tags: + - Client Certificates + summary: Retrieve/ Search Uploaded Client Certificates of a given key type + description: | + This operation can be used to retrieve and search the uploaded client certificates of a given key type. + parameters: + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' + - name: alias + in: query + description: Alias for the client certificate + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. Successful response with the list of matching certificate information in the body. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertificates' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates?alias=wso2carbon"' + operationId: getAPIClientCertificatesByKeyType + post: + tags: + - Client Certificates + summary: Upload a New Certificate of the given key type + description: | + This operation can be used to upload a new certificate for an endpoint of the given type. + parameters: + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + required: + - alias + - certificate + - tier + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + alias: + maxLength: 30 + minLength: 1 + type: string + description: Alias for the certificate + tier: + type: string + description: API tier to which the certificate should be applied. + required: true + responses: + 200: + description: | + OK. + The Certificate added successfully. + headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_add + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' + operationId: addAPIClientCertificateOfGivenKeyType + /apis/{apiId}/client-certificates/{alias}: get: + deprecated: true tags: - Client Certificates summary: Get the Certificate Information @@ -4718,6 +4836,7 @@ paths: operationId: getAPIClientCertificateByAlias put: + deprecated: true tags: - Client Certificates summary: Update a Certificate @@ -4789,6 +4908,7 @@ paths: operationId: updateAPIClientCertificateByAlias delete: + deprecated: true tags: - Client Certificates summary: Delete a Certificate @@ -4831,9 +4951,174 @@ paths: source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByAlias + /apis/{apiId}/client-certificates/{keyType}/{alias}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: + tags: + - Client Certificates + summary: Get the Certificate Information of a Given Key Type + description: | + This operation can be used to get the information about a certificate of a given key type. + parameters: + - name: alias + in: path + required: true + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/CertificateInfo' + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: getAPIClientCertificateByKeyTypeAndAlias + + put: + tags: + - Client Certificates + summary: Update a Certificate of a Given Key Type + description: | + This operation can be used to update an uploaded certificate of a given key type. + parameters: + - name: alias + in: path + description: Alias for the certificate + required: true + schema: + maxLength: 30 + minLength: 1 + type: string + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + tier: + type: string + description: The tier of the certificate + responses: + 200: + description: | + OK. + The Certificate updated successfully. + headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_update + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: updateAPIClientCertificateByKeyTypeAndAlias + + delete: + tags: + - Client Certificates + summary: Delete a Certificate of a Given Key Type + description: | + This operation can be used to delete an uploaded certificate of a given key type. + parameters: + - name: alias + in: path + description: | + The alias of the certificate that should be deleted. + required: true + schema: + type: string + - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. + The Certificate deleted successfully. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: { } + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_create + - apim:api_manage + - apim:client_certificates_update + x-code-samples: + - lang: Curl + source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: deleteAPIClientCertificateByKeyTypeAndAlias + /apis/{apiId}/client-certificates/{alias}/content: get: + deprecated: true tags: - Client Certificates summary: Download a Certificate @@ -4875,6 +5160,57 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByAlias + /apis/{apiId}/client-certificates/{keyType}/{alias}/content: + get: + tags: + - Client Certificates + summary: Download a Certificate of Given Key Type + description: | + This operation can be used to download a certificate which matches the given alias and key type. + parameters: + - $ref: '#/components/parameters/apiId' + - name: alias + in: path + required: true + schema: + type: string + - name: keyType + in: path + description: | + The key type of the certificate that should be deleted. + required: true + schema: + type: string + responses: + 200: + description: | + OK. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: {} + 400: + $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + operationId: getAPIClientCertificateContentByKeyTypeAndAlias + + ###################################################### # The "Certificate Management" resource APIs ###################################################### @@ -11339,9 +11675,6 @@ components: tier: type: string example: Gold - keyType: - type: string - example: PRODUCTION description: Meta data of certificate LifecycleState: title: Lifecycle State diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java index b0ef195efde1..7a58d442b036 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/dto/ClientCertMetadataDTO.java @@ -26,7 +26,6 @@ public class ClientCertMetadataDTO { private String alias = null; private String apiId = null; private String tier = null; - private String keyType = null; /** **/ @@ -79,23 +78,6 @@ public void setTier(String tier) { this.tier = tier; } - /** - **/ - public ClientCertMetadataDTO keyType(String keyType) { - this.keyType = keyType; - return this; - } - - - @ApiModelProperty(example = "PRODUCTION", value = "") - @JsonProperty("keyType") - public String getKeyType() { - return keyType; - } - public void setKeyType(String keyType) { - this.keyType = keyType; - } - @Override public boolean equals(java.lang.Object o) { @@ -108,13 +90,12 @@ public boolean equals(java.lang.Object o) { ClientCertMetadataDTO clientCertMetadata = (ClientCertMetadataDTO) o; return Objects.equals(alias, clientCertMetadata.alias) && Objects.equals(apiId, clientCertMetadata.apiId) && - Objects.equals(tier, clientCertMetadata.tier) && - Objects.equals(keyType, clientCertMetadata.keyType); + Objects.equals(tier, clientCertMetadata.tier); } @Override public int hashCode() { - return Objects.hash(alias, apiId, tier, keyType); + return Objects.hash(alias, apiId, tier); } @Override @@ -125,7 +106,6 @@ public String toString() { sb.append(" alias: ").append(toIndentedString(alias)).append("\n"); sb.append(" apiId: ").append(toIndentedString(apiId)).append("\n"); sb.append(" tier: ").append(toIndentedString(tier)).append("\n"); - sb.append(" keyType: ").append(toIndentedString(keyType)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java index e965c8d3afb2..a6f131d9a40a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java @@ -165,11 +165,12 @@ public static CertificatesDTO getPaginatedCertificates( * @param clientCertificateDTOList Client certificate list. * @param limit Limit * @param offset Offset + * @param keyType Key type * @param query query * @return paginated list of client certificates. */ public static ClientCertificatesDTO getPaginatedClientCertificates( - List clientCertificateDTOList, int limit, int offset, String query) { + List clientCertificateDTOList, int limit, int offset, String keyType, String query) { if (log.isDebugEnabled()) { log.debug(String.format( "Filter the client certificates based on the pagination parameters, limit = %d and" + "offset = %d", @@ -195,20 +196,20 @@ public static ClientCertificatesDTO getPaginatedClientCertificates( clientCertMetadataDTO.setAlias(clientCertificateDTO.getAlias()); clientCertMetadataDTO.setApiId(clientCertificateDTO.getApiIdentifier().toString()); clientCertMetadataDTO.setTier(clientCertificateDTO.getTierName()); - clientCertMetadataDTO.setKeyType(clientCertificateDTO.getKeyType()); clientCertificateList.add(clientCertMetadataDTO); } Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, certCount); String paginatedPrevious = ""; String paginatedNext = ""; + //base path of pagination url -> deptecated api if (paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET) != null) { - paginatedPrevious = getCertificatesPaginatedURL(RestApiConstants.CLIENT_CERTS_GET_PAGINATED_URL, - paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), + paginatedPrevious = getClientCertificatesPaginatedURL(RestApiConstants.CLIENT_CERTS_GET_PAGINATED_URL, + keyType, paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_LIMIT), query); } if (paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET) != null) { - paginatedNext = getCertificatesPaginatedURL(RestApiConstants.CLIENT_CERTS_GET_PAGINATED_URL, - paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET), + paginatedNext = getClientCertificatesPaginatedURL(RestApiConstants.CLIENT_CERTS_GET_PAGINATED_URL, + keyType, paginatedParams.get(RestApiConstants.PAGINATION_NEXT_OFFSET), paginatedParams.get(RestApiConstants.PAGINATION_NEXT_LIMIT), query); } certificatesDTO.setCount(clientCertificateList.size()); @@ -232,6 +233,24 @@ private static String getCertificatesPaginatedURL(String paginatedURL, Integer o return paginatedURL; } + /** + * Get the paginated client certificate urls. + * + * @param keyType : The key type of the client certificate + * @param offset : The offset + * @param limit : The limit parameter. + * @param query : The provided query string + * @return : Certificates paginated URL + */ + private static String getClientCertificatesPaginatedURL(String paginatedURL, String keyType, Integer offset, Integer limit, + String query) { + paginatedURL = paginatedURL.replace(RestApiConstants.KEYTYPE_PARAM, keyType); + paginatedURL = paginatedURL.replace(RestApiConstants.LIMIT_PARAM, String.valueOf(limit)); + paginatedURL = paginatedURL.replace(RestApiConstants.OFFSET_PARAM, String.valueOf(offset)); + paginatedURL = paginatedURL.replace(RestApiConstants.QUERY_PARAM, query); + return paginatedURL; + } + /** * Generates the query string from the provided params. * @@ -258,22 +277,26 @@ public static String buildQueryString(String firstParamName, String firstParamVa } /** - * To pre validate client certificate given for an alias + * To pre validate client certificate given for an alias and key type * * @param alias Alias of the certificate. + * @param keyType Key type of the certificate * @param organization Identifier of the organization. * @return Client certificate * @throws APIManagementException API Management Exception. */ - public static ClientCertificateDTO preValidateClientCertificate(String alias, ApiTypeWrapper apiTypeWrapper, - String organization) throws APIManagementException { + public static ClientCertificateDTO preValidateClientCertificate(String alias, String keyType, + ApiTypeWrapper apiTypeWrapper, String organization) throws APIManagementException { if (StringUtils.isEmpty(alias)) { throw new APIManagementException("The alias cannot be empty", ExceptionCodes.ALIAS_CANNOT_BE_EMPTY); } + if (StringUtils.isEmpty(keyType)) { + throw new APIManagementException("The key type cannot be empty", ExceptionCodes.KEY_TYPE_CANNOT_BE_EMPTY); + } APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); ClientCertificateDTO clientCertificate = apiProvider - .getClientCertificate(alias, apiTypeWrapper, organization); + .getClientCertificate(alias, keyType, apiTypeWrapper, organization); if (clientCertificate == null) { if (log.isDebugEnabled()) { log.debug(String.format("Could not find a client certificate in truststore which belongs to " + diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java index 1f03274fd6f7..3186f5de47d2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java @@ -1023,10 +1023,12 @@ public static void addClientCertificatesToArchive(String archivePath, Identifier try { if (identifier instanceof APIProductIdentifier) { certificateMetadataDTOs = provider - .searchClientCertificates(tenantId, null, (APIProductIdentifier) identifier, organization); + .searchClientCertificates(tenantId, null, null, + (APIProductIdentifier) identifier, organization); } else { certificateMetadataDTOs = provider - .searchClientCertificates(tenantId, null, (APIIdentifier) identifier, organization); + .searchClientCertificates(tenantId, null, null, + (APIIdentifier) identifier, organization); } if (!certificateMetadataDTOs.isEmpty()) { String clientCertsDirectoryPath = diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java index 078f284e8d12..6364c7b7da97 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java @@ -872,15 +872,18 @@ public Response getAPIClientCertificateContentByAlias(String apiId, String alias @Override public Response getAPIClientCertificateContentByKeyTypeAndAlias(String apiId, String alias, String keyType, MessageContext messageContext) { - String organization = null; String certFileName = alias + ".crt"; + + //validate the input for key type + validateKeyType(keyType); + try { organization = RestApiUtil.getValidatedOrganization(messageContext); APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); ApiTypeWrapper apiTypeWrapper = apiProvider.getAPIorAPIProductByUUID(apiId, organization); ClientCertificateDTO clientCertificateDTO = CertificateRestApiUtils.preValidateClientCertificate(alias, - apiTypeWrapper, organization); + keyType, apiTypeWrapper, organization); if (clientCertificateDTO != null) { Object certificate = CertificateRestApiUtils .getDecodedCertificate(clientCertificateDTO.getCertificate()); @@ -909,6 +912,10 @@ public Response deleteAPIClientCertificateByAlias(String alias, String apiId, public Response deleteAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, MessageContext messageContext) { String organization = null; + + //validate the input for key type + validateKeyType(keyType); + try { organization = RestApiUtil.getValidatedOrganization(messageContext); //validate if api exists @@ -921,28 +928,30 @@ public Response deleteAPIClientCertificateByKeyTypeAndAlias(String keyType, Stri validateAPIOperationsPerLC(apiTypeWrapper.getStatus()); ClientCertificateDTO clientCertificateDTO = CertificateRestApiUtils.preValidateClientCertificate(alias, - apiTypeWrapper, organization); + keyType, apiTypeWrapper, organization); int responseCode = apiProvider - .deleteClientCertificate(RestApiCommonUtil.getLoggedInUsername(), apiTypeWrapper, alias); + .deleteClientCertificate(RestApiCommonUtil.getLoggedInUsername(), apiTypeWrapper, alias, keyType); if (responseCode == ResponseCode.SUCCESS.getResponseCode()) { if (log.isDebugEnabled()) { - log.debug(String.format("The client certificate which belongs to tenant : %s represented by the " - + "alias : %s is deleted successfully", organization, alias)); + log.debug(String.format("The client certificate of type %s which belongs to tenant : %s represented by the " + + "alias : %s is deleted successfully", keyType, organization, alias)); } - return Response.ok().entity("The certificate for alias '" + alias + "' deleted successfully.").build(); + return Response.ok().entity("The " + keyType + " type certificate for alias '" + alias + + "' deleted successfully.").build(); } else { if (log.isDebugEnabled()) { - log.debug(String.format("Failed to delete the client certificate which belongs to tenant : %s " - + "represented by the alias : %s.", organization, alias)); + log.debug(String.format("Failed to delete the %s type client certificate which belongs to tenant :" + + " %s represented by the alias : %s.", keyType, organization, alias)); } RestApiUtil.handleInternalServerError( - "Error while deleting the client certificate for alias '" + alias + "'.", log); + "Error while deleting the " + keyType + " type client certificate for alias '" + + alias + "'.", log); } } catch (APIManagementException e) { RestApiUtil.handleInternalServerError( - "Error while deleting the client certificate with alias " + alias + " for the tenant " - + organization, e, log); + "Error while deleting the " + keyType + " type client certificate with alias " + + alias + " for the tenant " + organization, e, log); } return null; } @@ -958,13 +967,17 @@ public Response getAPIClientCertificateByAlias(String alias, String apiId, public Response getAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, MessageContext messageContext) { String organization = null; + + //validate the input for key type + validateKeyType(keyType); + CertificateMgtUtils certificateMgtUtils = CertificateMgtUtils.getInstance(); try { organization = RestApiUtil.getValidatedOrganization(messageContext); APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); ApiTypeWrapper apiTypeWrapper = apiProvider.getAPIorAPIProductByUUID(apiId, organization); ClientCertificateDTO clientCertificateDTO = CertificateRestApiUtils.preValidateClientCertificate(alias, - apiTypeWrapper, organization); + keyType, apiTypeWrapper, organization); CertificateInformationDTO certificateInformationDTO = certificateMgtUtils .getCertificateInfo(clientCertificateDTO.getCertificate()); if (certificateInformationDTO != null) { @@ -995,6 +1008,9 @@ public Response updateAPIClientCertificateByAlias(String alias, String apiId, public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) { try { + //validate the input for key type + validateKeyType(keyType); + //validate if api exists CommonUtils.validateAPIExistence(apiId); @@ -1009,7 +1025,7 @@ public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, Stri String userName = RestApiCommonUtil.getLoggedInUsername(); int tenantId = APIUtil.getInternalOrganizationId(organization); ClientCertificateDTO clientCertificateDTO = CertificateRestApiUtils.preValidateClientCertificate(alias, - apiTypeWrapper, organization); + keyType, apiTypeWrapper, organization); if (certificateDetail != null) { contentDisposition = certificateDetail.getContentDisposition(); fileName = contentDisposition.getParameter(RestApiConstants.CONTENT_DISPOSITION_FILENAME); @@ -1020,10 +1036,6 @@ public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, Stri if (StringUtils.isEmpty(base64EncodedCert) && StringUtils.isEmpty(tier)) { return Response.ok().entity("Client Certificate is not updated for alias " + alias).build(); } - // to make the API consistent - if (StringUtils.isEmpty(keyType)) { - keyType = APIConstants.API_KEY_TYPE_PRODUCTION; - } int responseCode = apiProvider .updateClientCertificate(base64EncodedCert, alias, apiTypeWrapper, tier, keyType.toUpperCase(), tenantId, organization); @@ -1031,10 +1043,9 @@ public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, Stri if (ResponseCode.SUCCESS.getResponseCode() == responseCode) { ClientCertMetadataDTO clientCertMetadataDTO = new ClientCertMetadataDTO(); clientCertMetadataDTO.setAlias(alias); - clientCertMetadataDTO.setKeyType(keyType.toUpperCase()); clientCertMetadataDTO.setApiId(apiTypeWrapper.getUuid()); clientCertMetadataDTO.setTier(clientCertificateDTO.getTierName()); - URI updatedCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + "?alias=" + alias); + URI updatedCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + keyType + "?alias=" + alias); return Response.ok(updatedCertUri).entity(clientCertMetadataDTO).build(); } else if (ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode() == responseCode) { @@ -1076,24 +1087,29 @@ public Response getAPIClientCertificatesByKeyType(String keyType, String apiId, limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; List certificates = new ArrayList<>(); + + //validate the input for key type + validateKeyType(keyType); + String query = CertificateRestApiUtils.buildQueryString("alias", alias, "apiId", apiId); try { String organization = RestApiUtil.getValidatedOrganization(messageContext); int tenantId = APIUtil.getInternalOrganizationId(organization); APIProvider apiProvider = RestApiCommonUtil.getLoggedInUserProvider(); - int totalCount = apiProvider.getClientCertificateCount(tenantId); + int totalCount = apiProvider.getClientCertificateCount(tenantId, keyType); if (totalCount > 0) { APIIdentifier apiIdentifier = null; if (StringUtils.isNotEmpty(apiId)) { API api = apiProvider.getAPIbyUUID(apiId, organization); apiIdentifier = api.getId(); } - certificates = apiProvider.searchClientCertificates(tenantId, alias, apiIdentifier, organization); + certificates = apiProvider.searchClientCertificates(tenantId, alias, keyType, + apiIdentifier, organization); } ClientCertificatesDTO certificatesDTO = CertificateRestApiUtils - .getPaginatedClientCertificates(certificates, limit, offset, query); + .getPaginatedClientCertificates(certificates, limit, offset, keyType, query); PaginationDTO paginationDTO = new PaginationDTO(); paginationDTO.setLimit(limit); paginationDTO.setOffset(offset); @@ -1106,6 +1122,14 @@ public Response getAPIClientCertificatesByKeyType(String keyType, String apiId, return null; } + private void validateKeyType(String keyType) { + if (!(keyType.equalsIgnoreCase(APIConstants.API_KEY_TYPE_PRODUCTION) || + keyType.equalsIgnoreCase(APIConstants.API_KEY_TYPE_SANDBOX))) { + RestApiUtil.handleBadRequest("The key type is invalid. It should be either PRODUCTION or SANDBOX", + log); + } + } + @Override public Response addAPIClientCertificate(String apiId, InputStream certificateInputStream, Attachment certificateDetail, String alias, String tier, @@ -1123,6 +1147,10 @@ public Response addAPIClientCertificateOfGivenKeyType(String keyType, String api ContentDisposition contentDisposition = certificateDetail.getContentDisposition(); String organization = RestApiUtil.getValidatedOrganization(messageContext); String fileName = contentDisposition.getParameter(RestApiConstants.CONTENT_DISPOSITION_FILENAME); + + //validate the input for key type + validateKeyType(keyType); + if (StringUtils.isEmpty(alias) || StringUtils.isEmpty(apiId)) { RestApiUtil.handleBadRequest("The alias and/ or apiId should not be empty", log); } @@ -1130,10 +1158,6 @@ public Response addAPIClientCertificateOfGivenKeyType(String keyType, String api RestApiUtil.handleBadRequest( "Certificate addition failed. Proper Certificate file should be provided", log); } - // to make the API consistent - if (StringUtils.isBlank(keyType)) { - keyType = APIConstants.API_KEY_TYPE_PRODUCTION; - } //validate if api exists CommonUtils.validateAPIExistence(apiId); @@ -1155,8 +1179,7 @@ public Response addAPIClientCertificateOfGivenKeyType(String keyType, String api certificateDTO.setAlias(alias); certificateDTO.setApiId(apiId); certificateDTO.setTier(tier); - certificateDTO.setKeyType(keyType.toUpperCase()); - URI createdCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + "?alias=" + alias); + URI createdCertUri = new URI(RestApiConstants.CLIENT_CERTS_BASE_PATH + keyType + "?alias=" + alias); return Response.created(createdCertUri).entity(certificateDTO).build(); } else if (ResponseCode.INTERNAL_SERVER_ERROR.getResponseCode() == responseCode) { RestApiUtil.handleInternalServerError( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql index d4ecf1e2cdd9..e6bf8b139413 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql @@ -1893,7 +1893,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ) / CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql index e9904030fcfb..fdc06e18fe8e 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql @@ -1893,7 +1893,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ) / CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql index 62f3f9a3db41..d4e3a839ac21 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql @@ -2228,7 +2228,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( TIER_NAME VARCHAR(512), KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID), + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE ); diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql index e9eafa9c76c1..0d3fe3c4be3f 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql @@ -2772,7 +2772,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) )/ CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql index aec49edb4cae..01f3fa3a7a15 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql @@ -2239,7 +2239,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( TIER_NAME VARCHAR(512), KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID), + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE ); diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql index 56341ff12206..97769e017052 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql @@ -3224,7 +3224,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql index a8ff64669dd2..ddf1e38f0d47 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql @@ -3224,7 +3224,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql index e42e1dccc9d4..69f0c0829092 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql @@ -3198,7 +3198,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql index 4b68cf809a39..c22b2e025a80 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql @@ -2330,7 +2330,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) ); DROP TABLE IF EXISTS AM_APPLICATION_GROUP_MAPPING; From 953a3d8d904d5f4904b96d681b4c9b12e6031661 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Tue, 2 Jul 2024 17:15:45 +0530 Subject: [PATCH 07/10] Modify database queries and resource paths --- .../apimgt/api/gateway/GatewayAPIDTO.java | 34 +++-- .../apimgt/gateway/InMemoryAPIDeployer.java | 33 +++-- .../apimgt/gateway/internal/DataHolder.java | 32 +++-- .../gateway/service/APIGatewayAdmin.java | 22 +++- .../certificatemgt/CertificateManager.java | 1 + .../importexport/ImportExportConstants.java | 10 +- .../rest/api/common/RestApiConstants.java | 2 +- .../src/main/resources/publisher-api.yaml | 6 +- .../v1/common/TemplateBuilderUtil.java | 116 ++++++++++++------ .../v1/common/mappings/APIControllerUtil.java | 91 ++++++++++---- .../v1/common/mappings/ImportUtils.java | 34 +++-- .../apimgt/rest/api/publisher/v1/ApisApi.java | 12 +- .../publisher/v1/impl/ApisApiServiceImpl.java | 4 +- .../src/main/resources/publisher-api.yaml | 6 +- .../rest/api/util/RestApiConstants.java | 2 +- .../multi-dc/OGG/oracle/apimgt/tables.sql | 2 +- .../multi-dc/OGG/oracle/apimgt/tables_23c.sql | 2 +- .../SQLServer/mssql/apimgt/tables.sql | 2 +- .../src/main/resources/sql/db2.sql | 2 +- .../src/main/resources/sql/h2.sql | 2 +- .../src/main/resources/sql/mssql.sql | 2 +- .../src/main/resources/sql/mysql.sql | 2 +- .../src/main/resources/sql/mysql_cluster.sql | 2 +- .../src/main/resources/sql/oracle.sql | 2 +- .../src/main/resources/sql/oracle_23c.sql | 2 +- .../src/main/resources/sql/oracle_rac.sql | 2 +- .../src/main/resources/sql/postgresql.sql | 2 +- .../src/main/resources/sql/h2.sql | 2 +- 28 files changed, 289 insertions(+), 142 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java index 64b563665b88..988fab5fad7a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java @@ -44,8 +44,10 @@ public class GatewayAPIDTO implements Serializable { private String[] sequencesToBeRemove; private GatewayContentDTO[] localEntriesToBeAdd; private String[] localEntriesToBeRemove; - private GatewayContentDTO[] clientCertificatesToBeAdd; - private String[] clientCertificatesToBeRemove; + private GatewayContentDTO[] productionClientCertificatesToBeAdd; + private GatewayContentDTO[] sandboxClientCertificatesToBeAdd; + private String[] productionClientCertificatesToBeRemove; + private String[] sandboxClientCertificatesToBeRemove; private GatewayContentDTO[] endpointEntriesToBeAdd; private String[] endpointEntriesToBeRemove; private CredentialDto[] credentialsToBeAdd ; @@ -151,24 +153,36 @@ public void setLocalEntriesToBeRemove(String[] localEntriesToBeRemove) { this.localEntriesToBeRemove = localEntriesToBeRemove; } - public GatewayContentDTO[] getClientCertificatesToBeAdd() { + public GatewayContentDTO[] getProductionClientCertificatesToBeAdd() { + return productionClientCertificatesToBeAdd; + } - return clientCertificatesToBeAdd; + public void setProductionClientCertificatesToBeAdd(GatewayContentDTO[] productionClientCertificatesToBeAdd) { + this.productionClientCertificatesToBeAdd = productionClientCertificatesToBeAdd; } - public void setClientCertificatesToBeAdd(GatewayContentDTO[] clientCertificatesToBeAdd) { + public GatewayContentDTO[] getSandboxClientCertificatesToBeAdd() { + return sandboxClientCertificatesToBeAdd; + } - this.clientCertificatesToBeAdd = clientCertificatesToBeAdd; + public void setSandboxClientCertificatesToBeAdd(GatewayContentDTO[] sandboxClientCertificatesToBeAdd) { + this.sandboxClientCertificatesToBeAdd = sandboxClientCertificatesToBeAdd; } - public String[] getClientCertificatesToBeRemove() { + public String[] getProductionClientCertificatesToBeRemove() { + return productionClientCertificatesToBeRemove; + } - return clientCertificatesToBeRemove; + public void setProductionClientCertificatesToBeRemove(String[] productionClientCertificatesToBeRemove) { + this.productionClientCertificatesToBeRemove = productionClientCertificatesToBeRemove; } - public void setClientCertificatesToBeRemove(String[] clientCertificatesToBeRemove) { + public String[] getSandboxClientCertificatesToBeRemove() { + return sandboxClientCertificatesToBeRemove; + } - this.clientCertificatesToBeRemove = clientCertificatesToBeRemove; + public void setSandboxClientCertificatesToBeRemove(String[] sandboxClientCertificatesToBeRemove) { + this.sandboxClientCertificatesToBeRemove = sandboxClientCertificatesToBeRemove; } public GatewayContentDTO[] getEndpointEntriesToBeAdd() { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index dbb9d0ecac21..3c05f7ca3b39 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -355,7 +355,9 @@ private void unDeployAPI(APIGatewayAdmin apiGatewayAdmin, DeployAPIInGatewayEven GatewayUtils .addStringToList(gatewayEvent.getUuid(), gatewayAPIDTO.getLocalEntriesToBeRemove())); apiGatewayAdmin.unDeployAPI(gatewayAPIDTO); - DataHolder.getInstance().getApiToCertificatesMap().remove(gatewayEvent.getUuid()); + DataHolder.getInstance().getApiToProductionCertificatesMap().remove(gatewayEvent.getUuid()); + DataHolder.getInstance().getApiToSandboxCertificatesMap().remove(gatewayEvent.getUuid()); + DataHolder.getInstance().removeKeyManagerToAPIMapping(gatewayAPIDTO.getApiId()); } } @@ -419,13 +421,21 @@ private void addDeployedCertificatesToAPIAssociation(GatewayAPIDTO gatewayAPIDTO if (gatewayAPIDTO != null) { String apiId = gatewayAPIDTO.getApiId(); - List aliasList = new ArrayList<>(); - if (gatewayAPIDTO.getClientCertificatesToBeAdd() != null) { - for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getClientCertificatesToBeAdd()) { - aliasList.add(gatewayContentDTO.getName()); + List productionAliasList = new ArrayList<>(); + if (gatewayAPIDTO.getProductionClientCertificatesToBeAdd() != null) { + for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getProductionClientCertificatesToBeAdd()) { + productionAliasList.add(gatewayContentDTO.getName()); + } + } + DataHolder.getInstance().addApiToProductionAliasList(apiId, productionAliasList); + + List sandboxAliasList = new ArrayList<>(); + if (gatewayAPIDTO.getSandboxClientCertificatesToBeAdd() != null) { + for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getSandboxClientCertificatesToBeAdd()) { + sandboxAliasList.add(gatewayContentDTO.getName()); } } - DataHolder.getInstance().addApiToAliasList(apiId, aliasList); + DataHolder.getInstance().addApiToSandboxAliasList(apiId, sandboxAliasList); } } @@ -450,9 +460,14 @@ private void setClientCertificatesToRemoveIntoGatewayDTO(GatewayAPIDTO gatewayDT if (gatewayDTO != null) { if (StringUtils.isNotEmpty(gatewayDTO.getApiId())) { - List certificateAliasListForAPI = - DataHolder.getInstance().getCertificateAliasListForAPI(gatewayDTO.getApiId()); - gatewayDTO.setClientCertificatesToBeRemove(certificateAliasListForAPI.toArray(new String[0])); + List productionCertificateAliasListForAPI = + DataHolder.getInstance().getProductionCertificateAliasListForAPI(gatewayDTO.getApiId()); + gatewayDTO.setProductionClientCertificatesToBeRemove(productionCertificateAliasListForAPI.toArray(new String[0])); + } + if (StringUtils.isNotEmpty(gatewayDTO.getApiId())) { + List sandboxCertificateAliasListForAPI = + DataHolder.getInstance().getSandboxCertificateAliasListForAPI(gatewayDTO.getApiId()); + gatewayDTO.setSandboxClientCertificatesToBeRemove(sandboxCertificateAliasListForAPI.toArray(new String[0])); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java index cff90588df0c..3d1dda6d4bba 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java @@ -39,7 +39,8 @@ public class DataHolder { private static final Log log = LogFactory.getLog(DataHolder.class); private static final DataHolder Instance = new DataHolder(); - private Map> apiToCertificatesMap = new HashMap(); + private Map> apiToProductionCertificatesMap = new HashMap(); + private Map> apiToSandboxCertificatesMap = new HashMap(); private Map googleAnalyticsConfigMap = new HashMap<>(); private Map apiToGraphQLSchemaDTOMap = new HashMap<>(); private Map> apiToKeyManagersMap = new HashMap<>(); @@ -51,29 +52,42 @@ private DataHolder() { initializeTenantDeploymentStatusMap(); } - public Map> getApiToCertificatesMap() { + public Map> getApiToProductionCertificatesMap() { + return apiToProductionCertificatesMap; + } - return apiToCertificatesMap; + public void setApiToProductionCertificatesMap(Map> apiToProductionCertificatesMap) { + this.apiToProductionCertificatesMap = apiToProductionCertificatesMap; } - public void setApiToCertificatesMap(Map> apiToCertificatesMap) { + public Map> getApiToSandboxCertificatesMap() { + return apiToSandboxCertificatesMap; + } - this.apiToCertificatesMap = apiToCertificatesMap; + public void setApiToSandboxCertificatesMap(Map> apiToSandboxCertificatesMap) { + this.apiToSandboxCertificatesMap = apiToSandboxCertificatesMap; } public static DataHolder getInstance() { return Instance; } + public void addApiToProductionAliasList(String apiId, List aliasList) { - public void addApiToAliasList(String apiId, List aliasList) { + apiToProductionCertificatesMap.put(apiId, aliasList); + } + public void addApiToSandboxAliasList(String apiId, List aliasList) { - apiToCertificatesMap.put(apiId, aliasList); + apiToSandboxCertificatesMap.put(apiId, aliasList); } - public List getCertificateAliasListForAPI(String apiId) { + public List getProductionCertificateAliasListForAPI(String apiId) { + + return apiToProductionCertificatesMap.getOrDefault(apiId, Collections.emptyList()); + } + public List getSandboxCertificateAliasListForAPI(String apiId) { - return apiToCertificatesMap.getOrDefault(apiId, Collections.emptyList()); + return apiToSandboxCertificatesMap.getOrDefault(apiId, Collections.emptyList()); } public void addGoogleAnalyticsConfig(String tenantDomain, String config) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java index 83c59df1de7e..3f42784623dc 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java @@ -666,9 +666,16 @@ public boolean deployAPI(GatewayAPIDTO gatewayAPIDTO) throws AxisFault { } // Add Client Certificates - if (gatewayAPIDTO.getClientCertificatesToBeAdd() != null) { + if (gatewayAPIDTO.getProductionClientCertificatesToBeAdd() != null) { synchronized (certificateManager) { - for (GatewayContentDTO certificate : gatewayAPIDTO.getClientCertificatesToBeAdd()) { + for (GatewayContentDTO certificate : gatewayAPIDTO.getProductionClientCertificatesToBeAdd()) { + certificateManager.addClientCertificateToGateway(certificate.getContent(), certificate.getName()); + } + } + } + if (gatewayAPIDTO.getSandboxClientCertificatesToBeAdd() != null) { + synchronized (certificateManager) { + for (GatewayContentDTO certificate : gatewayAPIDTO.getSandboxClientCertificatesToBeAdd()) { certificateManager.addClientCertificateToGateway(certificate.getContent(), certificate.getName()); } } @@ -810,9 +817,16 @@ private void unDeployAPI(SequenceAdminServiceProxy sequenceAdminServiceProxy, } // Remove clientCertificates - if (gatewayAPIDTO.getClientCertificatesToBeRemove() != null) { + if (gatewayAPIDTO.getProductionClientCertificatesToBeRemove() != null) { + synchronized (certificateManager) { + for (String alias : gatewayAPIDTO.getProductionClientCertificatesToBeRemove()) { + certificateManager.deleteClientCertificateFromGateway(alias); + } + } + } + if (gatewayAPIDTO.getSandboxClientCertificatesToBeRemove() != null) { synchronized (certificateManager) { - for (String alias : gatewayAPIDTO.getClientCertificatesToBeRemove()) { + for (String alias : gatewayAPIDTO.getSandboxClientCertificatesToBeRemove()) { certificateManager.deleteClientCertificateFromGateway(alias); } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java index b8ebbe6f0982..7d8f1af45dc9 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/certificatemgt/CertificateManager.java @@ -203,6 +203,7 @@ ResponseCode deleteClientCertificateFromParentNode(Identifier apiIdentifier, Str * Method to add client certificate to gateway nodes. * * @param certificate : The Base64 encoded certificate string. + * @param keyType : Key type of the certificate. * @param alias : Certificate alias. * @return : True if the certificate is added to gateway node successfully. False otherwise. */ diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java index 778b058c2424..0beb53f2baa5 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/importexport/ImportExportConstants.java @@ -18,6 +18,8 @@ package org.wso2.carbon.apimgt.impl.importexport; +import org.wso2.carbon.apimgt.impl.APIConstants; + import java.io.File; import java.util.HashMap; import java.util.Map; @@ -287,8 +289,12 @@ public final class ImportExportConstants { public static final String CLIENT_CERTIFICATES_DIRECTORY_PATH = File.separator + "Client-certificates"; public static final String ENDPOINT_CERTIFICATES_META_DATA_FILE_PATH = ENDPOINT_CERTIFICATES_DIRECTORY_PATH + File.separator + "endpoint_certificates"; - public static final String CLIENT_CERTIFICATES_META_DATA_FILE_PATH = - CLIENT_CERTIFICATES_DIRECTORY_PATH + File.separator + "client_certificates"; + public static final String PRODUCTION_CLIENT_CERTIFICATES_META_DATA_FILE_PATH = + CLIENT_CERTIFICATES_DIRECTORY_PATH + File.separator + APIConstants.API_KEY_TYPE_PRODUCTION + + File.separator + "client_certificates"; + public static final String SANDBOX_CLIENT_CERTIFICATES_META_DATA_FILE_PATH = + CLIENT_CERTIFICATES_DIRECTORY_PATH + File.separator + APIConstants.API_KEY_TYPE_SANDBOX + + File.separator + "client_certificates"; //Deployment directory related constants public static final String DEPLOYMENT_DIRECTORY_NAME= "Deployment"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java index 2d39e73d6200..b9ee6a70056d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java @@ -303,7 +303,7 @@ public final class RestApiConstants { public static final String MIGRATION_MODE = "migrationMode"; public static final String CERTS_BASE_PATH = "/certificates"; - public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/"; + public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/v2/"; public static final String CERTS_GET_PAGINATED_URL = CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String CLIENT_CERTS_GET_PAGINATED_URL = diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index 2cd878390958..1f4536a16f6a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4669,7 +4669,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate - /apis/{apiId}/client-certificates/{keyType}: + /apis/{apiId}/client-certificates/v2/{keyType}: parameters: - in: path name: keyType @@ -4951,7 +4951,7 @@ paths: source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/{keyType}/{alias}: + /apis/{apiId}/client-certificates/v2/{keyType}/{alias}: parameters: - in: path name: keyType @@ -5160,7 +5160,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByAlias - /apis/{apiId}/client-certificates/{keyType}/{alias}/content: + /apis/{apiId}/client-certificates/v2/{keyType}/{alias}/content: get: tags: - Client Certificates diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java index ca7e89fe370f..630a1e0947c3 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java @@ -90,7 +90,8 @@ public class TemplateBuilderUtil { private static final Log log = LogFactory.getLog(TemplateBuilderUtil.class); public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenantDomain, - List clientCertificateDTOS, + List clientCertificateDTOSProduction, + List clientCertificateDTOSSandbox, List soapToRestInMediationDtos, List soapToRestMediationDtos) throws APIManagementException { @@ -179,17 +180,26 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenan } vtb.addHandler("org.wso2.carbon.apimgt.gateway.handlers.common.APIStatusHandler", Collections.emptyMap()); } - Map clientCertificateObject = null; + Map clientCertificateObject = new HashMap<>(); CertificateMgtUtils certificateMgtUtils = CertificateMgtUtils.getInstance(); - if (clientCertificateDTOS != null) { - clientCertificateObject = new HashMap<>(); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + if (clientCertificateDTOSProduction != null) { + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOSProduction) { /* appending the values without using a data structure to store them separately to avoid conflicts when reading from certificatesDetails string at MutualSSLAuthenticator */ clientCertificateObject.put(certificateMgtUtils .getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) - .concat(clientCertificateDTO.getKeyType())); + .concat(APIConstants.API_KEY_TYPE_PRODUCTION)); + } + } + if (clientCertificateDTOSSandbox != null) { + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOSSandbox) { + /* appending the values without using a data structure to store them separately to avoid conflicts + when reading from certificatesDetails string at MutualSSLAuthenticator */ + clientCertificateObject.put(certificateMgtUtils + .getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), + clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) + .concat(APIConstants.API_KEY_TYPE_SANDBOX)); } } @@ -204,7 +214,7 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenan String apiLevelPolicy = api.getApiLevelPolicy(); authProperties.put(APIConstants.API_SECURITY, apiSecurity); authProperties.put(APIConstants.API_LEVEL_POLICY, apiLevelPolicy); - if (clientCertificateObject != null) { + if (!clientCertificateObject.isEmpty()) { authProperties.put(APIConstants.CERTIFICATE_INFORMATION, clientCertificateObject.toString()); } //Get RemoveHeaderFromOutMessage from tenant registry or api-manager.xml @@ -282,8 +292,8 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenan } public static APITemplateBuilderImpl getAPITemplateBuilder(APIProduct apiProduct, String tenantDomain, - List clientCertificateDTOS, - Map associatedAPIMap) + List clientCertificateDTOSProduction, + List clientCertificateDTOSSandbox, Map associatedAPIMap) throws APIManagementException { int tenantId = APIUtil.getTenantIdFromTenantDomain(tenantDomain); @@ -367,18 +377,26 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(APIProduct apiProduct } vtb.addHandler("org.wso2.carbon.apimgt.gateway.handlers.common.APIStatusHandler", Collections.emptyMap()); - Map clientCertificateObject = null; + Map clientCertificateObject = new HashMap<>(); CertificateMgtUtils certificateMgtUtils = CertificateMgtUtils.getInstance(); - if (clientCertificateDTOS != null) { - clientCertificateObject = new HashMap<>(); - for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOS) { + if (clientCertificateDTOSProduction != null) { + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOSProduction) { /* appending the values without using a data structure to store them separately to avoid conflicts when reading from certificatesDetails string at MutualSSLAuthenticator */ clientCertificateObject.put(certificateMgtUtils. getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) - .concat(clientCertificateDTO.getKeyType())); - + .concat(APIConstants.API_KEY_TYPE_PRODUCTION)); + } + } + if (clientCertificateDTOSSandbox != null) { + for (ClientCertificateDTO clientCertificateDTO : clientCertificateDTOSSandbox) { + /* appending the values without using a data structure to store them separately to avoid conflicts + when reading from certificatesDetails string at MutualSSLAuthenticator */ + clientCertificateObject.put(certificateMgtUtils. + getUniqueIdentifierOfCertificate(clientCertificateDTO.getCertificate()), + clientCertificateDTO.getTierName().concat(APIConstants.DELEM_COLON) + .concat(APIConstants.API_KEY_TYPE_SANDBOX)); } } @@ -393,7 +411,7 @@ public static APITemplateBuilderImpl getAPITemplateBuilder(APIProduct apiProduct String apiLevelPolicy = apiProduct.getProductLevelPolicy(); authProperties.put(APIConstants.API_SECURITY, apiSecurity); authProperties.put(APIConstants.API_LEVEL_POLICY, apiLevelPolicy); - if (clientCertificateObject != null) { + if (!clientCertificateObject.isEmpty()) { authProperties.put(APIConstants.CERTIFICATE_INFORMATION, clientCertificateObject.toString()); } @@ -460,8 +478,10 @@ public static GatewayAPIDTO retrieveGatewayAPIDto(API api, Environment environme APIDTO apidto, String extractedFolderPath) throws APIManagementException, XMLStreamException, APITemplateException { - List clientCertificatesDTOList = - ImportUtils.retrieveClientCertificates(extractedFolderPath); + List clientCertificatesDTOListProduction = + ImportUtils.retrieveClientCertificates(extractedFolderPath, APIConstants.API_KEY_TYPE_PRODUCTION); + List clientCertificatesDTOListSandbox = + ImportUtils.retrieveClientCertificates(extractedFolderPath, APIConstants.API_KEY_TYPE_SANDBOX); List soapToRestInMediationDtoList = ImportUtils.retrieveSoapToRestFlowMediations(extractedFolderPath, ImportUtils.IN); List soapToRestOutMediationDtoList = @@ -472,10 +492,10 @@ public static GatewayAPIDTO retrieveGatewayAPIDto(API api, Environment environme JSONObject modifiedProperties = getModifiedProperties(originalProperties); api.setAdditionalProperties(modifiedProperties); APITemplateBuilder apiTemplateBuilder = TemplateBuilderUtil - .getAPITemplateBuilder(api, tenantDomain, clientCertificatesDTOList, soapToRestInMediationDtoList, - soapToRestOutMediationDtoList); + .getAPITemplateBuilder(api, tenantDomain, clientCertificatesDTOListProduction, + clientCertificatesDTOListSandbox, soapToRestInMediationDtoList, soapToRestOutMediationDtoList); GatewayAPIDTO gatewaAPIDto = createAPIGatewayDTOtoPublishAPI(environment, api, apiTemplateBuilder, tenantDomain, - extractedFolderPath, apidto, clientCertificatesDTOList); + extractedFolderPath, apidto, clientCertificatesDTOListProduction, clientCertificatesDTOListSandbox); // Reset the additional properties to the original values if (originalProperties != null) { api.setAdditionalProperties(originalProperties); @@ -523,8 +543,10 @@ public static GatewayAPIDTO retrieveGatewayAPIDto(APIProduct apiProduct, Environ String tenantDomain, String extractedFolderPath) throws APIManagementException, XMLStreamException, APITemplateException { - List clientCertificatesDTOList = - ImportUtils.retrieveClientCertificates(extractedFolderPath); + List clientCertificatesDTOListProduction = + ImportUtils.retrieveClientCertificates(extractedFolderPath, APIConstants.API_KEY_TYPE_PRODUCTION); + List clientCertificatesDTOListSandbox = + ImportUtils.retrieveClientCertificates(extractedFolderPath, APIConstants.API_KEY_TYPE_SANDBOX); Map apidtoMap = retrieveAssociatedApis(extractedFolderPath); Map associatedAPIsMap = convertAPIIdToDto(apidtoMap.values()); for (APIProductResource productResource : apiProduct.getProductResources()) { @@ -562,16 +584,16 @@ public static GatewayAPIDTO retrieveGatewayAPIDto(APIProduct apiProduct, Environ } APITemplateBuilder apiTemplateBuilder = - TemplateBuilderUtil.getAPITemplateBuilder(apiProduct, tenantDomain, clientCertificatesDTOList, - convertAPIIdToDto(associatedAPIsMap.values())); + TemplateBuilderUtil.getAPITemplateBuilder(apiProduct, tenantDomain, clientCertificatesDTOListProduction, + clientCertificatesDTOListSandbox, convertAPIIdToDto(associatedAPIsMap.values())); return createAPIGatewayDTOtoPublishAPI(environment, apiProduct, apiTemplateBuilder, tenantDomain, - apidtoMap, clientCertificatesDTOList); + apidtoMap, clientCertificatesDTOListProduction, clientCertificatesDTOListSandbox); } private static GatewayAPIDTO createAPIGatewayDTOtoPublishAPI(Environment environment, APIProduct apiProduct, - APITemplateBuilder builder, String tenantDomain, - Map associatedAPIsMap, - List clientCertificatesDTOList) + APITemplateBuilder builder, String tenantDomain, Map associatedAPIsMap, + List clientCertificatesDTOListProduction, + List clientCertificatesDTOListSandbox) throws APITemplateException, XMLStreamException, APIManagementException { APIProductIdentifier id = apiProduct.getId(); @@ -594,7 +616,8 @@ private static GatewayAPIDTO createAPIGatewayDTOtoPublishAPI(Environment environ + ""); productAPIDto.setLocalEntriesToBeAdd(addGatewayContentToList(productLocalEntry, productAPIDto.getLocalEntriesToBeAdd())); - setClientCertificatesToBeAdded(tenantDomain, productAPIDto, clientCertificatesDTOList); + setClientCertificatesToBeAdded(tenantDomain, productAPIDto, clientCertificatesDTOListProduction, + clientCertificatesDTOListSandbox); for (Map.Entry apidtoEntry : associatedAPIsMap.entrySet()) { String apiExtractedPath = apidtoEntry.getKey(); APIDTO apidto = apidtoEntry.getValue(); @@ -653,7 +676,8 @@ private static void setCustomSequencesToBeAdded(APIProduct apiProduct, API api, private static GatewayAPIDTO createAPIGatewayDTOtoPublishAPI(Environment environment, API api, APITemplateBuilder builder, String tenantDomain, String extractedPath, APIDTO apidto, - List clientCertificatesDTOList) + List productionClientCertificatesDTOList, + List sandboxClientCertificatesDTOList) throws APIManagementException, APITemplateException, XMLStreamException { GatewayAPIDTO gatewayAPIDTO = new GatewayAPIDTO(); @@ -754,7 +778,8 @@ private static GatewayAPIDTO createAPIGatewayDTOtoPublishAPI(Environment environ GatewayUtils.setCustomSequencesToBeRemoved(api, gatewayAPIDTO); setAPIFaultSequencesToBeAdded(api, gatewayAPIDTO, extractedPath, apidto); setCustomSequencesToBeAdded(api, gatewayAPIDTO, extractedPath, apidto); - setClientCertificatesToBeAdded(tenantDomain, gatewayAPIDTO, clientCertificatesDTOList); + setClientCertificatesToBeAdded(tenantDomain, gatewayAPIDTO, productionClientCertificatesDTOList, + sandboxClientCertificatesDTOList); boolean isWsApi = APIConstants.APITransportType.WS.toString().equals(api.getType()); if (isWsApi) { @@ -904,20 +929,33 @@ private static void setAPIFaultSequencesToBeAdded(API api, GatewayAPIDTO gateway * To deploy client certificate in given API environment. * * @param tenantDomain Tenant domain. - * @param clientCertificatesDTOList + * @param productionClientCertificatesDTOList + * @param sandboxClientCertificatesDTOList */ private static void setClientCertificatesToBeAdded(String tenantDomain, GatewayAPIDTO gatewayAPIDTO, - List clientCertificatesDTOList) { + List productionClientCertificatesDTOList, + List sandboxClientCertificatesDTOList) { int tenantId = APIUtil.getTenantIdFromTenantDomain(tenantDomain); - if (clientCertificatesDTOList != null) { - for (ClientCertificateDTO clientCertificateDTO : clientCertificatesDTOList) { + if (productionClientCertificatesDTOList != null) { + for (ClientCertificateDTO clientCertificateDTO : productionClientCertificatesDTOList) { + GatewayContentDTO clientCertificate = new GatewayContentDTO(); + clientCertificate.setName(APIConstants.API_KEY_TYPE_PRODUCTION + "_" + clientCertificateDTO.getAlias() + + "_" + tenantId); + clientCertificate.setContent(clientCertificateDTO.getCertificate()); + gatewayAPIDTO.setProductionClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, + gatewayAPIDTO.getProductionClientCertificatesToBeAdd())); + } + } + if (sandboxClientCertificatesDTOList != null) { + for (ClientCertificateDTO clientCertificateDTO : sandboxClientCertificatesDTOList) { GatewayContentDTO clientCertificate = new GatewayContentDTO(); - clientCertificate.setName(clientCertificateDTO.getAlias() + "_" + tenantId); + clientCertificate.setName(APIConstants.API_KEY_TYPE_SANDBOX + "_" + clientCertificateDTO.getAlias() + + "_" + tenantId); clientCertificate.setContent(clientCertificateDTO.getCertificate()); - gatewayAPIDTO.setClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, - gatewayAPIDTO.getClientCertificatesToBeAdd())); + gatewayAPIDTO.setSandboxClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, + gatewayAPIDTO.getSandboxClientCertificatesToBeAdd())); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java index 0b20f1bd49dc..94a06c4c2d40 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java @@ -983,7 +983,8 @@ private static void handleClientCertificates(JsonArray certificates, Identifier APIIdentifier apiIdentifier = new APIIdentifier(identifier.getProviderName(), identifier.getName(), identifier.getVersion()); - List certs = new ArrayList<>(); + List productionCerts = new ArrayList<>(); + List sandboxCerts = new ArrayList<>(); for (JsonElement certificate : certificates) { JsonObject certObject = certificate.getAsJsonObject(); @@ -991,52 +992,88 @@ private static void handleClientCertificates(JsonArray certificates, Identifier ClientCertificateDTO cert = new ClientCertificateDTO(); cert.setApiIdentifier(apiIdentifier); cert.setAlias(alias); - cert.setKeyType(certObject.get(ImportExportConstants.KEY_TYPE_JSON_KEY).getAsString()); cert.setTierName(certObject.get(ImportExportConstants.CERTIFICATE_TIER_NAME_PROPERTY).getAsString()); String certName = certObject.get(ImportExportConstants.CERTIFICATE_PATH_PROPERTY).getAsString(); cert.setCertificate(certName); - certs.add(cert); - //check and create a directory - String clientCertificatesDirectory = - pathToArchive + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY_PATH; - if (!CommonUtil.checkFileExistence(clientCertificatesDirectory)) { - try { - CommonUtil.createDirectory(clientCertificatesDirectory); - } catch (APIImportExportException e) { - throw new APIManagementException(e); + String clientCertificatesDirectory; + String userCertificatesTempDirectoryPath = pathToArchive + ImportExportConstants.DEPLOYMENT_DIRECTORY + + ImportExportConstants.CERTIFICATE_DIRECTORY + File.separator; + String userCertificatesTempDirectory; + + if (certObject.get(ImportExportConstants.KEY_TYPE_JSON_KEY).getAsString(). + equalsIgnoreCase(APIConstants.API_KEY_TYPE_SANDBOX)) { + + sandboxCerts.add(cert); + clientCertificatesDirectory = pathToArchive + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY_PATH + + File.separator + APIConstants.API_KEY_TYPE_SANDBOX; + if (!CommonUtil.checkFileExistence(clientCertificatesDirectory)) { + try { + CommonUtil.createDirectory(clientCertificatesDirectory); + } catch (APIImportExportException e) { + throw new APIManagementException(e); + } + } + + //copy certs file from certificates + userCertificatesTempDirectory = userCertificatesTempDirectoryPath + APIConstants.API_KEY_TYPE_SANDBOX; + + } else { + productionCerts.add(cert); + clientCertificatesDirectory = pathToArchive + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY_PATH + + File.separator + APIConstants.API_KEY_TYPE_PRODUCTION; + if (!CommonUtil.checkFileExistence(clientCertificatesDirectory)) { + try { + CommonUtil.createDirectory(clientCertificatesDirectory); + } catch (APIImportExportException e) { + throw new APIManagementException(e); + } } + //copy certs file from certificates + userCertificatesTempDirectory = userCertificatesTempDirectoryPath + APIConstants.API_KEY_TYPE_PRODUCTION; } - //copy certs file from certificates - String userCertificatesTempDirectory = pathToArchive + ImportExportConstants.DEPLOYMENT_DIRECTORY - + ImportExportConstants.CERTIFICATE_DIRECTORY; + String sourcePath = userCertificatesTempDirectory + File.separator + certName; String destinationPath = clientCertificatesDirectory + File.separator + certName; if (Files.notExists(Paths.get(sourcePath))) { String errorMessage = - "The mentioned certificate file " + certName + " is not in the certificates directory"; + "The mentioned certificate file " + certName + "of" + certObject.get(ImportExportConstants + .KEY_TYPE_JSON_KEY).getAsString() + " key type is not in the " + "certificates directory"; throw new APIManagementException(errorMessage, ExceptionCodes.ERROR_READING_PARAMS_FILE); } CommonUtil.moveFile(sourcePath, destinationPath); } + JsonElement productionJsonElement = new Gson().toJsonTree(productionCerts); + JsonElement sandboxJsonElement = new Gson().toJsonTree(sandboxCerts); - JsonElement jsonElement = new Gson().toJsonTree(certs); + String metadataFilePath; //generate meta-data yaml file - String metadataFilePath = pathToArchive + ImportExportConstants.CLIENT_CERTIFICATES_META_DATA_FILE_PATH; + metadataFilePath = pathToArchive + ImportExportConstants.PRODUCTION_CLIENT_CERTIFICATES_META_DATA_FILE_PATH; try { - if (CommonUtil.checkFileExistence(metadataFilePath + ImportExportConstants.YAML_EXTENSION)) { - File oldFile = new File(metadataFilePath + ImportExportConstants.YAML_EXTENSION); - oldFile.delete(); - } - if (CommonUtil.checkFileExistence(metadataFilePath + ImportExportConstants.JSON_EXTENSION)) { - File oldFile = new File(metadataFilePath + ImportExportConstants.JSON_EXTENSION); - oldFile.delete(); - } - CommonUtil.writeDtoToFile(metadataFilePath, ExportFormat.JSON, - ImportExportConstants.TYPE_CLIENT_CERTIFICATES, jsonElement); + verifyExistenceOfClientCertAndWriteToMetadataFile(metadataFilePath, productionJsonElement); } catch (APIImportExportException e) { throw new APIManagementException(e); } + metadataFilePath = pathToArchive + ImportExportConstants.SANDBOX_CLIENT_CERTIFICATES_META_DATA_FILE_PATH; + try { + verifyExistenceOfClientCertAndWriteToMetadataFile(metadataFilePath, sandboxJsonElement); + } catch (APIImportExportException e) { + throw new APIManagementException(e); + } + } + + private static void verifyExistenceOfClientCertAndWriteToMetadataFile(String metadataFilePath, JsonElement jsonElement) + throws APIImportExportException, IOException { + if (CommonUtil.checkFileExistence(metadataFilePath + ImportExportConstants.YAML_EXTENSION)) { + File oldFile = new File(metadataFilePath + ImportExportConstants.YAML_EXTENSION); + oldFile.delete(); + } + if (CommonUtil.checkFileExistence(metadataFilePath + ImportExportConstants.JSON_EXTENSION)) { + File oldFile = new File(metadataFilePath + ImportExportConstants.JSON_EXTENSION); + oldFile.delete(); + } + CommonUtil.writeDtoToFile(metadataFilePath, ExportFormat.JSON, + ImportExportConstants.TYPE_CLIENT_CERTIFICATES, jsonElement); } /** diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java index 6c19ea325cfe..4f93c417ab96 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ImportUtils.java @@ -415,8 +415,10 @@ public static ImportedAPIDTO importApi(String extractedFolderPath, APIDTO import if (log.isDebugEnabled()) { log.debug("Mutual SSL enabled. Importing client certificates."); } - addClientCertificates(extractedFolderPath, apiProvider, new ApiTypeWrapper(importedApi), organization, - overwrite, tenantId); + addClientCertificates(extractedFolderPath, apiProvider, new ApiTypeWrapper(importedApi), + APIConstants.API_KEY_TYPE_PRODUCTION, organization, overwrite, tenantId); + addClientCertificates(extractedFolderPath, apiProvider, new ApiTypeWrapper(importedApi), + APIConstants.API_KEY_TYPE_SANDBOX, organization, overwrite, tenantId); } // Change API lifecycle if state transition is required @@ -2249,24 +2251,24 @@ private static void updateAPIWithCertificate(JsonElement certificate, APIProvide * * @param pathToArchive Location of the extracted folder of the API * @param apiProvider API Provider + * @param keyType Key type of the certificate * @param organization Identifier of the organization * @throws APIImportExportException */ private static void addClientCertificates(String pathToArchive, APIProvider apiProvider, - ApiTypeWrapper apiTypeWrapper, String organization, boolean isOverwrite - , int tenantId) - throws APIManagementException { + ApiTypeWrapper apiTypeWrapper, String keyType, String organization, + boolean isOverwrite, int tenantId) throws APIManagementException { try { Identifier apiIdentifier = apiTypeWrapper.getId(); - List certificateMetadataDTOS = retrieveClientCertificates(pathToArchive); + List certificateMetadataDTOS = retrieveClientCertificates(pathToArchive, keyType); for (ClientCertificateDTO certDTO : certificateMetadataDTOS) { if (ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode() == (apiProvider.addClientCertificate( APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName()), apiTypeWrapper, - certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(), certDTO.getKeyType(), + certDTO.getCertificate(), certDTO.getAlias(), certDTO.getTierName(), keyType, organization)) && isOverwrite) { apiProvider.updateClientCertificate(certDTO.getCertificate(), certDTO.getAlias(), apiTypeWrapper, - certDTO.getTierName(), certDTO.getKeyType(), tenantId, organization); + certDTO.getTierName(), keyType, tenantId, organization); } } } catch (APIManagementException e) { @@ -2274,12 +2276,16 @@ private static void addClientCertificates(String pathToArchive, APIProvider apiP } } - public static List retrieveClientCertificates(String pathToArchive) + public static List retrieveClientCertificates(String pathToArchive, String keyType) throws APIManagementException { String jsonContent = null; - String pathToClientCertificatesDirectory = - pathToArchive + File.separator + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY; + /* + since the certificate file is named by the alias, this also need to store in two separate directories + considering the key type, to support same alias for production and sandbox + */ + String pathToClientCertificatesDirectory = pathToArchive + File.separator + + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY + File.separator + keyType; String pathToYamlFile = pathToClientCertificatesDirectory + ImportExportConstants.CLIENT_CERTIFICATE_FILE + ImportExportConstants.YAML_EXTENSION; String pathToJsonFile = pathToClientCertificatesDirectory + ImportExportConstants.CLIENT_CERTIFICATE_FILE @@ -2611,8 +2617,10 @@ public static APIProduct importApiProduct(String extractedFolderPath, Boolean pr log.debug("Mutual SSL enabled. Importing client certificates."); } int tenantId = APIUtil.getTenantId(RestApiCommonUtil.getLoggedInUsername()); - addClientCertificates(extractedFolderPath, apiProvider, apiTypeWrapperWithUpdatedApiProduct, organization, - overwriteAPIProduct, tenantId); + addClientCertificates(extractedFolderPath, apiProvider, apiTypeWrapperWithUpdatedApiProduct, + APIConstants.API_KEY_TYPE_PRODUCTION, organization, overwriteAPIProduct, tenantId); + addClientCertificates(extractedFolderPath, apiProvider, apiTypeWrapperWithUpdatedApiProduct, + APIConstants.API_KEY_TYPE_SANDBOX, organization, overwriteAPIProduct, tenantId); // Change API Product lifecycle if state transition is required if (!lifecycleActions.isEmpty()) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index 0b7e3574d60c..8af77275eddd 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -100,7 +100,7 @@ public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting } @POST - @Path("/{apiId}/client-certificates/{keyType}") + @Path("/{apiId}/client-certificates/v2/{keyType}") @Consumes({ "multipart/form-data" }) @Produces({ "application/json" }) @ApiOperation(value = "Upload a New Certificate of the given key type", notes = "This operation can be used to upload a new certificate for an endpoint of the given type. ", response = ClientCertMetadataDTO.class, authorizations = { @@ -419,7 +419,7 @@ public Response deleteAPIClientCertificateByAlias(@ApiParam(value = "The alias o } @DELETE - @Path("/{apiId}/client-certificates/{keyType}/{alias}") + @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") @Produces({ "application/json" }) @ApiOperation(value = "Delete a Certificate of a Given Key Type", notes = "This operation can be used to delete an uploaded certificate of a given key type. ", response = Void.class, authorizations = { @@ -699,7 +699,7 @@ public Response getAPIClientCertificateByAlias(@ApiParam(value = "",required=tru } @GET - @Path("/{apiId}/client-certificates/{keyType}/{alias}") + @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") @Produces({ "application/json" }) @ApiOperation(value = "Get the Certificate Information of a Given Key Type", notes = "This operation can be used to get the information about a certificate of a given key type. ", response = CertificateInfoDTO.class, authorizations = { @@ -741,7 +741,7 @@ public Response getAPIClientCertificateContentByAlias(@ApiParam(value = "**API I } @GET - @Path("/{apiId}/client-certificates/{keyType}/{alias}/content") + @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}/content") @Produces({ "application/json" }) @ApiOperation(value = "Download a Certificate of Given Key Type", notes = "This operation can be used to download a certificate which matches the given alias and key type. ", response = Void.class, authorizations = { @@ -782,7 +782,7 @@ public Response getAPIClientCertificates(@ApiParam(value = "**API ID** consistin } @GET - @Path("/{apiId}/client-certificates/{keyType}") + @Path("/{apiId}/client-certificates/v2/{keyType}") @Produces({ "application/json" }) @ApiOperation(value = "Retrieve/ Search Uploaded Client Certificates of a given key type", notes = "This operation can be used to retrieve and search the uploaded client certificates of a given key type. ", response = ClientCertificatesDTO.class, authorizations = { @@ -1654,7 +1654,7 @@ public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam( } @PUT - @Path("/{apiId}/client-certificates/{keyType}/{alias}") + @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") @Consumes({ "multipart/form-data" }) @Produces({ "application/json" }) @ApiOperation(value = "Update a Certificate of a Given Key Type", notes = "This operation can be used to update an uploaded certificate of a given key type. ", response = ClientCertMetadataDTO.class, authorizations = { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java index 6364c7b7da97..e41b4d8d5dfe 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java @@ -1185,8 +1185,8 @@ public Response addAPIClientCertificateOfGivenKeyType(String keyType, String api RestApiUtil.handleInternalServerError( "Internal server error while adding the client certificate to " + "API " + apiId, log); } else if (ResponseCode.ALIAS_EXISTS_IN_TRUST_STORE.getResponseCode() == responseCode) { - RestApiUtil.handleResourceAlreadyExistsError( - "The alias '" + alias + "' already exists in the trust store.", log); + RestApiUtil.handleResourceAlreadyExistsError("The alias '" + alias + + "' already exists in the trust store for " + keyType + " key type.", log); } else if (ResponseCode.CERTIFICATE_EXPIRED.getResponseCode() == responseCode) { RestApiUtil.handleBadRequest( "Error while adding the certificate to the API " + apiId + ". " + "Certificate Expired.", log); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index 2cd878390958..1f4536a16f6a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4669,7 +4669,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate - /apis/{apiId}/client-certificates/{keyType}: + /apis/{apiId}/client-certificates/v2/{keyType}: parameters: - in: path name: keyType @@ -4951,7 +4951,7 @@ paths: source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/{keyType}/{alias}: + /apis/{apiId}/client-certificates/v2/{keyType}/{alias}: parameters: - in: path name: keyType @@ -5160,7 +5160,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByAlias - /apis/{apiId}/client-certificates/{keyType}/{alias}/content: + /apis/{apiId}/client-certificates/v2/{keyType}/{alias}/content: get: tags: - Client Certificates diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java index c18551ceffab..bcf95830660e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java @@ -263,7 +263,7 @@ public final class RestApiConstants { public static final String MIGRATION_MODE = "migrationMode"; public static final String CERTS_BASE_PATH = "/certificates"; - public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates"; + public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/v2"; public static final String CERTS_GET_PAGINATED_URL = CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String CLIENT_CERTS_GET_PAGINATED_URL = diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql index e6bf8b139413..bd76746e5608 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables.sql @@ -1893,7 +1893,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ) / CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql index fdc06e18fe8e..645b74970270 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/OGG/oracle/apimgt/tables_23c.sql @@ -1893,7 +1893,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ) / CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql index d4e3a839ac21..15a7763abbf4 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/multi-dc/SQLServer/mssql/apimgt/tables.sql @@ -2228,7 +2228,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( TIER_NAME VARCHAR(512), KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID), + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE ); diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql index 0d3fe3c4be3f..1a3bf480dbda 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/db2.sql @@ -2772,7 +2772,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) )/ CREATE TABLE AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql index 98402e27a516..16a72011705b 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/h2.sql @@ -2017,7 +2017,7 @@ CREATE TABLE IF NOT EXISTS AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, - PRIMARY KEY (ALIAS,TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS,TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ); CREATE TABLE IF NOT EXISTS AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql index 01f3fa3a7a15..b183ac022fbf 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mssql.sql @@ -2239,7 +2239,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( TIER_NAME VARCHAR(512), KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID), + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID), FOREIGN KEY (API_ID) REFERENCES AM_API(API_ID) ON DELETE CASCADE ); diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql index 931dd31cacbf..a4bace7ddf78 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql.sql @@ -1964,7 +1964,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', `REVISION_UUID` VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, - PRIMARY KEY (`ALIAS`, `TENANT_ID`, `REMOVED`, `REVISION_UUID`) + PRIMARY KEY (`ALIAS`, `TENANT_ID`, `KEY_TYPE`, `REMOVED`, `REVISION_UUID`) ) ENGINE=InnoDB; CREATE TABLE IF NOT EXISTS AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql index fcf364b58b4c..51c0dd21ee7b 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/mysql_cluster.sql @@ -2144,7 +2144,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', `REVISION_UUID` VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID), - PRIMARY KEY (`ALIAS`, `TENANT_ID`, `REMOVED`, `REVISION_UUID`) + PRIMARY KEY (`ALIAS`, `TENANT_ID`, `KEY_TYPE`, `REMOVED`, `REVISION_UUID`) ) ENGINE=NDB; CREATE TABLE IF NOT EXISTS AM_APPLICATION_GROUP_MAPPING ( diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql index 97769e017052..a5591c7086a4 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle.sql @@ -3224,7 +3224,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql index ddf1e38f0d47..5c62db3fc242 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_23c.sql @@ -3224,7 +3224,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql index 69f0c0829092..441969cf40a2 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/oracle_rac.sql @@ -3198,7 +3198,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR2(20) DEFAULT 'PRODUCTION' NOT NULL, REVISION_UUID VARCHAR2(255) DEFAULT 'Current API' NOT NULL, FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ) / diff --git a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql index c22b2e025a80..da2e4fb70541 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.core.feature/src/main/resources/sql/postgresql.sql @@ -2330,7 +2330,7 @@ CREATE TABLE AM_API_CLIENT_CERTIFICATE ( KEY_TYPE VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', REVISION_UUID VARCHAR(255) NOT NULL DEFAULT 'Current API', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE, - PRIMARY KEY (ALIAS, KEY_TYPE, TENANT_ID, REMOVED, REVISION_UUID) + PRIMARY KEY (ALIAS, TENANT_ID, KEY_TYPE, REMOVED, REVISION_UUID) ); DROP TABLE IF EXISTS AM_APPLICATION_GROUP_MAPPING; diff --git a/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql b/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql index ea536e316628..ad6989643e3a 100644 --- a/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql +++ b/features/apimgt/org.wso2.carbon.apimgt.keymanager.feature/src/main/resources/sql/h2.sql @@ -1703,7 +1703,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `TIER_NAME` VARCHAR (512), `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, - PRIMARY KEY (`ALIAS`,`TENANT_ID`, `REMOVED`) + PRIMARY KEY (`ALIAS`,`TENANT_ID`, `KEY_TYPE`, `REMOVED`) ); CREATE TABLE IF NOT EXISTS AM_APPLICATION_GROUP_MAPPING ( From 2f730e48de03aca1272a6a814cfe6322161daa7a Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Tue, 2 Jul 2024 17:16:48 +0530 Subject: [PATCH 08/10] Modify the API export flows --- .../apimgt/api/gateway/GatewayAPIDTO.java | 34 ++++-------- .../apimgt/gateway/InMemoryAPIDeployer.java | 34 ++++-------- .../apimgt/gateway/internal/DataHolder.java | 32 +++-------- .../gateway/service/APIGatewayAdmin.java | 24 ++------ .../src/test/resources/dbscripts/h2.sql | 2 +- .../v1/common/TemplateBuilderUtil.java | 8 +-- .../v1/common/mappings/ExportUtils.java | 55 ++++++++++--------- 7 files changed, 71 insertions(+), 118 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java index 988fab5fad7a..64b563665b88 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/gateway/GatewayAPIDTO.java @@ -44,10 +44,8 @@ public class GatewayAPIDTO implements Serializable { private String[] sequencesToBeRemove; private GatewayContentDTO[] localEntriesToBeAdd; private String[] localEntriesToBeRemove; - private GatewayContentDTO[] productionClientCertificatesToBeAdd; - private GatewayContentDTO[] sandboxClientCertificatesToBeAdd; - private String[] productionClientCertificatesToBeRemove; - private String[] sandboxClientCertificatesToBeRemove; + private GatewayContentDTO[] clientCertificatesToBeAdd; + private String[] clientCertificatesToBeRemove; private GatewayContentDTO[] endpointEntriesToBeAdd; private String[] endpointEntriesToBeRemove; private CredentialDto[] credentialsToBeAdd ; @@ -153,36 +151,24 @@ public void setLocalEntriesToBeRemove(String[] localEntriesToBeRemove) { this.localEntriesToBeRemove = localEntriesToBeRemove; } - public GatewayContentDTO[] getProductionClientCertificatesToBeAdd() { - return productionClientCertificatesToBeAdd; - } + public GatewayContentDTO[] getClientCertificatesToBeAdd() { - public void setProductionClientCertificatesToBeAdd(GatewayContentDTO[] productionClientCertificatesToBeAdd) { - this.productionClientCertificatesToBeAdd = productionClientCertificatesToBeAdd; + return clientCertificatesToBeAdd; } - public GatewayContentDTO[] getSandboxClientCertificatesToBeAdd() { - return sandboxClientCertificatesToBeAdd; - } + public void setClientCertificatesToBeAdd(GatewayContentDTO[] clientCertificatesToBeAdd) { - public void setSandboxClientCertificatesToBeAdd(GatewayContentDTO[] sandboxClientCertificatesToBeAdd) { - this.sandboxClientCertificatesToBeAdd = sandboxClientCertificatesToBeAdd; + this.clientCertificatesToBeAdd = clientCertificatesToBeAdd; } - public String[] getProductionClientCertificatesToBeRemove() { - return productionClientCertificatesToBeRemove; - } + public String[] getClientCertificatesToBeRemove() { - public void setProductionClientCertificatesToBeRemove(String[] productionClientCertificatesToBeRemove) { - this.productionClientCertificatesToBeRemove = productionClientCertificatesToBeRemove; + return clientCertificatesToBeRemove; } - public String[] getSandboxClientCertificatesToBeRemove() { - return sandboxClientCertificatesToBeRemove; - } + public void setClientCertificatesToBeRemove(String[] clientCertificatesToBeRemove) { - public void setSandboxClientCertificatesToBeRemove(String[] sandboxClientCertificatesToBeRemove) { - this.sandboxClientCertificatesToBeRemove = sandboxClientCertificatesToBeRemove; + this.clientCertificatesToBeRemove = clientCertificatesToBeRemove; } public GatewayContentDTO[] getEndpointEntriesToBeAdd() { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index 3c05f7ca3b39..6c9b55897bf6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -355,8 +355,7 @@ private void unDeployAPI(APIGatewayAdmin apiGatewayAdmin, DeployAPIInGatewayEven GatewayUtils .addStringToList(gatewayEvent.getUuid(), gatewayAPIDTO.getLocalEntriesToBeRemove())); apiGatewayAdmin.unDeployAPI(gatewayAPIDTO); - DataHolder.getInstance().getApiToProductionCertificatesMap().remove(gatewayEvent.getUuid()); - DataHolder.getInstance().getApiToSandboxCertificatesMap().remove(gatewayEvent.getUuid()); + DataHolder.getInstance().getApiToCertificatesMap().remove(gatewayEvent.getUuid()); DataHolder.getInstance().removeKeyManagerToAPIMapping(gatewayAPIDTO.getApiId()); } @@ -421,21 +420,13 @@ private void addDeployedCertificatesToAPIAssociation(GatewayAPIDTO gatewayAPIDTO if (gatewayAPIDTO != null) { String apiId = gatewayAPIDTO.getApiId(); - List productionAliasList = new ArrayList<>(); - if (gatewayAPIDTO.getProductionClientCertificatesToBeAdd() != null) { - for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getProductionClientCertificatesToBeAdd()) { - productionAliasList.add(gatewayContentDTO.getName()); + List aliasList = new ArrayList<>(); + if (gatewayAPIDTO.getClientCertificatesToBeAdd() != null) { + for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getClientCertificatesToBeAdd()) { + aliasList.add(gatewayContentDTO.getName()); } } - DataHolder.getInstance().addApiToProductionAliasList(apiId, productionAliasList); - - List sandboxAliasList = new ArrayList<>(); - if (gatewayAPIDTO.getSandboxClientCertificatesToBeAdd() != null) { - for (GatewayContentDTO gatewayContentDTO : gatewayAPIDTO.getSandboxClientCertificatesToBeAdd()) { - sandboxAliasList.add(gatewayContentDTO.getName()); - } - } - DataHolder.getInstance().addApiToSandboxAliasList(apiId, sandboxAliasList); + DataHolder.getInstance().addApiToAliasList(apiId, aliasList); } } @@ -460,14 +451,11 @@ private void setClientCertificatesToRemoveIntoGatewayDTO(GatewayAPIDTO gatewayDT if (gatewayDTO != null) { if (StringUtils.isNotEmpty(gatewayDTO.getApiId())) { - List productionCertificateAliasListForAPI = - DataHolder.getInstance().getProductionCertificateAliasListForAPI(gatewayDTO.getApiId()); - gatewayDTO.setProductionClientCertificatesToBeRemove(productionCertificateAliasListForAPI.toArray(new String[0])); - } - if (StringUtils.isNotEmpty(gatewayDTO.getApiId())) { - List sandboxCertificateAliasListForAPI = - DataHolder.getInstance().getSandboxCertificateAliasListForAPI(gatewayDTO.getApiId()); - gatewayDTO.setSandboxClientCertificatesToBeRemove(sandboxCertificateAliasListForAPI.toArray(new String[0])); + List certificateAliasListForAPI = + DataHolder.getInstance().getCertificateAliasListForAPI(gatewayDTO.getApiId()); + certificateAliasListForAPI.addAll(certificateAliasListForAPI); + gatewayDTO.setClientCertificatesToBeRemove(certificateAliasListForAPI.toArray(new String[0])); + } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java index 3d1dda6d4bba..cff90588df0c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/internal/DataHolder.java @@ -39,8 +39,7 @@ public class DataHolder { private static final Log log = LogFactory.getLog(DataHolder.class); private static final DataHolder Instance = new DataHolder(); - private Map> apiToProductionCertificatesMap = new HashMap(); - private Map> apiToSandboxCertificatesMap = new HashMap(); + private Map> apiToCertificatesMap = new HashMap(); private Map googleAnalyticsConfigMap = new HashMap<>(); private Map apiToGraphQLSchemaDTOMap = new HashMap<>(); private Map> apiToKeyManagersMap = new HashMap<>(); @@ -52,42 +51,29 @@ private DataHolder() { initializeTenantDeploymentStatusMap(); } - public Map> getApiToProductionCertificatesMap() { - return apiToProductionCertificatesMap; - } + public Map> getApiToCertificatesMap() { - public void setApiToProductionCertificatesMap(Map> apiToProductionCertificatesMap) { - this.apiToProductionCertificatesMap = apiToProductionCertificatesMap; + return apiToCertificatesMap; } - public Map> getApiToSandboxCertificatesMap() { - return apiToSandboxCertificatesMap; - } + public void setApiToCertificatesMap(Map> apiToCertificatesMap) { - public void setApiToSandboxCertificatesMap(Map> apiToSandboxCertificatesMap) { - this.apiToSandboxCertificatesMap = apiToSandboxCertificatesMap; + this.apiToCertificatesMap = apiToCertificatesMap; } public static DataHolder getInstance() { return Instance; } - public void addApiToProductionAliasList(String apiId, List aliasList) { - apiToProductionCertificatesMap.put(apiId, aliasList); - } - public void addApiToSandboxAliasList(String apiId, List aliasList) { + public void addApiToAliasList(String apiId, List aliasList) { - apiToSandboxCertificatesMap.put(apiId, aliasList); + apiToCertificatesMap.put(apiId, aliasList); } - public List getProductionCertificateAliasListForAPI(String apiId) { - - return apiToProductionCertificatesMap.getOrDefault(apiId, Collections.emptyList()); - } - public List getSandboxCertificateAliasListForAPI(String apiId) { + public List getCertificateAliasListForAPI(String apiId) { - return apiToSandboxCertificatesMap.getOrDefault(apiId, Collections.emptyList()); + return apiToCertificatesMap.getOrDefault(apiId, Collections.emptyList()); } public void addGoogleAnalyticsConfig(String tenantDomain, String config) { diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java index 3f42784623dc..78dcb9758e2d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java @@ -666,20 +666,14 @@ public boolean deployAPI(GatewayAPIDTO gatewayAPIDTO) throws AxisFault { } // Add Client Certificates - if (gatewayAPIDTO.getProductionClientCertificatesToBeAdd() != null) { + if (gatewayAPIDTO.getClientCertificatesToBeAdd() != null) { synchronized (certificateManager) { - for (GatewayContentDTO certificate : gatewayAPIDTO.getProductionClientCertificatesToBeAdd()) { - certificateManager.addClientCertificateToGateway(certificate.getContent(), certificate.getName()); - } - } - } - if (gatewayAPIDTO.getSandboxClientCertificatesToBeAdd() != null) { - synchronized (certificateManager) { - for (GatewayContentDTO certificate : gatewayAPIDTO.getSandboxClientCertificatesToBeAdd()) { + for (GatewayContentDTO certificate : gatewayAPIDTO.getClientCertificatesToBeAdd()) { certificateManager.addClientCertificateToGateway(certificate.getContent(), certificate.getName()); } } } + if (log.isDebugEnabled()) { log.debug(gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion() + " client certificates deployed"); log.debug("Start to add vault entries " + gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion()); @@ -817,20 +811,14 @@ private void unDeployAPI(SequenceAdminServiceProxy sequenceAdminServiceProxy, } // Remove clientCertificates - if (gatewayAPIDTO.getProductionClientCertificatesToBeRemove() != null) { + if (gatewayAPIDTO.getClientCertificatesToBeRemove() != null) { synchronized (certificateManager) { - for (String alias : gatewayAPIDTO.getProductionClientCertificatesToBeRemove()) { - certificateManager.deleteClientCertificateFromGateway(alias); - } - } - } - if (gatewayAPIDTO.getSandboxClientCertificatesToBeRemove() != null) { - synchronized (certificateManager) { - for (String alias : gatewayAPIDTO.getSandboxClientCertificatesToBeRemove()) { + for (String alias : gatewayAPIDTO.getClientCertificatesToBeRemove()) { certificateManager.deleteClientCertificateFromGateway(alias); } } } + if (log.isDebugEnabled()) { log.debug(gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion() + " client certificates undeployed " + "successfully"); diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql index 6ba0ae41c324..834115bd1cb4 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/test/resources/dbscripts/h2.sql @@ -1717,7 +1717,7 @@ CREATE TABLE IF NOT EXISTS `AM_API_CLIENT_CERTIFICATE` ( `TIER_NAME` VARCHAR (512), `KEY_TYPE` VARCHAR(20) NOT NULL DEFAULT 'PRODUCTION', FOREIGN KEY (API_ID) REFERENCES AM_API (API_ID) ON DELETE CASCADE ON UPDATE CASCADE, - PRIMARY KEY (`ALIAS`,`TENANT_ID`, `REMOVED`) + PRIMARY KEY (`ALIAS`,`TENANT_ID`, `KEY_TYPE`, `REMOVED`) ); CREATE TABLE IF NOT EXISTS AM_APPLICATION_GROUP_MAPPING ( diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java index 630a1e0947c3..5a488bf08034 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java @@ -944,8 +944,8 @@ private static void setClientCertificatesToBeAdded(String tenantDomain, GatewayA clientCertificate.setName(APIConstants.API_KEY_TYPE_PRODUCTION + "_" + clientCertificateDTO.getAlias() + "_" + tenantId); clientCertificate.setContent(clientCertificateDTO.getCertificate()); - gatewayAPIDTO.setProductionClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, - gatewayAPIDTO.getProductionClientCertificatesToBeAdd())); + gatewayAPIDTO.setClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, + gatewayAPIDTO.getClientCertificatesToBeAdd())); } } if (sandboxClientCertificatesDTOList != null) { @@ -954,8 +954,8 @@ private static void setClientCertificatesToBeAdded(String tenantDomain, GatewayA clientCertificate.setName(APIConstants.API_KEY_TYPE_SANDBOX + "_" + clientCertificateDTO.getAlias() + "_" + tenantId); clientCertificate.setContent(clientCertificateDTO.getCertificate()); - gatewayAPIDTO.setSandboxClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, - gatewayAPIDTO.getSandboxClientCertificatesToBeAdd())); + gatewayAPIDTO.setClientCertificatesToBeAdd(addGatewayContentToList(clientCertificate, + gatewayAPIDTO.getClientCertificatesToBeAdd())); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java index 3186f5de47d2..4c8c4813d10d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java @@ -1019,35 +1019,40 @@ public static void addClientCertificatesToArchive(String archivePath, Identifier APIProvider provider, ExportFormat exportFormat, String organization) throws APIImportExportException { - List certificateMetadataDTOs; - try { - if (identifier instanceof APIProductIdentifier) { - certificateMetadataDTOs = provider - .searchClientCertificates(tenantId, null, null, - (APIProductIdentifier) identifier, organization); - } else { - certificateMetadataDTOs = provider - .searchClientCertificates(tenantId, null, null, - (APIIdentifier) identifier, organization); - } - if (!certificateMetadataDTOs.isEmpty()) { - String clientCertsDirectoryPath = - archivePath + File.separator + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY; - CommonUtil.createDirectory(clientCertsDirectoryPath); + String[] keyTypes = new String[] {APIConstants.API_KEY_TYPE_PRODUCTION, APIConstants.API_KEY_TYPE_SANDBOX}; - JsonArray certificateList = getClientCertificateContentAndMetaData(certificateMetadataDTOs, - clientCertsDirectoryPath); + for (String keyType : keyTypes) { - if (certificateList.size() > 0) { - CommonUtil.writeDtoToFile(clientCertsDirectoryPath + ImportExportConstants.CLIENT_CERTIFICATE_FILE, - exportFormat, ImportExportConstants.TYPE_CLIENT_CERTIFICATES, certificateList); + List certificateMetadataDTOs; + try { + if (identifier instanceof APIProductIdentifier) { + certificateMetadataDTOs = provider + .searchClientCertificates(tenantId, null, keyType, + (APIProductIdentifier) identifier, organization); + } else { + certificateMetadataDTOs = provider + .searchClientCertificates(tenantId, null, keyType, + (APIIdentifier) identifier, organization); } + if (!certificateMetadataDTOs.isEmpty()) { + String clientCertsDirectoryPath = archivePath + File.separator + + ImportExportConstants.CLIENT_CERTIFICATES_DIRECTORY + File.separator + keyType; + CommonUtil.createDirectory(clientCertsDirectoryPath); + + JsonArray certificateList = getClientCertificateContentAndMetaData(certificateMetadataDTOs, + clientCertsDirectoryPath); + + if (certificateList.size() > 0) { + CommonUtil.writeDtoToFile(clientCertsDirectoryPath + ImportExportConstants.CLIENT_CERTIFICATE_FILE, + exportFormat, ImportExportConstants.TYPE_CLIENT_CERTIFICATES, certificateList); + } + } + } catch (IOException e) { + throw new APIImportExportException("Error while saving as YAML or JSON", e); + } catch (APIManagementException e) { + throw new APIImportExportException( + "Error retrieving certificate meta data. tenantId [" + tenantId + "] api [" + tenantId + "]", e); } - } catch (IOException e) { - throw new APIImportExportException("Error while saving as YAML or JSON", e); - } catch (APIManagementException e) { - throw new APIImportExportException( - "Error retrieving certificate meta data. tenantId [" + tenantId + "] api [" + tenantId + "]", e); } } From b873ee7af25b50585392109a2d8ce92055ca52fa Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Wed, 3 Jul 2024 14:19:14 +0530 Subject: [PATCH 09/10] change resource paths of client certificate apis --- .../rest/api/common/RestApiConstants.java | 2 +- .../src/main/resources/publisher-api.yaml | 318 +++++++++--------- .../mappings/CertificateRestApiUtils.java | 2 +- .../apimgt/rest/api/publisher/v1/ApisApi.java | 12 +- .../src/main/resources/publisher-api.yaml | 318 +++++++++--------- .../rest/api/util/RestApiConstants.java | 2 +- 6 files changed, 333 insertions(+), 321 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java index b9ee6a70056d..f36b87e33521 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/java/org/wso2/carbon/apimgt/rest/api/common/RestApiConstants.java @@ -303,7 +303,7 @@ public final class RestApiConstants { public static final String MIGRATION_MODE = "migrationMode"; public static final String CERTS_BASE_PATH = "/certificates"; - public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/v2/"; + public static final String CLIENT_CERTS_BASE_PATH = "/client-certs/"; public static final String CERTS_GET_PAGINATED_URL = CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String CLIENT_CERTS_GET_PAGINATED_URL = diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index 1f4536a16f6a..a1370de98dc1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4554,6 +4554,9 @@ paths: source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/throttling-policies/api/Platinum"' + ###################################################### + # The "Client Certificates" resource APIs (Deprecated) + ###################################################### /apis/{apiId}/client-certificates: get: tags: @@ -4669,33 +4672,25 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate - /apis/{apiId}/client-certificates/v2/{keyType}: - parameters: - - in: path - name: keyType - schema: - type: string - required: true - description: Key type for the certificate + /apis/{apiId}/client-certificates/{alias}: get: + deprecated: true tags: - Client Certificates - summary: Retrieve/ Search Uploaded Client Certificates of a given key type + summary: Get the Certificate Information description: | - This operation can be used to retrieve and search the uploaded client certificates of a given key type. + This operation can be used to get the information about a certificate. parameters: - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/offset' - name: alias - in: query - description: Alias for the client certificate + in: path + required: true schema: type: string - $ref: '#/components/parameters/apiId' responses: 200: description: | - OK. Successful response with the list of matching certificate information in the body. + OK. headers: Content-Type: description: | @@ -4705,9 +4700,11 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ClientCertificates' + $ref: '#/components/schemas/CertificateInfo' 400: $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: @@ -4719,43 +4716,47 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates?alias=wso2carbon"' - operationId: getAPIClientCertificatesByKeyType - post: + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: getAPIClientCertificateByAlias + + put: + deprecated: true tags: - Client Certificates - summary: Upload a New Certificate of the given key type + summary: Update a Certificate description: | - This operation can be used to upload a new certificate for an endpoint of the given type. + This operation can be used to update an uploaded certificate. parameters: + - name: alias + in: path + description: Alias for the certificate + required: true + schema: + maxLength: 30 + minLength: 1 + type: string - $ref: '#/components/parameters/apiId' requestBody: content: multipart/form-data: schema: - required: - - alias - - certificate - - tier properties: certificate: type: string description: The certificate that needs to be uploaded. format: binary - alias: - maxLength: 30 - minLength: 1 - type: string - description: Alias for the certificate tier: type: string - description: API tier to which the certificate should be applied. - required: true + description: The tier of the certificate + keyType: + type: string + description: Whether the key type is PRODUCTION or SANDBOX + default: PRODUCTION responses: 200: description: | OK. - The Certificate added successfully. + The Certificate updated successfully. headers: Location: description: | @@ -4773,32 +4774,35 @@ paths: $ref: '#/components/schemas/ClientCertMetadata' 400: $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - apim:api_create - apim:api_manage - - apim:client_certificates_add + - apim:client_certificates_update - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' - operationId: addAPIClientCertificateOfGivenKeyType + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: updateAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/{alias}: - get: + delete: deprecated: true tags: - Client Certificates - summary: Get the Certificate Information + summary: Delete a Certificate description: | - This operation can be used to get the information about a certificate. + This operation can be used to delete an uploaded certificate. parameters: - name: alias in: path + description: | + The alias of the certificate that should be deleted. required: true schema: type: string @@ -4807,16 +4811,14 @@ paths: 200: description: | OK. + The Certificate deleted successfully. headers: Content-Type: description: | The content type of the body. schema: type: string - content: - application/json: - schema: - $ref: '#/components/schemas/CertificateInfo' + content: {} 400: $ref: '#/components/responses/BadRequest' 404: @@ -4825,69 +4827,41 @@ paths: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - - apim:api_view + - apim:api_create - apim:api_manage - - apim:client_certificates_view - - apim:client_certificates_manage + - apim:client_certificates_update x-code-samples: - lang: Curl - source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: getAPIClientCertificateByAlias + operationId: deleteAPIClientCertificateByAlias - put: + /apis/{apiId}/client-certificates/{alias}/content: + get: deprecated: true tags: - Client Certificates - summary: Update a Certificate + summary: Download a Certificate description: | - This operation can be used to update an uploaded certificate. + This operation can be used to download a certificate which matches the given alias. parameters: + - $ref: '#/components/parameters/apiId' - name: alias in: path - description: Alias for the certificate required: true schema: - maxLength: 30 - minLength: 1 type: string - - $ref: '#/components/parameters/apiId' - requestBody: - content: - multipart/form-data: - schema: - properties: - certificate: - type: string - description: The certificate that needs to be uploaded. - format: binary - tier: - type: string - description: The tier of the certificate - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION responses: 200: description: | OK. - The Certificate updated successfully. headers: - Location: - description: | - The URL of the newly created resource. - schema: - type: string Content-Type: description: | The content type of the body. schema: type: string - content: - application/json: - schema: - $ref: '#/components/schemas/ClientCertMetadata' + content: {} 400: $ref: '#/components/responses/BadRequest' 404: @@ -4896,62 +4870,139 @@ paths: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - - apim:api_create + - apim:api_view - apim:api_manage - - apim:client_certificates_update + - apim:client_certificates_view - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon - -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: updateAPIClientCertificateByAlias + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + operationId: getAPIClientCertificateContentByAlias - delete: - deprecated: true + ###################################################### + # The "Client Certificates" resource APIs (New) + ###################################################### + /apis/{apiId}/client-certs/{keyType}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: tags: - Client Certificates - summary: Delete a Certificate + summary: Retrieve/ Search Uploaded Client Certificates of a given key type description: | - This operation can be used to delete an uploaded certificate. + This operation can be used to retrieve and search the uploaded client certificates of a given key type. parameters: + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' - name: alias - in: path - description: | - The alias of the certificate that should be deleted. - required: true + in: query + description: Alias for the client certificate schema: type: string - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. Successful response with the list of matching certificate information in the body. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertificates' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION?alias=wso2carbon"' + operationId: getAPIClientCertificatesByKeyType + post: + tags: + - Client Certificates + summary: Upload a New Certificate of the given key type + description: | + This operation can be used to upload a new certificate for an endpoint of the given type. + parameters: + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + required: + - alias + - certificate + - tier + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + alias: + maxLength: 30 + minLength: 1 + type: string + description: Alias for the certificate + tier: + type: string + description: API tier to which the certificate should be applied. + required: true responses: 200: description: | OK. - The Certificate deleted successfully. + The Certificate added successfully. headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string Content-Type: description: | The content type of the body. schema: type: string - content: {} + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' 400: $ref: '#/components/responses/BadRequest' - 404: - $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - apim:api_create - apim:api_manage - - apim:client_certificates_update + - apim:client_certificates_add + - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: deleteAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/v2/{keyType}/{alias}: + source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION"' + operationId: addAPIClientCertificateOfGivenKeyType + + /apis/{apiId}/client-certs/{keyType}/{alias}: parameters: - in: path name: keyType @@ -5001,7 +5052,7 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon"' operationId: getAPIClientCertificateByKeyTypeAndAlias put: @@ -5068,7 +5119,7 @@ paths: - lang: Curl source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon - -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon"' operationId: updateAPIClientCertificateByKeyTypeAndAlias delete: @@ -5115,52 +5166,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByKeyTypeAndAlias - - /apis/{apiId}/client-certificates/{alias}/content: - get: - deprecated: true - tags: - - Client Certificates - summary: Download a Certificate - description: | - This operation can be used to download a certificate which matches the given alias. - parameters: - - $ref: '#/components/parameters/apiId' - - name: alias - in: path - required: true - schema: - type: string - responses: - 200: - description: | - OK. - headers: - Content-Type: - description: | - The content type of the body. - schema: - type: string - content: {} - 400: - $ref: '#/components/responses/BadRequest' - 404: - $ref: '#/components/responses/NotFound' - 500: - $ref: '#/components/responses/InternalServerError' - security: - - OAuth2Security: - - apim:api_view - - apim:api_manage - - apim:client_certificates_view - - apim:client_certificates_manage - x-code-samples: - - lang: Curl - source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' - operationId: getAPIClientCertificateContentByAlias - - /apis/{apiId}/client-certificates/v2/{keyType}/{alias}/content: + /apis/{apiId}/client-certs/{keyType}/{alias}/content: get: tags: - Client Certificates @@ -5207,7 +5213,7 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByKeyTypeAndAlias diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java index a6f131d9a40a..b9633a0f6da7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java @@ -201,7 +201,7 @@ public static ClientCertificatesDTO getPaginatedClientCertificates( Map paginatedParams = RestApiCommonUtil.getPaginationParams(offset, limit, certCount); String paginatedPrevious = ""; String paginatedNext = ""; - //base path of pagination url -> deptecated api + if (paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET) != null) { paginatedPrevious = getClientCertificatesPaginatedURL(RestApiConstants.CLIENT_CERTS_GET_PAGINATED_URL, keyType, paginatedParams.get(RestApiConstants.PAGINATION_PREVIOUS_OFFSET), diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index 8af77275eddd..a76a7d10400e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -100,7 +100,7 @@ public Response addAPIClientCertificate(@ApiParam(value = "**API ID** consisting } @POST - @Path("/{apiId}/client-certificates/v2/{keyType}") + @Path("/{apiId}/client-certs/{keyType}") @Consumes({ "multipart/form-data" }) @Produces({ "application/json" }) @ApiOperation(value = "Upload a New Certificate of the given key type", notes = "This operation can be used to upload a new certificate for an endpoint of the given type. ", response = ClientCertMetadataDTO.class, authorizations = { @@ -419,7 +419,7 @@ public Response deleteAPIClientCertificateByAlias(@ApiParam(value = "The alias o } @DELETE - @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") + @Path("/{apiId}/client-certs/{keyType}/{alias}") @Produces({ "application/json" }) @ApiOperation(value = "Delete a Certificate of a Given Key Type", notes = "This operation can be used to delete an uploaded certificate of a given key type. ", response = Void.class, authorizations = { @@ -699,7 +699,7 @@ public Response getAPIClientCertificateByAlias(@ApiParam(value = "",required=tru } @GET - @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") + @Path("/{apiId}/client-certs/{keyType}/{alias}") @Produces({ "application/json" }) @ApiOperation(value = "Get the Certificate Information of a Given Key Type", notes = "This operation can be used to get the information about a certificate of a given key type. ", response = CertificateInfoDTO.class, authorizations = { @@ -741,7 +741,7 @@ public Response getAPIClientCertificateContentByAlias(@ApiParam(value = "**API I } @GET - @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}/content") + @Path("/{apiId}/client-certs/{keyType}/{alias}/content") @Produces({ "application/json" }) @ApiOperation(value = "Download a Certificate of Given Key Type", notes = "This operation can be used to download a certificate which matches the given alias and key type. ", response = Void.class, authorizations = { @@ -782,7 +782,7 @@ public Response getAPIClientCertificates(@ApiParam(value = "**API ID** consistin } @GET - @Path("/{apiId}/client-certificates/v2/{keyType}") + @Path("/{apiId}/client-certs/{keyType}") @Produces({ "application/json" }) @ApiOperation(value = "Retrieve/ Search Uploaded Client Certificates of a given key type", notes = "This operation can be used to retrieve and search the uploaded client certificates of a given key type. ", response = ClientCertificatesDTO.class, authorizations = { @@ -1654,7 +1654,7 @@ public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam( } @PUT - @Path("/{apiId}/client-certificates/v2/{keyType}/{alias}") + @Path("/{apiId}/client-certs/{keyType}/{alias}") @Consumes({ "multipart/form-data" }) @Produces({ "application/json" }) @ApiOperation(value = "Update a Certificate of a Given Key Type", notes = "This operation can be used to update an uploaded certificate of a given key type. ", response = ClientCertMetadataDTO.class, authorizations = { diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index 1f4536a16f6a..a1370de98dc1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4554,6 +4554,9 @@ paths: source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/throttling-policies/api/Platinum"' + ###################################################### + # The "Client Certificates" resource APIs (Deprecated) + ###################################################### /apis/{apiId}/client-certificates: get: tags: @@ -4669,33 +4672,25 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' operationId: addAPIClientCertificate - /apis/{apiId}/client-certificates/v2/{keyType}: - parameters: - - in: path - name: keyType - schema: - type: string - required: true - description: Key type for the certificate + /apis/{apiId}/client-certificates/{alias}: get: + deprecated: true tags: - Client Certificates - summary: Retrieve/ Search Uploaded Client Certificates of a given key type + summary: Get the Certificate Information description: | - This operation can be used to retrieve and search the uploaded client certificates of a given key type. + This operation can be used to get the information about a certificate. parameters: - - $ref: '#/components/parameters/limit' - - $ref: '#/components/parameters/offset' - name: alias - in: query - description: Alias for the client certificate + in: path + required: true schema: type: string - $ref: '#/components/parameters/apiId' responses: 200: description: | - OK. Successful response with the list of matching certificate information in the body. + OK. headers: Content-Type: description: | @@ -4705,9 +4700,11 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ClientCertificates' + $ref: '#/components/schemas/CertificateInfo' 400: $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: @@ -4719,43 +4716,47 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates?alias=wso2carbon"' - operationId: getAPIClientCertificatesByKeyType - post: + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: getAPIClientCertificateByAlias + + put: + deprecated: true tags: - Client Certificates - summary: Upload a New Certificate of the given key type + summary: Update a Certificate description: | - This operation can be used to upload a new certificate for an endpoint of the given type. + This operation can be used to update an uploaded certificate. parameters: + - name: alias + in: path + description: Alias for the certificate + required: true + schema: + maxLength: 30 + minLength: 1 + type: string - $ref: '#/components/parameters/apiId' requestBody: content: multipart/form-data: schema: - required: - - alias - - certificate - - tier properties: certificate: type: string description: The certificate that needs to be uploaded. format: binary - alias: - maxLength: 30 - minLength: 1 - type: string - description: Alias for the certificate tier: type: string - description: API tier to which the certificate should be applied. - required: true + description: The tier of the certificate + keyType: + type: string + description: Whether the key type is PRODUCTION or SANDBOX + default: PRODUCTION responses: 200: description: | OK. - The Certificate added successfully. + The Certificate updated successfully. headers: Location: description: | @@ -4773,32 +4774,35 @@ paths: $ref: '#/components/schemas/ClientCertMetadata' 400: $ref: '#/components/responses/BadRequest' + 404: + $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - apim:api_create - apim:api_manage - - apim:client_certificates_add + - apim:client_certificates_update - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates"' - operationId: addAPIClientCertificateOfGivenKeyType + source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + operationId: updateAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/{alias}: - get: + delete: deprecated: true tags: - Client Certificates - summary: Get the Certificate Information + summary: Delete a Certificate description: | - This operation can be used to get the information about a certificate. + This operation can be used to delete an uploaded certificate. parameters: - name: alias in: path + description: | + The alias of the certificate that should be deleted. required: true schema: type: string @@ -4807,16 +4811,14 @@ paths: 200: description: | OK. + The Certificate deleted successfully. headers: Content-Type: description: | The content type of the body. schema: type: string - content: - application/json: - schema: - $ref: '#/components/schemas/CertificateInfo' + content: {} 400: $ref: '#/components/responses/BadRequest' 404: @@ -4825,69 +4827,41 @@ paths: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - - apim:api_view + - apim:api_create - apim:api_manage - - apim:client_certificates_view - - apim:client_certificates_manage + - apim:client_certificates_update x-code-samples: - lang: Curl - source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: getAPIClientCertificateByAlias + operationId: deleteAPIClientCertificateByAlias - put: + /apis/{apiId}/client-certificates/{alias}/content: + get: deprecated: true tags: - Client Certificates - summary: Update a Certificate + summary: Download a Certificate description: | - This operation can be used to update an uploaded certificate. + This operation can be used to download a certificate which matches the given alias. parameters: + - $ref: '#/components/parameters/apiId' - name: alias in: path - description: Alias for the certificate required: true schema: - maxLength: 30 - minLength: 1 type: string - - $ref: '#/components/parameters/apiId' - requestBody: - content: - multipart/form-data: - schema: - properties: - certificate: - type: string - description: The certificate that needs to be uploaded. - format: binary - tier: - type: string - description: The tier of the certificate - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION responses: 200: description: | OK. - The Certificate updated successfully. headers: - Location: - description: | - The URL of the newly created resource. - schema: - type: string Content-Type: description: | The content type of the body. schema: type: string - content: - application/json: - schema: - $ref: '#/components/schemas/ClientCertMetadata' + content: {} 400: $ref: '#/components/responses/BadRequest' 404: @@ -4896,62 +4870,139 @@ paths: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - - apim:api_create + - apim:api_view - apim:api_manage - - apim:client_certificates_update + - apim:client_certificates_view - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon - -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: updateAPIClientCertificateByAlias + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + operationId: getAPIClientCertificateContentByAlias - delete: - deprecated: true + ###################################################### + # The "Client Certificates" resource APIs (New) + ###################################################### + /apis/{apiId}/client-certs/{keyType}: + parameters: + - in: path + name: keyType + schema: + type: string + required: true + description: Key type for the certificate + get: tags: - Client Certificates - summary: Delete a Certificate + summary: Retrieve/ Search Uploaded Client Certificates of a given key type description: | - This operation can be used to delete an uploaded certificate. + This operation can be used to retrieve and search the uploaded client certificates of a given key type. parameters: + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/offset' - name: alias - in: path - description: | - The alias of the certificate that should be deleted. - required: true + in: query + description: Alias for the client certificate schema: type: string - $ref: '#/components/parameters/apiId' + responses: + 200: + description: | + OK. Successful response with the list of matching certificate information in the body. + headers: + Content-Type: + description: | + The content type of the body. + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertificates' + 400: + $ref: '#/components/responses/BadRequest' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - OAuth2Security: + - apim:api_view + - apim:api_manage + - apim:client_certificates_view + - apim:client_certificates_manage + x-code-samples: + - lang: Curl + source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION?alias=wso2carbon"' + operationId: getAPIClientCertificatesByKeyType + post: + tags: + - Client Certificates + summary: Upload a New Certificate of the given key type + description: | + This operation can be used to upload a new certificate for an endpoint of the given type. + parameters: + - $ref: '#/components/parameters/apiId' + requestBody: + content: + multipart/form-data: + schema: + required: + - alias + - certificate + - tier + properties: + certificate: + type: string + description: The certificate that needs to be uploaded. + format: binary + alias: + maxLength: 30 + minLength: 1 + type: string + description: Alias for the certificate + tier: + type: string + description: API tier to which the certificate should be applied. + required: true responses: 200: description: | OK. - The Certificate deleted successfully. + The Certificate added successfully. headers: + Location: + description: | + The URL of the newly created resource. + schema: + type: string Content-Type: description: | The content type of the body. schema: type: string - content: {} + content: + application/json: + schema: + $ref: '#/components/schemas/ClientCertMetadata' 400: $ref: '#/components/responses/BadRequest' - 404: - $ref: '#/components/responses/NotFound' 500: $ref: '#/components/responses/InternalServerError' security: - OAuth2Security: - apim:api_create - apim:api_manage - - apim:client_certificates_update + - apim:client_certificates_add + - apim:client_certificates_manage x-code-samples: - lang: Curl - source: 'curl -k -X DELETE -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' - operationId: deleteAPIClientCertificateByAlias - /apis/{apiId}/client-certificates/v2/{keyType}/{alias}: + source: 'curl -k -X POST -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" + -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon -F tier=Gold + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION"' + operationId: addAPIClientCertificateOfGivenKeyType + + /apis/{apiId}/client-certs/{keyType}/{alias}: parameters: - in: path name: keyType @@ -5001,7 +5052,7 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon"' operationId: getAPIClientCertificateByKeyTypeAndAlias put: @@ -5068,7 +5119,7 @@ paths: - lang: Curl source: 'curl -k -X PUT -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -H "Content-Type: multipart/form-data" -F certificate=@test.crt -F alias=wso2carbon - -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' + -F apiId=fea749dd-d548-4a8b-b308-34903b39a34b -F tier=Gold "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon"' operationId: updateAPIClientCertificateByKeyTypeAndAlias delete: @@ -5115,52 +5166,7 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon"' operationId: deleteAPIClientCertificateByKeyTypeAndAlias - - /apis/{apiId}/client-certificates/{alias}/content: - get: - deprecated: true - tags: - - Client Certificates - summary: Download a Certificate - description: | - This operation can be used to download a certificate which matches the given alias. - parameters: - - $ref: '#/components/parameters/apiId' - - name: alias - in: path - required: true - schema: - type: string - responses: - 200: - description: | - OK. - headers: - Content-Type: - description: | - The content type of the body. - schema: - type: string - content: {} - 400: - $ref: '#/components/responses/BadRequest' - 404: - $ref: '#/components/responses/NotFound' - 500: - $ref: '#/components/responses/InternalServerError' - security: - - OAuth2Security: - - apim:api_view - - apim:api_manage - - apim:client_certificates_view - - apim:client_certificates_manage - x-code-samples: - - lang: Curl - source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' - operationId: getAPIClientCertificateContentByAlias - - /apis/{apiId}/client-certificates/v2/{keyType}/{alias}/content: + /apis/{apiId}/client-certs/{keyType}/{alias}/content: get: tags: - Client Certificates @@ -5207,7 +5213,7 @@ paths: x-code-samples: - lang: Curl source: 'curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" - "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certificates/wso2carbon/content" > test.crt' + "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByKeyTypeAndAlias diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java index bcf95830660e..c18551ceffab 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/RestApiConstants.java @@ -263,7 +263,7 @@ public final class RestApiConstants { public static final String MIGRATION_MODE = "migrationMode"; public static final String CERTS_BASE_PATH = "/certificates"; - public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates/v2"; + public static final String CLIENT_CERTS_BASE_PATH = "/clientCertificates"; public static final String CERTS_GET_PAGINATED_URL = CERTS_BASE_PATH + "?limit=" + LIMIT_PARAM + "&offset=" + OFFSET_PARAM + QUERY_PARAM; public static final String CLIENT_CERTS_GET_PAGINATED_URL = From 96dd874f19980c7f6cf2af3dfebefc530b327383 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Sat, 6 Jul 2024 00:11:27 +0530 Subject: [PATCH 10/10] Remove unrelated modifications and Address review comments --- .../wso2/carbon/apimgt/api/APIProvider.java | 2 +- .../apimgt/api/dto/ClientCertificateDTO.java | 3 --- .../apimgt/gateway/InMemoryAPIDeployer.java | 3 --- .../security/APIAuthenticationHandler.java | 19 ------------------- .../authenticator/MutualSSLAuthenticator.java | 6 +++--- .../gateway/service/APIGatewayAdmin.java | 2 -- .../swagger.json | 4 ++-- .../src/main/resources/admin-api.yaml | 12 ------------ .../src/main/resources/publisher-api.yaml | 5 ----- .../v1/common/TemplateBuilderUtil.java | 16 ++++++++-------- .../v1/common/mappings/APIControllerUtil.java | 7 ++++--- .../mappings/CertificateRestApiUtils.java | 4 ++-- .../v1/common/mappings/ExportUtils.java | 6 ++++-- .../apimgt/rest/api/publisher/v1/ApisApi.java | 4 ++-- .../rest/api/publisher/v1/ApisApiService.java | 2 +- .../publisher/v1/impl/ApisApiServiceImpl.java | 2 +- .../src/main/resources/publisher-api.yaml | 5 ----- 17 files changed, 28 insertions(+), 74 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java index 796ae0126323..4eb5ee14b7ed 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIProvider.java @@ -836,7 +836,7 @@ int addClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String * 4 : If certificate is not found in the trust store. * @throws APIManagementException API Management Exception. */ - int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias, String keyTye) + int deleteClientCertificate(String userName, ApiTypeWrapper apiTypeWrapper, String alias, String keyType) throws APIManagementException; /** diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java index 41f86b34e05e..0d6313f93904 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/dto/ClientCertificateDTO.java @@ -30,9 +30,6 @@ public class ClientCertificateDTO { private String tierName; private APIIdentifier apiIdentifier; - public ClientCertificateDTO() { - } - /** * To get the identifier of the API related with client certificate. * diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java index 6c9b55897bf6..dbb9d0ecac21 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/InMemoryAPIDeployer.java @@ -356,7 +356,6 @@ private void unDeployAPI(APIGatewayAdmin apiGatewayAdmin, DeployAPIInGatewayEven .addStringToList(gatewayEvent.getUuid(), gatewayAPIDTO.getLocalEntriesToBeRemove())); apiGatewayAdmin.unDeployAPI(gatewayAPIDTO); DataHolder.getInstance().getApiToCertificatesMap().remove(gatewayEvent.getUuid()); - DataHolder.getInstance().removeKeyManagerToAPIMapping(gatewayAPIDTO.getApiId()); } } @@ -453,9 +452,7 @@ private void setClientCertificatesToRemoveIntoGatewayDTO(GatewayAPIDTO gatewayDT if (StringUtils.isNotEmpty(gatewayDTO.getApiId())) { List certificateAliasListForAPI = DataHolder.getInstance().getCertificateAliasListForAPI(gatewayDTO.getApiId()); - certificateAliasListForAPI.addAll(certificateAliasListForAPI); gatewayDTO.setClientCertificatesToBeRemove(certificateAliasListForAPI.toArray(new String[0])); - } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java index 4676a5b6b075..e68aca00112d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/APIAuthenticationHandler.java @@ -97,7 +97,6 @@ public class APIAuthenticationHandler extends AbstractHandler implements Managed private String apiKeyHeader; private String apiSecurity; private String apiLevelPolicy; - private String environmentType; private String certificateInformation; private String apiUUID; private String apiType = String.valueOf(APIConstants.ApiTypes.API); // Default API Type @@ -152,24 +151,6 @@ public void setAPILevelPolicy(String apiLevelPolicy) { this.apiLevelPolicy = apiLevelPolicy; } - /** - * To get the environment type (whether production or sandbox). - * - * @return the environment type. - */ - public String getEnvironmentType() { - return environmentType; - } - - /** - * To set the environment type (whether production or sandbox). - * - * @param environmentType the environment type. - */ - public void setEnvironmentType(String environmentType) { - this.environmentType = environmentType; - } - /** * Get type of the API * @return API Type diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java index 3a5a9a96016b..dfab069f7e05 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/authenticator/MutualSSLAuthenticator.java @@ -60,7 +60,7 @@ public class MutualSSLAuthenticator implements Authenticator { private boolean isMandatory; // -Format - private HashMap> certificates; + private Map> certificates; /** * Initialized the mutual SSL authenticator. @@ -217,7 +217,7 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi String subjectDNIdentifier = (x509Certificate.getSerialNumber() + "_" + x509Certificate.getSubjectDN()).replaceAll(",", "#").replaceAll("\"", "'").trim(); subjectDNIdentifiers.add(subjectDNIdentifier); - for (Map.Entry> entry : certificates.entrySet()) { + for (Map.Entry> entry : certificates.entrySet()) { String key = entry.getKey(); if (StringUtils.equals(subjectDNIdentifier, key)) { uniqueIdentifier = key; @@ -231,7 +231,7 @@ private void setAuthContext(MessageContext messageContext, Certificate[] certifi } } if (StringUtils.isEmpty(tier)) { - for (Map.Entry> entry : certificates.entrySet()) { + for (Map.Entry> entry : certificates.entrySet()) { String key = entry.getKey(); if (key.contains(issuerDNIdentifier)) { uniqueIdentifier = key; diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java index 78dcb9758e2d..83c59df1de7e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/service/APIGatewayAdmin.java @@ -673,7 +673,6 @@ public boolean deployAPI(GatewayAPIDTO gatewayAPIDTO) throws AxisFault { } } } - if (log.isDebugEnabled()) { log.debug(gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion() + " client certificates deployed"); log.debug("Start to add vault entries " + gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion()); @@ -818,7 +817,6 @@ private void unDeployAPI(SequenceAdminServiceProxy sequenceAdminServiceProxy, } } } - if (log.isDebugEnabled()) { log.debug(gatewayAPIDTO.getName() + ":" + gatewayAPIDTO.getVersion() + " client certificates undeployed " + "successfully"); diff --git a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json index 8040e385bd35..a7fa59630d63 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json +++ b/components/apimgt/org.wso2.carbon.apimgt.internal.service/swagger.json @@ -1354,8 +1354,8 @@ "type" : "string", "example" : "EXCHANGED", "description" : "The type of the tokens to be used (exchanged or without exchanged). Accepted values are EXCHANGED, DIRECT or BOTH.", - "default" : "DIRECT", - "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ] + "enum" : [ "EXCHANGED", "DIRECT", "BOTH" ], + "default" : "DIRECT" } } }, diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml index 8dff2ebf0c29..9aa4db9ea6a8 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/admin-api.yaml @@ -1330,18 +1330,6 @@ paths: Retrieves all existing deny policies. parameters: - $ref: '#/components/parameters/Accept' - - name: query - in: query - description: | - **Search condition**. - You can search in attributes by using **"conditionType:"** modifier and **"conditionValue:"** modifier. - Eg. - The entry "conditionType:API" will result in a match with blocking conditions only if the conditionType is "API". Similarly, "conditionValue:test/1.0.0" will result in a match with blocking conditions only if the conditionValue is "test/1.0.0". - When you use "conditionType:API & conditionValue:test/1.0.0" as a combination, it will result in a match with blocking conditions only if both the conditionType is "API" and the conditionValue is "test/1.0.0". - If query attribute is provided, this returns the blocking conditions that match the specified attributes. - Please note that you need to use encoded URL (URL encoding) if you are using a client which does not support URL encoding (such as curl) - schema: - type: string responses: 200: description: | diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml index a1370de98dc1..33befcd74c17 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.common/src/main/resources/publisher-api.yaml @@ -4748,10 +4748,6 @@ paths: tier: type: string description: The tier of the certificate - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION responses: 200: description: | @@ -5216,7 +5212,6 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByKeyTypeAndAlias - ###################################################### # The "Certificate Management" resource APIs ###################################################### diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java index 5a488bf08034..3364f31a794b 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/TemplateBuilderUtil.java @@ -90,10 +90,10 @@ public class TemplateBuilderUtil { private static final Log log = LogFactory.getLog(TemplateBuilderUtil.class); public static APITemplateBuilderImpl getAPITemplateBuilder(API api, String tenantDomain, - List clientCertificateDTOSProduction, - List clientCertificateDTOSSandbox, - List soapToRestInMediationDtos, - List soapToRestMediationDtos) + List clientCertificateDTOSProduction, + List clientCertificateDTOSSandbox, + List soapToRestInMediationDtos, + List soapToRestMediationDtos) throws APIManagementException { int tenantId = APIUtil.getTenantIdFromTenantDomain(tenantDomain); @@ -674,10 +674,10 @@ private static void setCustomSequencesToBeAdded(APIProduct apiProduct, API api, } private static GatewayAPIDTO createAPIGatewayDTOtoPublishAPI(Environment environment, API api, - APITemplateBuilder builder, String tenantDomain, - String extractedPath, APIDTO apidto, - List productionClientCertificatesDTOList, - List sandboxClientCertificatesDTOList) + APITemplateBuilder builder, String tenantDomain, + String extractedPath, APIDTO apidto, + List productionClientCertificatesDTOList, + List sandboxClientCertificatesDTOList) throws APIManagementException, APITemplateException, XMLStreamException { GatewayAPIDTO gatewayAPIDTO = new GatewayAPIDTO(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java index 94a06c4c2d40..eba1d83965ab 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/APIControllerUtil.java @@ -1030,7 +1030,8 @@ private static void handleClientCertificates(JsonArray certificates, Identifier } } //copy certs file from certificates - userCertificatesTempDirectory = userCertificatesTempDirectoryPath + APIConstants.API_KEY_TYPE_PRODUCTION; + userCertificatesTempDirectory = userCertificatesTempDirectoryPath + + APIConstants.API_KEY_TYPE_PRODUCTION; } String sourcePath = userCertificatesTempDirectory + File.separator + certName; @@ -1062,8 +1063,8 @@ private static void handleClientCertificates(JsonArray certificates, Identifier } } - private static void verifyExistenceOfClientCertAndWriteToMetadataFile(String metadataFilePath, JsonElement jsonElement) - throws APIImportExportException, IOException { + private static void verifyExistenceOfClientCertAndWriteToMetadataFile(String metadataFilePath, + JsonElement jsonElement) throws APIImportExportException, IOException { if (CommonUtil.checkFileExistence(metadataFilePath + ImportExportConstants.YAML_EXTENSION)) { File oldFile = new File(metadataFilePath + ImportExportConstants.YAML_EXTENSION); oldFile.delete(); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java index b9633a0f6da7..797014c540d0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/CertificateRestApiUtils.java @@ -242,8 +242,8 @@ private static String getCertificatesPaginatedURL(String paginatedURL, Integer o * @param query : The provided query string * @return : Certificates paginated URL */ - private static String getClientCertificatesPaginatedURL(String paginatedURL, String keyType, Integer offset, Integer limit, - String query) { + private static String getClientCertificatesPaginatedURL(String paginatedURL, String keyType, Integer offset, + Integer limit, String query) { paginatedURL = paginatedURL.replace(RestApiConstants.KEYTYPE_PARAM, keyType); paginatedURL = paginatedURL.replace(RestApiConstants.LIMIT_PARAM, String.valueOf(limit)); paginatedURL = paginatedURL.replace(RestApiConstants.OFFSET_PARAM, String.valueOf(offset)); diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java index 4c8c4813d10d..c318151d3d2e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1.common/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/common/mappings/ExportUtils.java @@ -1043,7 +1043,8 @@ public static void addClientCertificatesToArchive(String archivePath, Identifier clientCertsDirectoryPath); if (certificateList.size() > 0) { - CommonUtil.writeDtoToFile(clientCertsDirectoryPath + ImportExportConstants.CLIENT_CERTIFICATE_FILE, + CommonUtil.writeDtoToFile( + clientCertsDirectoryPath + ImportExportConstants.CLIENT_CERTIFICATE_FILE, exportFormat, ImportExportConstants.TYPE_CLIENT_CERTIFICATES, certificateList); } } @@ -1051,7 +1052,8 @@ public static void addClientCertificatesToArchive(String archivePath, Identifier throw new APIImportExportException("Error while saving as YAML or JSON", e); } catch (APIManagementException e) { throw new APIImportExportException( - "Error retrieving certificate meta data. tenantId [" + tenantId + "] api [" + tenantId + "]", e); + "Error retrieving certificate meta data. tenantId [" + tenantId + "] api [" + + tenantId + "]", e); } } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java index a76a7d10400e..1b1b92debca2 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApi.java @@ -1649,8 +1649,8 @@ public Response undeployAPIRevision(@ApiParam(value = "**API ID** consisting of @ApiResponse(code = 400, message = "Bad Request. Invalid request or validation error.", response = ErrorDTO.class), @ApiResponse(code = 404, message = "Not Found. The specified resource does not exist.", response = ErrorDTO.class), @ApiResponse(code = 500, message = "Internal Server Error.", response = ErrorDTO.class) }) - public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam(value = "Alias for the certificate",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate", required = false) InputStream certificateInputStream, @Multipart(value = "certificate" , required = false) Attachment certificateDetail, @Multipart(value = "tier", required = false) String tier, @Multipart(value = "keyType", required = false) String keyType) throws APIManagementException{ - return delegate.updateAPIClientCertificateByAlias(alias, apiId, certificateInputStream, certificateDetail, tier, keyType, securityContext); + public Response updateAPIClientCertificateByAlias( @Size(min=1,max=30)@ApiParam(value = "Alias for the certificate",required=true) @PathParam("alias") String alias, @ApiParam(value = "**API ID** consisting of the **UUID** of the API. ",required=true) @PathParam("apiId") String apiId, @Multipart(value = "certificate", required = false) InputStream certificateInputStream, @Multipart(value = "certificate" , required = false) Attachment certificateDetail, @Multipart(value = "tier", required = false) String tier) throws APIManagementException{ + return delegate.updateAPIClientCertificateByAlias(alias, apiId, certificateInputStream, certificateDetail, tier, securityContext); } @PUT diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java index ebf276ef28e4..109eed40030d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/gen/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/ApisApiService.java @@ -143,7 +143,7 @@ public interface ApisApiService { public Response restoreAPIRevision(String apiId, String revisionId, MessageContext messageContext) throws APIManagementException; public Response undeployAPIRevision(String apiId, String revisionId, String revisionNumber, Boolean allEnvironments, List apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPI(String apiId, APIDTO APIDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; - public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, String keyType, MessageContext messageContext) throws APIManagementException; + public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) throws APIManagementException; public Response updateAPIClientCertificateByKeyTypeAndAlias(String keyType, String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, MessageContext messageContext) throws APIManagementException; public Response updateAPIDeployment(String apiId, String deploymentId, APIRevisionDeploymentDTO apIRevisionDeploymentDTO, MessageContext messageContext) throws APIManagementException; public Response updateAPIDocument(String apiId, String documentId, DocumentDTO documentDTO, String ifMatch, MessageContext messageContext) throws APIManagementException; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java index e41b4d8d5dfe..2c4a3f36f68c 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/publisher/v1/impl/ApisApiServiceImpl.java @@ -999,7 +999,7 @@ public Response getAPIClientCertificateByKeyTypeAndAlias(String keyType, String public Response updateAPIClientCertificateByAlias(String alias, String apiId, InputStream certificateInputStream, Attachment certificateDetail, String tier, - String keyType, MessageContext messageContext) { + MessageContext messageContext) { return updateAPIClientCertificateByKeyTypeAndAlias(APIConstants.API_KEY_TYPE_PRODUCTION, alias, apiId, certificateInputStream, certificateDetail, tier, messageContext); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml index a1370de98dc1..33befcd74c17 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher.v1/src/main/resources/publisher-api.yaml @@ -4748,10 +4748,6 @@ paths: tier: type: string description: The tier of the certificate - keyType: - type: string - description: Whether the key type is PRODUCTION or SANDBOX - default: PRODUCTION responses: 200: description: | @@ -5216,7 +5212,6 @@ paths: "https://127.0.0.1:9443/api/am/publisher/v4/apis/d48a3412-1b85-49be-99f4-b81a3722ae73/client-certs/PRODUCTION/wso2carbon/content" > test.crt' operationId: getAPIClientCertificateContentByKeyTypeAndAlias - ###################################################### # The "Certificate Management" resource APIs ######################################################