diff --git a/components/org.wso2.carbon.identity.notification.push.common/pom.xml b/components/org.wso2.carbon.identity.notification.push.common/pom.xml
index d60dce2..52e1dbc 100644
--- a/components/org.wso2.carbon.identity.notification.push.common/pom.xml
+++ b/components/org.wso2.carbon.identity.notification.push.common/pom.xml
@@ -21,7 +21,7 @@
org.wso2.carbon.identity.notification.push
identity-notification-push
- 1.1.6-SNAPSHOT
+ 1.2.2-SNAPSHOT
../../pom.xml
diff --git a/components/org.wso2.carbon.identity.notification.push.common/src/main/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidator.java b/components/org.wso2.carbon.identity.notification.push.common/src/main/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidator.java
index f680766..f8f8b04 100644
--- a/components/org.wso2.carbon.identity.notification.push.common/src/main/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidator.java
+++ b/components/org.wso2.carbon.identity.notification.push.common/src/main/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ * Copyright (c) 2025-2026, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
@@ -36,6 +36,7 @@
import java.text.ParseException;
import java.util.Base64;
import java.util.Date;
+import java.util.Map;
/**
* JWT token validator for Push notification scenarios.
@@ -81,6 +82,21 @@ public static JWTClaimsSet getValidatedClaimSet(String jwt, String publicKey) th
}
}
+ /**
+ * Validate the JWT token and return the claim values.
+ *
+ * @param jwt JWT token to be validated
+ * @param publicKey Public key used for signing the JWT
+ * @return Map of claim values
+ * @throws PushTokenValidationException Error when validating the JWT token
+ */
+ public static Map getValidatedClaims(String jwt, String publicKey)
+ throws PushTokenValidationException {
+
+ JWTClaimsSet claimsSet = getValidatedClaimSet(jwt, publicKey);
+ return claimsSet.getClaims();
+ }
+
/**
* Validate the legitimacy of JWT token.
*
diff --git a/components/org.wso2.carbon.identity.notification.push.common/src/test/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidatorTest.java b/components/org.wso2.carbon.identity.notification.push.common/src/test/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidatorTest.java
index 167ae31..229e420 100644
--- a/components/org.wso2.carbon.identity.notification.push.common/src/test/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidatorTest.java
+++ b/components/org.wso2.carbon.identity.notification.push.common/src/test/java/org/wso2/carbon/identity/notification/push/common/PushChallengeValidatorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ * Copyright (c) 2025-2026, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
@@ -31,6 +31,8 @@
import java.text.ParseException;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@@ -141,6 +143,89 @@ public void testGetValidatedClaimSetWithExpiredToken() throws Exception {
}
}
+ @Test
+ public void testGetValidatedClaimsWithValidToken() throws Exception {
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)) {
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ Map expectedClaims = new HashMap<>();
+ expectedClaims.put("chg", "e0c3d04c-750b-4301-8f76-e07ebf02e53a");
+ expectedClaims.put("td", "carbon.super");
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+ when(mockClaimsSet.getClaims()).thenReturn(expectedClaims);
+
+ Map claims = PushChallengeValidator.getValidatedClaims(validJwt, publicKey);
+ assertNotNull(claims);
+ }
+ }
+
+ @Test(expectedExceptions = PushTokenValidationException.class)
+ public void testGetValidatedClaimsWithBlankToken() throws Exception {
+
+ PushChallengeValidator.getValidatedClaims("", publicKey);
+ }
+
+ @Test(expectedExceptions = PushTokenValidationException.class)
+ public void testGetValidatedClaimsWithInvalidJwtToken() throws Exception {
+
+ PushChallengeValidator.getValidatedClaims(invalidJwt, publicKey);
+ }
+
+ @Test(expectedExceptions = PushTokenValidationException.class)
+ public void testGetValidatedClaimsWithExpiredToken() throws Exception {
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)) {
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+ PushChallengeValidator.getValidatedClaims(validJwt, publicKey);
+ }
+ }
+
+ @Test(expectedExceptions = PushTokenValidationException.class)
+ public void testGetValidatedClaimsWithInvalidSignature() throws Exception {
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)) {
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(null);
+ PushChallengeValidator.getValidatedClaims(validJwt, invalidPublicKey);
+ }
+ }
+
+ @Test
+ public void testGetValidatedClaimsReturnsCorrectClaimValues() throws Exception {
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)) {
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ Map expectedClaims = new HashMap<>();
+ expectedClaims.put("td", "carbon.super");
+ expectedClaims.put("pid", "f5ae6a0d-390a-4eea-a380-8bcc86e4a148");
+ expectedClaims.put("chg", "e0c3d04c-750b-4301-8f76-e07ebf02e53a");
+ expectedClaims.put("res", "APPROVED");
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+ when(mockClaimsSet.getClaims()).thenReturn(expectedClaims);
+
+ Map claims = PushChallengeValidator.getValidatedClaims(validJwt, publicKey);
+ assertNotNull(claims);
+ Assert.assertEquals(claims.get("td"), "carbon.super");
+ Assert.assertEquals(claims.get("pid"), "f5ae6a0d-390a-4eea-a380-8bcc86e4a148");
+ Assert.assertEquals(claims.get("chg"), "e0c3d04c-750b-4301-8f76-e07ebf02e53a");
+ Assert.assertEquals(claims.get("res"), "APPROVED");
+ Assert.assertEquals(claims.size(), 4);
+ }
+ }
+
@Test
public void testValidateChallengeWithEmptyClaimsSet() {
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/pom.xml b/components/org.wso2.carbon.identity.notification.push.device.handler/pom.xml
index 4943ba1..a992db8 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/pom.xml
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/pom.xml
@@ -21,7 +21,7 @@
org.wso2.carbon.identity.notification.push
identity-notification-push
- 1.1.6-SNAPSHOT
+ 1.2.2-SNAPSHOT
../../pom.xml
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/DeviceHandlerService.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/DeviceHandlerService.java
index dbab23e..4d5ce01 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/DeviceHandlerService.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/DeviceHandlerService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ * Copyright (c) 2025-2026, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
@@ -92,6 +92,15 @@ Device registerDevice(RegistrationRequest registrationRequest, String tenantDoma
*/
void editDevice(String deviceId, String path, String value) throws PushDeviceHandlerException;
+ /**
+ * Edit the device from mobile.
+ *
+ * @param deviceId Device ID.
+ * @param token Token.
+ * @throws PushDeviceHandlerException Push Device Handler Exception.
+ */
+ default void editDeviceMobile(String deviceId, String token) throws PushDeviceHandlerException{}
+
/**
* Get registration discovery data.
*
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/constant/PushDeviceHandlerConstants.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/constant/PushDeviceHandlerConstants.java
index 7a6f958..72be7d8 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/constant/PushDeviceHandlerConstants.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/constant/PushDeviceHandlerConstants.java
@@ -30,6 +30,8 @@ public class PushDeviceHandlerConstants {
public static final String DEVICE_REGISTRATION_CONTEXT_VALIDITY_PERIOD =
"PushAuthenticator.DeviceRegistrationContext.ValidityPeriod";
public static final int DEFAULT_DEVICE_REGISTRATION_CONTEXT_VALIDITY_PERIOD = 180;
+ public static final String DEVICE_NAME = "name";
+ public static final String DEVICE_TOKEN = "deviceToken";
/**
* Private constructor to prevent initialization of the class.
@@ -56,7 +58,7 @@ public static class SQLQueries {
public static final String GET_PUBLIC_KEY_BY_ID = "SELECT PUBLIC_KEY FROM IDN_PUSH_DEVICE_STORE " +
"WHERE ID = :ID;";
public static final String UNREGISTER_DEVICE = "DELETE FROM IDN_PUSH_DEVICE_STORE WHERE ID = :ID;";
- public static final String EDIT_DEVICE = "UPDATE IDN_PUSH_DEVICE_STORE SET DEVICE_NAME = :DEVICE_NAME; " +
+ public static final String EDIT_DEVICE = "UPDATE IDN_PUSH_DEVICE_STORE SET DEVICE_NAME = :DEVICE_NAME;, " +
"DEVICE_TOKEN = :DEVICE_TOKEN; WHERE ID = :ID;";
}
@@ -136,6 +138,10 @@ public enum ErrorMessages {
ERROR_CODE_FAILED_TO_RESOLVE_PUSH_PROVIDER(
"PDH-15013",
"Failed to resolve the correct push provider for the request."
+ ),
+ ERROR_CODE_DEVICE_EDIT_FAILED(
+ "PDH-150014",
+ "Error occurred while updating the device for the device ID: %s."
);
private final String code;
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImpl.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImpl.java
index 320092b..94d68d9 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImpl.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImpl.java
@@ -71,7 +71,10 @@
import java.util.UUID;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.DEFAULT_PUSH_PROVIDER;
+import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.DEVICE_NAME;
+import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.DEVICE_TOKEN;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_ALREADY_REGISTERED;
+import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_EDIT_FAILED;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_NOT_FOUND;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_NOT_FOUND_FOR_USER_ID;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_REGISTRATION_FAILED;
@@ -135,6 +138,11 @@ public Device registerDevice(RegistrationRequest registrationRequest, String ten
device = handleDeviceRegistration(registrationRequest, context);
if (context.isRegistered()) {
deviceRegistrationContextManager.clearContext(registrationRequest.getDeviceId(), tenantDomain);
+ AUDIT_LOGGER.printAuditLog(
+ DeviceHandlerAuditLogger.Operation.REGISTER_DEVICE,
+ deviceId,
+ device.getUserId()
+ );
} else {
throw new PushDeviceHandlerClientException(ERROR_CODE_DEVICE_REGISTRATION_FAILED.getCode(),
String.format(ERROR_CODE_DEVICE_REGISTRATION_FAILED.getMessage(), deviceId));
@@ -245,6 +253,62 @@ public void editDevice(String deviceId, String path, String value) throws PushDe
Device device = getDevice(deviceId);
handleEditDevice(device, path, value);
+ AUDIT_LOGGER.printAuditLog(
+ DeviceHandlerAuditLogger.Operation.UPDATE_DEVICE,
+ deviceId,
+ device.getUserId()
+ );
+ }
+
+ @Override
+ public void editDeviceMobile(String deviceId, String token) throws PushDeviceHandlerException {
+
+ Optional deviceOptional = deviceDAO.getDevice(deviceId);
+ if (!deviceOptional.isPresent()) {
+ throw new PushDeviceHandlerClientException(ERROR_CODE_DEVICE_NOT_FOUND.getCode(),
+ String.format(ERROR_CODE_DEVICE_NOT_FOUND.getMessage(), deviceId));
+ }
+ Device device = deviceOptional.get();
+
+ Map claims;
+ try {
+ claims = PushChallengeValidator.getValidatedClaims(token, device.getPublicKey());
+ } catch (PushTokenValidationException e) {
+ throw new PushDeviceHandlerClientException(ERROR_CODE_TOKEN_CLAIM_VERIFICATION_FAILED.getCode(),
+ String.format(ERROR_CODE_TOKEN_CLAIM_VERIFICATION_FAILED.getMessage(), deviceId), e);
+ }
+
+ validateDeviceEditClaims(claims, deviceId);
+
+ String deviceToken = null;
+ String deviceName = null;
+
+ if (claims.containsKey(DEVICE_TOKEN)) {
+ deviceToken = (String) claims.get(DEVICE_TOKEN);
+ }
+
+ if (claims.containsKey(DEVICE_NAME)) {
+ deviceName = (String) claims.get(DEVICE_NAME);
+ }
+
+ if (deviceToken == null && deviceName == null) {
+ throw new PushDeviceHandlerClientException(ERROR_CODE_DEVICE_EDIT_FAILED.getCode(),
+ String.format(ERROR_CODE_DEVICE_EDIT_FAILED.getMessage(), deviceId));
+ }
+ if (deviceToken != null) {
+ device.setDeviceToken(deviceToken);
+ }
+ if (deviceName != null) {
+ device.setDeviceName(deviceName);
+ }
+
+ handleUpdateDeviceForProvider(device);
+ deviceDAO.editDevice(device.getDeviceId(), device);
+ AUDIT_LOGGER.printAuditLog(
+ DeviceHandlerAuditLogger.Operation.UPDATE_DEVICE,
+ deviceId,
+ device.getUserId()
+ );
}
@Override
@@ -673,4 +737,25 @@ public static PushSenderData buildPushSenderData(PushSenderDTO pushSenderDTO) {
pushSenderData.setProviderId(pushSenderDTO.getProviderId());
return pushSenderData;
}
+
+ /**
+ * Validate the claims in the edit device token.
+ *
+ * @param claims Claims to validate.
+ * @param deviceId Device ID for error messages.
+ * @throws PushDeviceHandlerClientException If the claims are invalid.
+ */
+ private static void validateDeviceEditClaims(Map claims, String deviceId)
+ throws PushDeviceHandlerClientException {
+
+ if (claims.containsKey(DEVICE_TOKEN) && !(claims.get(DEVICE_TOKEN) instanceof String)) {
+ throw new PushDeviceHandlerClientException(ERROR_CODE_DEVICE_EDIT_FAILED.getCode(),
+ String.format(ERROR_CODE_DEVICE_EDIT_FAILED.getMessage(), deviceId));
+ }
+
+ if (claims.containsKey(DEVICE_NAME) && !(claims.get(DEVICE_NAME) instanceof String)) {
+ throw new PushDeviceHandlerClientException(ERROR_CODE_DEVICE_EDIT_FAILED.getCode(),
+ String.format(ERROR_CODE_DEVICE_EDIT_FAILED.getMessage(), deviceId));
+ }
+ }
}
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLogger.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLogger.java
index b3b2d33..d252301 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLogger.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/main/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLogger.java
@@ -45,7 +45,7 @@ public class DeviceHandlerAuditLogger {
*/
public void printAuditLog(Operation operation, String deviceId, String userId) {
- JSONObject data = createAuditLogEntry(userId);
+ JSONObject data = createAuditLogEntry(operation, userId);
buildAuditLog(operation, deviceId, data);
}
@@ -72,11 +72,21 @@ private void buildAuditLog(Operation operation, String targetId, JSONObject data
*
* @return Audit log data.
*/
- private JSONObject createAuditLogEntry(String userId) {
+ private JSONObject createAuditLogEntry(Operation operation, String userId) {
JSONObject data = new JSONObject();
data.put(LogConstants.END_USER_ID, userId != null ? userId : JSONObject.NULL);
- data.put(LogConstants.UNREGISTERED_AT, System.currentTimeMillis());
+ switch (operation) {
+ case REGISTER_DEVICE:
+ data.put(LogConstants.REGISTERED_AT, System.currentTimeMillis());
+ break;
+ case UPDATE_DEVICE:
+ data.put(LogConstants.UPDATED_AT, System.currentTimeMillis());
+ break;
+ case UNREGISTER_DEVICE:
+ data.put(LogConstants.UNREGISTERED_AT, System.currentTimeMillis());
+ break;
+ }
return data;
}
@@ -128,6 +138,8 @@ private String getInitiatorId() {
*/
public enum Operation {
+ REGISTER_DEVICE("Register-Push-Auth-Device"),
+ UPDATE_DEVICE("Update-Push-Auth-Device"),
UNREGISTER_DEVICE("Unregister-Push-Auth-Device");
private final String logAction;
@@ -150,6 +162,8 @@ private static class LogConstants {
public static final String TARGET_TYPE_FIELD = "Push-Auth-Device";
public static final String END_USER_ID = "UserId";
+ public static final String REGISTERED_AT = "RegisteredAt";
+ public static final String UPDATED_AT = "UpdatedAt";
public static final String UNREGISTERED_AT = "UnregisteredAt";
}
}
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/dao/DeviceDAOImplTest.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/dao/DeviceDAOImplTest.java
index 8376fbe..8dc9a8e 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/dao/DeviceDAOImplTest.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/dao/DeviceDAOImplTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
+ * Copyright (c) 2025-2026, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
@@ -42,7 +42,7 @@ public class DeviceDAOImplTest {
"DEVICE_MODEL, DEVICE_TOKEN, DEVICE_HANDLE, PROVIDER, PUBLIC_KEY, TENANT_ID) VALUES " +
"( ? , ? , ? , ? , ? , ? , ? , ? , ? )";
public static final String UNREGISTER_DEVICE_TEST = "DELETE FROM IDN_PUSH_DEVICE_STORE WHERE ID = ? ";
- public static final String EDIT_DEVICE_TEST = "UPDATE IDN_PUSH_DEVICE_STORE SET DEVICE_NAME = ? " +
+ public static final String EDIT_DEVICE_TEST = "UPDATE IDN_PUSH_DEVICE_STORE SET DEVICE_NAME = ? , " +
"DEVICE_TOKEN = ? WHERE ID = ? ";
private DeviceDAOImpl deviceDAO;
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImplTest.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImplTest.java
index ed63812..98b5d36 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImplTest.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/impl/DeviceHandlerServiceImplTest.java
@@ -1010,6 +1010,515 @@ public void testEditDeviceWhenPushProviderServerExceptionThrown()
}
}
+ @Test
+ public void testEditDeviceMobileWithBothFields()
+ throws PushDeviceHandlerException, NotificationSenderManagementException, PushProviderException,
+ JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedIdentityTenantUtil =
+ Mockito.mockStatic(IdentityTenantUtil.class);
+ MockedStatic mockedPushDeviceHandlerDataHolder =
+ Mockito.mockStatic(PushDeviceHandlerDataHolder.class);
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(any())).thenReturn(-1234);
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", "newDeviceToken");
+ claims.put("name", "newDeviceName");
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+ when(mockClaimsSet.getStringClaim("deviceToken")).thenReturn("newDeviceToken");
+ when(mockClaimsSet.getStringClaim("name")).thenReturn("newDeviceName");
+
+ PushDeviceHandlerDataHolder pushDeviceHandlerDataHolder = mock(PushDeviceHandlerDataHolder.class);
+ mockedPushDeviceHandlerDataHolder.when(PushDeviceHandlerDataHolder::getInstance)
+ .thenReturn(pushDeviceHandlerDataHolder);
+
+ NotificationSenderManagementService notificationSenderManagementService =
+ mock(NotificationSenderManagementService.class);
+ when(pushDeviceHandlerDataHolder.getNotificationSenderManagementService())
+ .thenReturn(notificationSenderManagementService);
+ PushSenderDTO pushSenderDTO = new PushSenderDTO();
+ pushSenderDTO.setName("FCM_PushPublisher");
+ pushSenderDTO.setProvider("FCM");
+ pushSenderDTO.setProviderId("fcm-provider-id");
+ List pushSenders = new ArrayList<>();
+ pushSenders.add(pushSenderDTO);
+ when(notificationSenderManagementService.getPushSenders(anyBoolean()))
+ .thenReturn(pushSenders);
+
+ FCMPushProvider fcmPushProvider = mock(FCMPushProvider.class);
+ when(pushDeviceHandlerDataHolder.getPushProvider(eq("FCM"))).thenReturn(fcmPushProvider);
+ when(fcmPushProvider.getName()).thenReturn("FCM");
+ doNothing().when(fcmPushProvider).updateDevice(any(), any());
+
+ doNothing().when(deviceDAO).editDevice(anyString(), any());
+ Mockito.clearInvocations(deviceDAO);
+
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+
+ verify(fcmPushProvider, times(1)).updateDevice(any(), any());
+ verify(deviceDAO, times(1)).editDevice(anyString(), any());
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileWithTokenOnly()
+ throws PushDeviceHandlerException, NotificationSenderManagementException, PushProviderException,
+ JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedIdentityTenantUtil =
+ Mockito.mockStatic(IdentityTenantUtil.class);
+ MockedStatic mockedPushDeviceHandlerDataHolder =
+ Mockito.mockStatic(PushDeviceHandlerDataHolder.class);
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(any())).thenReturn(-1234);
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", "newDeviceToken");
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+ when(mockClaimsSet.getStringClaim("deviceToken")).thenReturn("newDeviceToken");
+
+ PushDeviceHandlerDataHolder pushDeviceHandlerDataHolder = mock(PushDeviceHandlerDataHolder.class);
+ mockedPushDeviceHandlerDataHolder.when(PushDeviceHandlerDataHolder::getInstance)
+ .thenReturn(pushDeviceHandlerDataHolder);
+
+ NotificationSenderManagementService notificationSenderManagementService =
+ mock(NotificationSenderManagementService.class);
+ when(pushDeviceHandlerDataHolder.getNotificationSenderManagementService())
+ .thenReturn(notificationSenderManagementService);
+ PushSenderDTO pushSenderDTO = new PushSenderDTO();
+ pushSenderDTO.setName("FCM_PushPublisher");
+ pushSenderDTO.setProvider("FCM");
+ pushSenderDTO.setProviderId("fcm-provider-id");
+ List pushSenders = new ArrayList<>();
+ pushSenders.add(pushSenderDTO);
+ when(notificationSenderManagementService.getPushSenders(anyBoolean()))
+ .thenReturn(pushSenders);
+
+ FCMPushProvider fcmPushProvider = mock(FCMPushProvider.class);
+ when(pushDeviceHandlerDataHolder.getPushProvider(eq("FCM"))).thenReturn(fcmPushProvider);
+ when(fcmPushProvider.getName()).thenReturn("FCM");
+ doNothing().when(fcmPushProvider).updateDevice(any(), any());
+
+ doNothing().when(deviceDAO).editDevice(anyString(), any());
+ Mockito.clearInvocations(deviceDAO);
+
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+
+ verify(fcmPushProvider, times(1)).updateDevice(any(), any());
+ verify(deviceDAO, times(1)).editDevice(anyString(), any());
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileWithNameOnly()
+ throws PushDeviceHandlerException, NotificationSenderManagementException, PushProviderException,
+ JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedIdentityTenantUtil =
+ Mockito.mockStatic(IdentityTenantUtil.class);
+ MockedStatic mockedPushDeviceHandlerDataHolder =
+ Mockito.mockStatic(PushDeviceHandlerDataHolder.class);
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(any())).thenReturn(-1234);
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ claims.put("name", "newDeviceName");
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+ when(mockClaimsSet.getStringClaim("name")).thenReturn("newDeviceName");
+
+ PushDeviceHandlerDataHolder pushDeviceHandlerDataHolder = mock(PushDeviceHandlerDataHolder.class);
+ mockedPushDeviceHandlerDataHolder.when(PushDeviceHandlerDataHolder::getInstance)
+ .thenReturn(pushDeviceHandlerDataHolder);
+
+ NotificationSenderManagementService notificationSenderManagementService =
+ mock(NotificationSenderManagementService.class);
+ when(pushDeviceHandlerDataHolder.getNotificationSenderManagementService())
+ .thenReturn(notificationSenderManagementService);
+ PushSenderDTO pushSenderDTO = new PushSenderDTO();
+ pushSenderDTO.setName("FCM_PushPublisher");
+ pushSenderDTO.setProvider("FCM");
+ pushSenderDTO.setProviderId("fcm-provider-id");
+ List pushSenders = new ArrayList<>();
+ pushSenders.add(pushSenderDTO);
+ when(notificationSenderManagementService.getPushSenders(anyBoolean()))
+ .thenReturn(pushSenders);
+
+ FCMPushProvider fcmPushProvider = mock(FCMPushProvider.class);
+ when(pushDeviceHandlerDataHolder.getPushProvider(eq("FCM"))).thenReturn(fcmPushProvider);
+ when(fcmPushProvider.getName()).thenReturn("FCM");
+ doNothing().when(fcmPushProvider).updateDevice(any(), any());
+
+ doNothing().when(deviceDAO).editDevice(anyString(), any());
+ Mockito.clearInvocations(deviceDAO);
+
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+
+ verify(fcmPushProvider, times(1)).updateDevice(any(), any());
+ verify(deviceDAO, times(1)).editDevice(anyString(), any());
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileDeviceNotFound() throws PushDeviceHandlerException {
+
+ Optional device = Optional.empty();
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+
+ @Test
+ public void testEditDeviceMobileWithInvalidDeviceTokenClaimType()
+ throws PushDeviceHandlerException, JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ // Set deviceToken claim as a non-String type (Integer) to trigger validation failure.
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", 12345);
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileWithInvalidDeviceNameClaimType()
+ throws PushDeviceHandlerException, JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ // Set name claim as a non-String type (Boolean) to trigger validation failure.
+ Map claims = new HashMap<>();
+ claims.put("name", true);
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileWithBothInvalidClaimTypes()
+ throws PushDeviceHandlerException, JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ // Set both claims as non-String types. The deviceToken check runs first.
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", 12345);
+ claims.put("name", 67890);
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileTokenValidationFailed()
+ throws PushDeviceHandlerException, JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(false);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileNoEditableFields()
+ throws PushDeviceHandlerException, JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileProviderClientException()
+ throws PushDeviceHandlerException, NotificationSenderManagementException, PushProviderException,
+ JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedIdentityTenantUtil =
+ Mockito.mockStatic(IdentityTenantUtil.class);
+ MockedStatic mockedPushDeviceHandlerDataHolder =
+ Mockito.mockStatic(PushDeviceHandlerDataHolder.class);
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(any())).thenReturn(-1234);
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", "newDeviceToken");
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+ when(mockClaimsSet.getStringClaim("deviceToken")).thenReturn("newDeviceToken");
+
+ PushDeviceHandlerDataHolder pushDeviceHandlerDataHolder = mock(PushDeviceHandlerDataHolder.class);
+ mockedPushDeviceHandlerDataHolder.when(PushDeviceHandlerDataHolder::getInstance)
+ .thenReturn(pushDeviceHandlerDataHolder);
+
+ NotificationSenderManagementService notificationSenderManagementService =
+ mock(NotificationSenderManagementService.class);
+ when(pushDeviceHandlerDataHolder.getNotificationSenderManagementService())
+ .thenReturn(notificationSenderManagementService);
+ PushSenderDTO pushSenderDTO = new PushSenderDTO();
+ pushSenderDTO.setName("FCM_PushPublisher");
+ pushSenderDTO.setProvider("FCM");
+ pushSenderDTO.setProviderId("fcm-provider-id");
+ List pushSenders = new ArrayList<>();
+ pushSenders.add(pushSenderDTO);
+ when(notificationSenderManagementService.getPushSenders(anyBoolean()))
+ .thenReturn(pushSenders);
+
+ FCMPushProvider fcmPushProvider = mock(FCMPushProvider.class);
+ when(pushDeviceHandlerDataHolder.getPushProvider(eq("FCM"))).thenReturn(fcmPushProvider);
+ when(fcmPushProvider.getName()).thenReturn("FCM");
+ PushProviderClientException ppce = new PushProviderClientException(
+ "ERR_DEVICE_UPDATE", "Failed to update device at provider");
+ doThrow(ppce).when(fcmPushProvider).updateDevice(any(), any());
+
+ Assert.assertThrows(PushDeviceHandlerClientException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
+ @Test
+ public void testEditDeviceMobileProviderServerException()
+ throws PushDeviceHandlerException, NotificationSenderManagementException, PushProviderException,
+ JOSEException, ParseException {
+
+ try (
+ MockedStatic mockedIdentityTenantUtil =
+ Mockito.mockStatic(IdentityTenantUtil.class);
+ MockedStatic mockedPushDeviceHandlerDataHolder =
+ Mockito.mockStatic(PushDeviceHandlerDataHolder.class);
+ MockedStatic mockedStatic = Mockito.mockStatic(SignedJWT.class)
+ ) {
+
+ mockedIdentityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(any())).thenReturn(-1234);
+
+ Device deviceObj = new Device();
+ deviceObj.setDeviceId("1234567890");
+ deviceObj.setProvider("FCM");
+ deviceObj.setDeviceToken(deviceToken);
+ deviceObj.setPublicKey(publicKey);
+ Optional device = Optional.of(deviceObj);
+ when(deviceDAO.getDevice(anyString())).thenReturn(device);
+
+ mockedStatic.when(() -> SignedJWT.parse(validJwt)).thenReturn(mockSignedJWT);
+
+ when(mockSignedJWT.getJWTClaimsSet()).thenReturn(mockClaimsSet);
+ when(mockClaimsSet.getExpirationTime()).thenReturn(new Date(System.currentTimeMillis() + 3000000));
+ when(mockClaimsSet.getNotBeforeTime()).thenReturn(new Date(System.currentTimeMillis() - 3000000));
+ when(mockSignedJWT.verify(any())).thenReturn(true);
+
+ Map claims = new HashMap<>();
+ claims.put("deviceToken", "newDeviceToken");
+ when(mockClaimsSet.getClaims()).thenReturn(claims);
+ when(mockClaimsSet.getStringClaim("deviceToken")).thenReturn("newDeviceToken");
+
+ PushDeviceHandlerDataHolder pushDeviceHandlerDataHolder = mock(PushDeviceHandlerDataHolder.class);
+ mockedPushDeviceHandlerDataHolder.when(PushDeviceHandlerDataHolder::getInstance)
+ .thenReturn(pushDeviceHandlerDataHolder);
+
+ NotificationSenderManagementService notificationSenderManagementService =
+ mock(NotificationSenderManagementService.class);
+ when(pushDeviceHandlerDataHolder.getNotificationSenderManagementService())
+ .thenReturn(notificationSenderManagementService);
+ PushSenderDTO pushSenderDTO = new PushSenderDTO();
+ pushSenderDTO.setName("FCM_PushPublisher");
+ pushSenderDTO.setProvider("FCM");
+ pushSenderDTO.setProviderId("fcm-provider-id");
+ List pushSenders = new ArrayList<>();
+ pushSenders.add(pushSenderDTO);
+ when(notificationSenderManagementService.getPushSenders(anyBoolean()))
+ .thenReturn(pushSenders);
+
+ PushProviderServerException ppse = new PushProviderServerException(
+ "ERR_PROVIDER_SERVER", "Provider service temporarily unavailable");
+ org.wso2.carbon.identity.notification.push.provider.PushProvider pushProvider =
+ mock(org.wso2.carbon.identity.notification.push.provider.PushProvider.class);
+ when(pushDeviceHandlerDataHolder.getPushProvider(eq("FCM"))).thenReturn(pushProvider);
+ when(pushProvider.getName()).thenReturn("FCM");
+ doThrow(ppse).when(pushProvider).updateDevice(any(), any());
+
+ Assert.assertThrows(PushDeviceHandlerServerException.class, () -> {
+ deviceHandlerService.editDeviceMobile("1234567890", validJwt);
+ });
+ }
+ }
+
@Test
public void testGetRegistrationDiscoveryData() throws PushDeviceHandlerException {
diff --git a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLoggerTest.java b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLoggerTest.java
index 863fd22..a44a72b 100644
--- a/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLoggerTest.java
+++ b/components/org.wso2.carbon.identity.notification.push.device.handler/src/test/java/org/wso2/carbon/identity/notification/push/device/handler/utils/DeviceHandlerAuditLoggerTest.java
@@ -130,9 +130,11 @@ public void testGetUserWithSystemUser() throws Exception {
public void testCreateAuditLogEntryWithValidData() throws Exception {
Method createAuditLogEntryMethod = DeviceHandlerAuditLogger.class
- .getDeclaredMethod("createAuditLogEntry", String.class);
+ .getDeclaredMethod("createAuditLogEntry",
+ DeviceHandlerAuditLogger.Operation.class, String.class);
createAuditLogEntryMethod.setAccessible(true);
- JSONObject result = (JSONObject) createAuditLogEntryMethod.invoke(auditLogger, "testUserId");
+ JSONObject result = (JSONObject) createAuditLogEntryMethod.invoke(
+ auditLogger, DeviceHandlerAuditLogger.Operation.UNREGISTER_DEVICE, "testUserId");
Assert.assertNotNull(result);
Assert.assertTrue(result.has("UserId"));
@@ -141,6 +143,46 @@ public void testCreateAuditLogEntryWithValidData() throws Exception {
Assert.assertTrue(result.getLong("UnregisteredAt") > 0);
}
+ /**
+ * Test the private method 'createAuditLogEntry' with register device operation.
+ */
+ @Test
+ public void testCreateAuditLogEntryWithRegisterDevice() throws Exception {
+
+ Method createAuditLogEntryMethod = DeviceHandlerAuditLogger.class
+ .getDeclaredMethod("createAuditLogEntry",
+ DeviceHandlerAuditLogger.Operation.class, String.class);
+ createAuditLogEntryMethod.setAccessible(true);
+ JSONObject result = (JSONObject) createAuditLogEntryMethod.invoke(
+ auditLogger, DeviceHandlerAuditLogger.Operation.REGISTER_DEVICE, "testUserId");
+
+ Assert.assertNotNull(result);
+ Assert.assertTrue(result.has("UserId"));
+ Assert.assertEquals(result.getString("UserId"), "testUserId");
+ Assert.assertTrue(result.has("RegisteredAt"));
+ Assert.assertTrue(result.getLong("RegisteredAt") > 0);
+ }
+
+ /**
+ * Test the private method 'createAuditLogEntry' with update device operation.
+ */
+ @Test
+ public void testCreateAuditLogEntryWithUpdateDevice() throws Exception {
+
+ Method createAuditLogEntryMethod = DeviceHandlerAuditLogger.class
+ .getDeclaredMethod("createAuditLogEntry",
+ DeviceHandlerAuditLogger.Operation.class, String.class);
+ createAuditLogEntryMethod.setAccessible(true);
+ JSONObject result = (JSONObject) createAuditLogEntryMethod.invoke(
+ auditLogger, DeviceHandlerAuditLogger.Operation.UPDATE_DEVICE, "testUserId");
+
+ Assert.assertNotNull(result);
+ Assert.assertTrue(result.has("UserId"));
+ Assert.assertEquals(result.getString("UserId"), "testUserId");
+ Assert.assertTrue(result.has("UpdatedAt"));
+ Assert.assertTrue(result.getLong("UpdatedAt") > 0);
+ }
+
/**
* Test the private method 'getInitiatorId'.
*/
diff --git a/components/org.wso2.carbon.identity.notification.push.provider/pom.xml b/components/org.wso2.carbon.identity.notification.push.provider/pom.xml
index 8db1d11..79879c5 100644
--- a/components/org.wso2.carbon.identity.notification.push.provider/pom.xml
+++ b/components/org.wso2.carbon.identity.notification.push.provider/pom.xml
@@ -21,7 +21,7 @@
org.wso2.carbon.identity.notification.push
identity-notification-push
- 1.1.6-SNAPSHOT
+ 1.2.2-SNAPSHOT
../../pom.xml
diff --git a/features/org.wso2.carbon.identity.notification.push.feature/pom.xml b/features/org.wso2.carbon.identity.notification.push.feature/pom.xml
index f226db6..60dda18 100644
--- a/features/org.wso2.carbon.identity.notification.push.feature/pom.xml
+++ b/features/org.wso2.carbon.identity.notification.push.feature/pom.xml
@@ -23,7 +23,7 @@
org.wso2.carbon.identity.notification.push
identity-notification-push
- 1.1.6-SNAPSHOT
+ 1.2.2-SNAPSHOT
../../pom.xml
diff --git a/pom.xml b/pom.xml
index 05b9010..ba1e571 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
org.wso2.carbon.identity.notification.push
4.0.0
- 1.1.6-SNAPSHOT
+ 1.2.2-SNAPSHOT
identity-notification-push
pom
WSO2 Carbon - Identity Notification Push