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 @@ -51,6 +51,10 @@
<groupId>org.wso2.carbon.identity.organization.management.core</groupId>
<artifactId>org.wso2.carbon.identity.organization.management.service</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.event.handler.notification</groupId>
<artifactId>org.wso2.carbon.identity.event.handler.notification</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.event.handler.notification</groupId>
<artifactId>org.wso2.carbon.identity.notification.sender.tenant.config</artifactId>
Expand Down Expand Up @@ -95,6 +99,10 @@
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.central.log.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.configuration.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.google.firebase</groupId>
<artifactId>firebase-admin</artifactId>
Expand Down Expand Up @@ -139,12 +147,19 @@
org.json,
org.wso2.carbon.identity.central.log.mgt.utils;
version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.configuration.mgt.core; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.configuration.mgt.core.exception; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.configuration.mgt.core.model; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.configuration.mgt.core.constant; version="${carbon.identity.framework.imp.pkg.version.range}",
org.apache.commons.logging; version="${org.apache.commons.logging.range}",
org.apache.commons.collections,
org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",
org.wso2.carbon.identity.base; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.core; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.core.cache; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.core.context; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.core.context.model; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.core.util; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.organization.management.service;version="${org.wso2.carbon.identity.organization.management.core.version.range}",
org.wso2.carbon.identity.organization.management.service.exception;version="${org.wso2.carbon.identity.organization.management.core.version.range}",
Expand All @@ -168,6 +183,10 @@
org.wso2.carbon.user.core.common; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.context; version="${carbon.kernel.package.import.version.range}",
org.wso2.carbon.identity.event; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.event.event; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.event.services; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.governance.service.notification; version="${identity.governance.imp.pkg.version.range}",
</Import-Package>
</instructions>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import org.wso2.carbon.identity.notification.push.device.handler.model.RegistrationDiscoveryData;
import org.wso2.carbon.identity.notification.push.device.handler.model.RegistrationRequest;

import java.util.Collections;
import java.util.List;

/**
* Device Handler interface.
*/
Expand Down Expand Up @@ -60,6 +63,7 @@ Device registerDevice(RegistrationRequest registrationRequest, String tenantDoma
* Remove all devices of a registered user.
*
* @param userId User ID.
* @param tenantDomain Tenant Domain.
* @throws PushDeviceHandlerException Push Device Handler Exception.
*/
void unregisterDeviceByUserId(String userId, String tenantDomain) throws PushDeviceHandlerException;
Expand All @@ -77,11 +81,25 @@ Device registerDevice(RegistrationRequest registrationRequest, String tenantDoma
* Get a device by the user ID.
*
* @param userId User ID.
* @param tenantDomain Tenant Domain.
* @return Device.
* @throws PushDeviceHandlerException Push Device Handler Exception.
*/
Device getDeviceByUserId(String userId, String tenantDomain) throws PushDeviceHandlerException;

/**
* Get devices by the user ID.
*
* @param userId User ID.
* @param tenantDomain Tenant Domain.
* @return Device.
* @throws PushDeviceHandlerException Push Device Handler Exception.
*/
default List<Device> getDevicesByUserId(String userId, String tenantDomain) throws PushDeviceHandlerException {

return Collections.emptyList();
}

/**
* Edit the name of a registered device.
*
Expand Down Expand Up @@ -111,5 +129,4 @@ RegistrationDiscoveryData getRegistrationDiscoveryData(String username, String t
* @throws PushDeviceHandlerException Push Device Handler Exception.
*/
String getPublicKey(String deviceId) throws PushDeviceHandlerException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,104 @@ public class PushDeviceHandlerConstants {
"PushAuthenticator.DeviceRegistrationContext.ValidityPeriod";
public static final int DEFAULT_DEVICE_REGISTRATION_CONTEXT_VALIDITY_PERIOD = 180;

public static final String MAX_DEVICE_LIMIT_PER_USER = "PushAuthenticator.DeviceManagement.MaxDeviceLimitPerUser";
public static final int DEFAULT_MAX_DEVICE_LIMIT_PER_USER = 10;
public static final int DEFAULT_MIN_DEVICE_LIMIT_PER_USER = 2;
public static final String PUSH_DEVICE_MGT_RESOURCE_TYPE = "DEVICE_MANAGEMENT";
public static final String PUSH_DEVICE_MGT_RESOURCE_NAME = "PUSH_DEVICE_MANAGEMENT";
public static final String ATTR_ENABLE_MULTIPLE_DEVICE_ENROLLMENT = "enableMultipleDeviceEnrollment";
public static final String ATTR_MAX_DEVICE_LIMIT = "maximumDeviceLimit";
public static final String ATTR_ENABLE_DEVICE_REGISTRATION_NOTIFICATIONS = "enableDeviceRegistrationNotifications";
public static final String ATTR_DEVICE_REGISTRATION_NOTIFICATION_CHANNELS =
"deviceRegistrationNotificationChannels";
public static final String NOTIFICATION_CHANNELS_SEPARATOR = ",";
public static final String REGISTRATION_TIME_FORMATTER_PATTERN = "yyyy-MM-dd HH:mm:ss 'UTC'";



/**
* Constants related to email notifications sent during device management operations.
*/
public static class EmailNotificationConstants {

public static final String PUSH_DEVICE_REGISTRATION_TEMPLATE = "PushDeviceRegistration";

// Placeholders used in the template body
public static final String DEVICE_NAME_PLACEHOLDER = "push-device-name";
public static final String DEVICE_MODEL_PLACEHOLDER = "push-device-model";
public static final String REGISTRATION_TIME_PLACEHOLDER = "registration-time";
public static final String IP_ADDRESS_PLACEHOLDER = "ip-address";
}

/**
* Constants related to push notifications sent during device management operations.
*/
public static final class PushNotificationConstants {

public static final String PUSH_NOTIFICATION_EVENT_NAME = "TRIGGER_PUSH_NOTIFICATION";
public static final String PUSH_NOTIFICATION_CHANNEL = "PUSH_NOTIFICATION";
Comment thread
raviendalpatadu marked this conversation as resolved.
public static final String NOTIFICATION_SCENARIO = "NOTIFICATION_SCENARIO";
public static final String DEVICE_REGISTRATION_SCENARIO = "DEVICE_REGISTRATION";
public static final String NOTIFICATION_PROVIDER = "notificationProvider";
public static final String DEVICE_TOKEN = "deviceToken";
public static final String DEVICE_ID = "deviceId";
public static final String DEVICE_HANDLE = "deviceHandle";
public static final String IP_ADDRESS = "ipAddress";

// Placeholders rendered in the push notification template.
public static final String DEVICE_NAME_PLACEHOLDER = "push-device-name";
public static final String DEVICE_MODEL_PLACEHOLDER = "push-device-model";
public static final String REGISTRATION_TIME_PLACEHOLDER = "registration-time";

/**
* Private constructor to prevent initialization of the class.
*/
private PushNotificationConstants() {

}
}

/**
* Constants related to diagnostic logging of device management operations.
*/
public static class LogConstants {

public static final String PUSH_DEVICE_HANDLER_SERVICE = "push-device-handler-service";

/**
* Action identifiers used in diagnostic logs.
*/
public static class ActionIDs {

public static final String TRIGGER_DEVICE_REGISTRATION_EMAIL_NOTIFICATION =
"trigger-device-registration-email-notification";
public static final String TRIGGER_DEVICE_REGISTRATION_PUSH_NOTIFICATION =
"trigger-device-registration-push-notification";

private ActionIDs() {

}
}

/**
* Input parameter keys used in diagnostic logs.
*/
public static class InputKeys {

public static final String DEVICE_ID = "device-id";
public static final String USER_ID = "user-id";
public static final String TENANT_DOMAIN = "tenant-domain";

private InputKeys() {

}
}

private LogConstants() {

}
}

/**
* Private constructor to prevent initialization of the class.
*/
Expand Down Expand Up @@ -136,6 +234,38 @@ public enum ErrorMessages {
ERROR_CODE_FAILED_TO_RESOLVE_PUSH_PROVIDER(
"PDH-15013",
"Failed to resolve the correct push provider for the request."
),
ERROR_CODE_GETTING_PUSH_DEVICE_CONFIG(
"PDH-15014",
"Failed to get push device configuration for the tenant."
),
ERROR_CODE_ADDING_PUSH_DEVICE_CONFIG(
"PDH-15015",
"Failed to add push device configuration for the tenant."
),
ERROR_CODE_UPDATING_PUSH_DEVICE_CONFIG(
"PDH-15016",
"Failed to update push device configuration for the tenant."
),
ERROR_CODE_INVALID_DEVICE_LIMIT_CONFIG(
"PDH-15017",
"Maximum device limit can only be updated when multiple device enrollment is enabled."
),
ERROR_CODE_DEVICE_LIMIT_PER_USER_EXCEEDS(
"PDH-15018",
"Maximum device limit cannot exceed the server-configured device registration per user."
),
ERROR_CODE_MAX_DEVICE_LIMIT_REACHED(
"PDH-15019",
"Maximum device limit reached for the user: %s."
),
ERROR_CODE_DEVICE_ID_ALREADY_REGISTERED(
"PDH-15020",
"Device is already registered for the device ID: %s."
),
ERROR_CODE_INVALID_DEVICE_LIMIT_VALUE(
"PDH-15021",
"Maximum device limit must be a positive value when multiple device enrollment is enabled."
);

private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

package org.wso2.carbon.identity.notification.push.device.handler.dao;

import org.wso2.carbon.identity.notification.push.device.handler.exception.PushDeviceHandlerException;
import org.wso2.carbon.identity.notification.push.device.handler.exception.PushDeviceHandlerServerException;
import org.wso2.carbon.identity.notification.push.device.handler.model.Device;

import java.util.List;
import java.util.Optional;

/**
Expand All @@ -33,9 +35,9 @@ public interface DeviceDAO {
*
* @param device Device to be registered.
* @param tenantId Tenant ID.
* @throws PushDeviceHandlerServerException PushDeviceHandlerServerException.
* @throws PushDeviceHandlerException PushDeviceHandlerException.
*/
void registerDevice(Device device, int tenantId) throws PushDeviceHandlerServerException;
void registerDevice(Device device, int tenantId) throws PushDeviceHandlerException;

/**
* Unregister a device.
Expand Down Expand Up @@ -67,11 +69,22 @@ public interface DeviceDAO {
* Get a device by the user ID.
*
* @param userId User ID.
* @param tenantId Tenant ID.
* @return Device.
* @throws PushDeviceHandlerServerException Push Device Handler Server Exception.
*/
Optional<Device> getDeviceByUserId(String userId, int tenantId) throws PushDeviceHandlerServerException;

/**
* Get all devices registered for a user.
*
* @param userId User ID.
* @param tenantId Tenant ID.
* @return List of registered devices, empty list if none found.
* @throws PushDeviceHandlerServerException Push Device Handler Server Exception.
*/
List<Device> getDevicesByUserId(String userId, int tenantId) throws PushDeviceHandlerServerException;

/**
* Get the public key of a device.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 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
Expand All @@ -21,14 +21,20 @@
import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants;
import org.wso2.carbon.identity.notification.push.device.handler.exception.PushDeviceHandlerClientException;
import org.wso2.carbon.identity.notification.push.device.handler.exception.PushDeviceHandlerException;
import org.wso2.carbon.identity.notification.push.device.handler.exception.PushDeviceHandlerServerException;
import org.wso2.carbon.identity.notification.push.device.handler.model.Device;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.ErrorMessages.ERROR_CODE_DEVICE_ID_ALREADY_REGISTERED;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.SQLQueries.EDIT_DEVICE;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.SQLQueries.GET_DEVICE_BY_DEVICE_ID;
import static org.wso2.carbon.identity.notification.push.device.handler.constant.PushDeviceHandlerConstants.SQLQueries.GET_DEVICE_BY_USER_ID;
Expand All @@ -42,7 +48,7 @@
public class DeviceDAOImpl implements DeviceDAO {

@Override
public void registerDevice(Device device, int tenantId) throws PushDeviceHandlerServerException {
public void registerDevice(Device device, int tenantId) throws PushDeviceHandlerException {

Connection connection = IdentityDatabaseUtil.getDBConnection(true);
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, REGISTER_DEVICE)) {
Expand All @@ -59,7 +65,13 @@ public void registerDevice(Device device, int tenantId) throws PushDeviceHandler
IdentityDatabaseUtil.commitTransaction(connection);
} catch (SQLException e) {
IdentityDatabaseUtil.rollbackTransaction(connection);
throw new PushDeviceHandlerServerException("Error occurred while registering the device.", e);
if (e instanceof SQLIntegrityConstraintViolationException) {
throw new PushDeviceHandlerClientException(
ERROR_CODE_DEVICE_ID_ALREADY_REGISTERED.getCode(),
ERROR_CODE_DEVICE_ID_ALREADY_REGISTERED.getMessage() + device.getDeviceId());
}
throw new PushDeviceHandlerServerException(
"Error occurred while registering the device.", e);
} finally {
IdentityDatabaseUtil.closeConnection(connection);
}
Expand Down Expand Up @@ -156,6 +168,39 @@ public Optional<Device> getDeviceByUserId(String userId, int tenantId) throws Pu
return Optional.ofNullable(device);
}

@Override
public List<Device> getDevicesByUserId(String userId, int tenantId)
throws PushDeviceHandlerServerException {

List<Device> devices = new ArrayList<>();
Connection connection = IdentityDatabaseUtil.getDBConnection(true);
try (NamedPreparedStatement statement =
new NamedPreparedStatement(connection, GET_DEVICE_BY_USER_ID)) {
statement.setString(PushDeviceHandlerConstants.ColumnNames.USER_ID, userId);
statement.setInt(PushDeviceHandlerConstants.ColumnNames.TENANT_ID, tenantId);
try (ResultSet resultSet = statement.executeQuery()) {
while (resultSet.next()) {
Device device = new Device();
device.setDeviceId(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.ID));
device.setUserId(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.USER_ID));
device.setDeviceName(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.DEVICE_NAME));
device.setDeviceModel(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.DEVICE_MODEL));
device.setDeviceToken(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.DEVICE_TOKEN));
device.setDeviceHandle(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.DEVICE_HANDLE));
device.setPublicKey(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.PUBLIC_KEY));
device.setProvider(resultSet.getString(PushDeviceHandlerConstants.ColumnNames.PROVIDER));
devices.add(device);
}
}
} catch (SQLException e) {
throw new PushDeviceHandlerServerException(
"Error occurred while retrieving devices for user.", e);
} finally {
IdentityDatabaseUtil.closeConnection(connection);
}
return devices;
}

@Override
public Optional<String> getPublicKey(String deviceId) throws PushDeviceHandlerServerException {

Expand Down
Loading
Loading