Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,106 @@ public ClientDetail buildClient(String clientId, ClientDetailUpdateRequestV3 cli
clientDetail.setAdditionalConfig(clientDetailUpdateRequestV3.getAdditionalConfig());
return clientDetail;
}

/**
* Build client detail entity for PATCH update operation.
* @param clientId The client ID to update
* @param patchRequest The patch request containing fields to update
* @return Updated ClientDetail entity
*/
public ClientDetail buildClient(String clientId, ClientDetailPatchRequest patchRequest) {
Optional<ClientDetail> result = clientDetailRepository.findById(clientId);
if (result.isEmpty()) {
log.error("Invalid Client Id : {}", ErrorConstants.INVALID_CLIENT_ID);
throw new EsignetException(ErrorConstants.INVALID_CLIENT_ID);
}

ClientDetail clientDetail = result.get();

// Apply partial updates - only non-null fields
if (patchRequest.getLogoUri() != null) {
clientDetail.setLogoUri(patchRequest.getLogoUri());
}

if (patchRequest.getRedirectUris() != null) {
patchRequest.getRedirectUris().removeAll(NULL);
clientDetail.setRedirectUris(JSONArray.toJSONString(patchRequest.getRedirectUris()));
}

if (patchRequest.getUserClaims() != null) {
patchRequest.getUserClaims().removeAll(NULL);
clientDetail.setClaims(JSONArray.toJSONString(patchRequest.getUserClaims()));
}

if (patchRequest.getAuthContextRefs() != null) {
patchRequest.getAuthContextRefs().removeAll(NULL);
clientDetail.setAcrValues(JSONArray.toJSONString(patchRequest.getAuthContextRefs()));
}

if (patchRequest.getStatus() != null) {
clientDetail.setStatus(patchRequest.getStatus());
}

if (patchRequest.getGrantTypes() != null) {
patchRequest.getGrantTypes().removeAll(NULL);
clientDetail.setGrantTypes(JSONArray.toJSONString(patchRequest.getGrantTypes()));
}

if (patchRequest.getClientAuthMethods() != null) {
patchRequest.getClientAuthMethods().removeAll(NULL);
clientDetail.setClientAuthMethods(JSONArray.toJSONString(patchRequest.getClientAuthMethods()));
}

// Handle client name update
if (patchRequest.getClientName() != null || patchRequest.getClientNameLangMap() != null) {
String existingName = clientDetail.getName();
Map<String, String> existingNameMap = new HashMap<>();
try {
existingNameMap = objectMapper.readValue(existingName, new TypeReference<>() {});
} catch (Exception e) {
log.warn("Failed to parse existing client name as JSON, using empty map");
}

String clientName = patchRequest.getClientName() != null ?
patchRequest.getClientName() :
existingNameMap.getOrDefault(Constants.NONE_LANG_KEY, "");

Map<String, String> clientNameLangMap = patchRequest.getClientNameLangMap() != null ?
patchRequest.getClientNameLangMap() :
existingNameMap;

clientDetail.setName(getClientNameLanguageMapAsJsonString(clientNameLangMap, clientName));
}

if (patchRequest.getAdditionalConfig() != null) {
clientDetail.setAdditionalConfig(patchRequest.getAdditionalConfig());
}

// Handle enc_public_key update - only if provided and not empty
if (patchRequest.getEncPublicKey() != null) {
try {
clientDetail.setEncPublicKey(IdentityProviderUtil.getJWKString(patchRequest.getEncPublicKey()));
} catch (EsignetException e) {
log.error("Invalid encryption public key",e);
throw e;
}
clientDetail.setEncPublicKeyHash(identityProviderUtil.computePublicKeyHash(patchRequest.getEncPublicKey()));
}

clientDetail.setUpdatedtimes(LocalDateTime.now(ZoneId.of("UTC")));
return clientDetail;
}

@CacheEvict(value = Constants.CLIENT_DETAIL_CACHE, key = "#clientId")
@Override
public ClientDetailResponse patchClient(String clientId, ClientDetailPatchRequest patchRequest) throws EsignetException {
ClientDetail clientDetail = buildClient(clientId, patchRequest);
clientDetail = clientDetailRepository.save(clientDetail);

auditWrapper.logAudit(AuditHelper.getClaimValue(SecurityContextHolder.getContext(), claimName),
Action.OAUTH_CLIENT_PATCH, ActionStatus.SUCCESS, AuditHelper.buildAuditDto(clientId), null);

return getClientDetailResponse(clientDetail);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,91 @@ public void createClientDetail_withInvalidStatus_thenFail() {
}
Assertions.fail();
}

@Test
public void createClientDetail_withEncPublicKey_thenPass() {
ClientDetail clientDetail = new ClientDetail();
clientDetail.setId("C02");
clientDetail.setName("Client-02");
clientDetail.setLogoUri("https://clienapp.com/logo.png");
clientDetail.setStatus("ACTIVE");
clientDetail.setRedirectUris("[\"https://clientapp.com/home\"]");
clientDetail.setPublicKey("DUMMY PEM CERT");
clientDetail.setPublicKeyHash(UUID.randomUUID().toString());
clientDetail.setEncPublicKey("DUMMY ENC PUBLIC KEY");
clientDetail.setEncPublicKeyHash(UUID.randomUUID().toString());
clientDetail.setRpId("RP02");
clientDetail.setClaims("[]");
clientDetail.setAcrValues("[]");
clientDetail.setGrantTypes("[\"authorization_code\"]");
clientDetail.setClientAuthMethods("[\"private_key_jwt\"]");
clientDetail.setCreatedtimes(LocalDateTime.now());
clientDetail = clientDetailRepository.saveAndFlush(clientDetail);
Assertions.assertNotNull(clientDetail);

Optional<ClientDetail> result = clientDetailRepository.findById("C02");
Assertions.assertTrue(result.isPresent());
Assertions.assertNotNull(result.get().getEncPublicKey());
Assertions.assertNotNull(result.get().getEncPublicKeyHash());
Assertions.assertEquals("DUMMY ENC PUBLIC KEY", result.get().getEncPublicKey());
}

@Test
public void createClientDetail_withNullEncPublicKey_thenPass() {
ClientDetail clientDetail = new ClientDetail();
clientDetail.setId("C03");
clientDetail.setName("Client-03");
clientDetail.setLogoUri("https://clienapp.com/logo.png");
clientDetail.setStatus("ACTIVE");
clientDetail.setRedirectUris("[\"https://clientapp.com/home\"]");
clientDetail.setPublicKey("DUMMY PEM CERT");
clientDetail.setPublicKeyHash(UUID.randomUUID().toString());
// encPublicKey and encPublicKeyHash are null (optional fields)
clientDetail.setRpId("RP03");
clientDetail.setClaims("[]");
clientDetail.setAcrValues("[]");
clientDetail.setGrantTypes("[\"authorization_code\"]");
clientDetail.setClientAuthMethods("[\"private_key_jwt\"]");
clientDetail.setCreatedtimes(LocalDateTime.now());
clientDetail = clientDetailRepository.saveAndFlush(clientDetail);
Assertions.assertNotNull(clientDetail);

Optional<ClientDetail> result = clientDetailRepository.findById("C03");
Assertions.assertTrue(result.isPresent());
Assertions.assertNull(result.get().getEncPublicKey());
Assertions.assertNull(result.get().getEncPublicKeyHash());
}

@Test
public void updateClientDetail_withEncPublicKey_thenPass() {
// First create a client without enc keys
ClientDetail clientDetail = new ClientDetail();
clientDetail.setId("C04");
clientDetail.setName("Client-04");
clientDetail.setLogoUri("https://clienapp.com/logo.png");
clientDetail.setStatus("ACTIVE");
clientDetail.setRedirectUris("[\"https://clientapp.com/home\"]");
clientDetail.setPublicKey("DUMMY PEM CERT");
clientDetail.setPublicKeyHash(UUID.randomUUID().toString());
clientDetail.setRpId("RP04");
clientDetail.setClaims("[]");
clientDetail.setAcrValues("[]");
clientDetail.setGrantTypes("[\"authorization_code\"]");
clientDetail.setClientAuthMethods("[\"private_key_jwt\"]");
clientDetail.setCreatedtimes(LocalDateTime.now());
clientDetail = clientDetailRepository.saveAndFlush(clientDetail);
Assertions.assertNotNull(clientDetail);
Assertions.assertNull(clientDetail.getEncPublicKey());

// Now update with enc keys
clientDetail.setEncPublicKey("UPDATED ENC PUBLIC KEY");
clientDetail.setEncPublicKeyHash(UUID.randomUUID().toString());
clientDetail.setUpdatedtimes(LocalDateTime.now());
clientDetail = clientDetailRepository.saveAndFlush(clientDetail);

Optional<ClientDetail> result = clientDetailRepository.findById("C04");
Assertions.assertTrue(result.isPresent());
Assertions.assertNotNull(result.get().getEncPublicKey());
Assertions.assertEquals("UPDATED ENC PUBLIC KEY", result.get().getEncPublicKey());
}
}
Loading
Loading