diff --git a/components/email-mgt/org.wso2.carbon.email.mgt.ui/pom.xml.versionsBackup b/components/email-mgt/org.wso2.carbon.email.mgt.ui/pom.xml.versionsBackup
new file mode 100644
index 000000000..f144bc222
--- /dev/null
+++ b/components/email-mgt/org.wso2.carbon.email.mgt.ui/pom.xml.versionsBackup
@@ -0,0 +1,93 @@
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt.ui
+ bundle
+ WSO2 Carbon - Email Management UI
+ A custom wso2 products or solution
+
+
+
+ org.apache.axis2.wso2
+ axis2
+
+
+ org.wso2.carbon
+ org.wso2.carbon.ui
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.base
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.stub
+
+
+ org.wso2.orbit.org.owasp.encoder
+ encoder
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ${project.artifactId}
+
+
+ org.wso2.carbon.email.mgt.ui.*;version="${identity.event.handler.notification.exp.pkg.version}",
+
+
+ org.apache.axis2;version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.client;version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.context;version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.commons.logging;version="${commons.logging.imp.pkg.version.range}",
+ org.wso2.carbon.email.mgt.model.xsd.*;version="${identity.event.handler.notification.imp.pkg.version.range}",
+ org.wso2.carbon.email.mgt.stub.*;version="${identity.event.handler.notification.imp.pkg.version.range}",
+
+ UIBundle
+
+
+
+
+
+
+
diff --git a/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml.versionsBackup b/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml.versionsBackup
new file mode 100644
index 000000000..0d9bee2fc
--- /dev/null
+++ b/components/email-mgt/org.wso2.carbon.email.mgt/pom.xml.versionsBackup
@@ -0,0 +1,223 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt
+ bundle
+ WSO2 Carbon - Email Management
+ A custom wso2 products or solution
+
+
+
+ org.wso2.carbon.identity.governance
+ org.wso2.carbon.identity.governance
+
+
+ org.apache.axis2.transport
+ axis2-transport-mail
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+
+
+ org.wso2.carbon
+ javax.cache.wso2
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.base
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.core
+
+
+ org.wso2.carbon.commons
+ org.wso2.carbon.tenant.common
+
+
+ com.google.code.gson
+ gson
+
+
+ org.testng
+ testng
+ test
+
+
+ org.powermock
+ powermock-module-testng
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ test
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ${project.artifactId}
+
+
+ org.wso2.carbon.email.mgt.internal,
+
+
+ !org.wso2.carbon.email.mgt.internal,
+ org.wso2.carbon.email.mgt.*;version="${identity.event.handler.notification.exp.pkg.version}",
+
+
+ javax.cache,
+ javax.xml.namespace,
+ org.apache.axiom.*; version="${axiom.wso2.imp.pkg.version.range}",
+ org.apache.commons.logging; version="${commons.logging.imp.pkg.version.range}",
+ org.apache.commons.lang.*; version="${commons-lang.version.range}",
+
+ 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.stratos.common.*; version="${carbon.commons.imp.pkg.version}",
+
+ com.google.gson.*; version="${com.google.code.gson.osgi.version.range}",
+
+ org.wso2.carbon.core;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.context;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.user.core.*;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.utils;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.utils.multitenancy;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}",
+ org.wso2.carbon.identity.core.*; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.registry.core.*;version="${carbon.kernel.registry.imp.pkg.version}",
+ org.wso2.carbon.identity.base; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.governance.*;version="${identity.governance.imp.pkg.version.range}"
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven.surefire.plugin.version}
+
+
+ src/test/resources/testng.xml
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ default-prepare-agent-integration
+
+ prepare-agent-integration
+
+
+
+ default-report
+
+ report
+
+
+
+ default-report-integration
+
+ report-integration
+
+
+
+ default-check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ COMPLEXITY
+ COVEREDRATIO
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+
+
+
+
diff --git a/components/event-handler-notification/org.wso2.carbon.identity.event.handler.notification/pom.xml.versionsBackup b/components/event-handler-notification/org.wso2.carbon.identity.event.handler.notification/pom.xml.versionsBackup
new file mode 100644
index 000000000..9b2e1373e
--- /dev/null
+++ b/components/event-handler-notification/org.wso2.carbon.identity.event.handler.notification/pom.xml.versionsBackup
@@ -0,0 +1,198 @@
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../../pom.xml
+
+ 4.0.0
+
+ org.wso2.carbon.identity.event.handler.notification
+ bundle
+ WSO2 Carbon - Notification Event Handling Management
+ A custom wso2 products or solution
+
+
+
+ org.wso2.carbon.identity.governance
+ org.wso2.carbon.identity.governance
+
+
+ org.apache.axis2.transport
+ axis2-transport-mail
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+
+
+ org.wso2.carbon
+ javax.cache.wso2
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.event
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.core
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.authentication.framework
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt
+
+
+ org.wso2.carbon.identity.organization.management.core
+ org.wso2.carbon.identity.organization.management.service
+
+
+ org.wso2.carbon.identity.branding.preference.management
+ org.wso2.carbon.identity.branding.preference.management.core
+ provided
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.central.log.mgt
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ provided
+
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.output.adapter.core
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.stream.core
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.publisher.core
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.commons
+
+
+ org.testng
+ testng
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ${project.artifactId}
+
+
+ org.wso2.carbon.identity.event.handler.notification.internal,
+
+
+ !org.wso2.carbon.identity.event.handler.notification.internal,
+ org.wso2.carbon.identity.event.handler.notification.*;version="${identity.event.handler.notification.exp.pkg.version}",
+
+
+ javax.cache,
+ javax.xml.namespace,
+
+ org.apache.axis2; version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.context; version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.engine; version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.description; version="${axis2.wso2.imp.pkg.version.range}",
+ org.apache.axis2.transport.http; version="${axis2.wso2.imp.pkg.version.range}",
+
+ org.apache.axiom.*; version="${axiom.wso2.imp.pkg.version.range}",
+ org.apache.commons.logging; version="${commons.logging.imp.pkg.version.range}",
+ org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}",
+
+ 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.stratos.common.*; version="${carbon.commons.imp.pkg.version}",
+
+ org.wso2.carbon.core;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.context; version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.user.core.*;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.utils;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.utils.multitenancy;version="${carbon.kernel.imp.pkg.version.range}",
+ org.wso2.carbon.identity.core.*; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}",
+ org.wso2.carbon.registry.core.*;version="${carbon.kernel.registry.imp.pkg.version}",
+ org.wso2.carbon.identity.base; version="${carbon.identity.framework.imp.pkg.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.handler; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.application.authentication.framework.config; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.event.output.adapter.core.*; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.event.stream.core.*; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.event.publisher.core.*; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.databridge.commons.*; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.email.mgt.*; version="${identity.event.handler.notification.imp.pkg.version.range}",
+ org.wso2.carbon.identity.central.log.mgt.*; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.governance.*; version="${identity.governance.imp.pkg.version.range}",
+ org.wso2.carbon.identity.branding.preference.management.core.*; version="${identity.branding.preference.management.version.range}",
+ org.wso2.carbon.identity.organization.management.service;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
+ org.wso2.carbon.identity.organization.management.service.constant;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
+ org.wso2.carbon.identity.organization.management.service.exception;version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
+
+
+
+
+
+
+
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/findbugs-exclude-filter.xml b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/findbugs-exclude-filter.xml
new file mode 100644
index 000000000..1517c11fd
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/findbugs-exclude-filter.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml
index 2a9032623..29b422606 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml
@@ -70,6 +70,10 @@
org.wso2.carbon.identity.notification.push
org.wso2.carbon.identity.notification.push.provider
+
+ org.apache.httpcomponents.wso2
+ httpcore
+
org.testng
@@ -94,6 +98,10 @@
org.wso2.carbon.identity.framework
org.wso2.carbon.identity.secret.mgt.core
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.external.api.token.handler
+
@@ -145,6 +153,11 @@
org.wso2.carbon.identity.application.common; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.application.common.util; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.external.api.token.handler.*; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.external.api.client.api.model; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.external.api.client.api.exception; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.external.api.client.api.service; version="${carbon.identity.framework.imp.pkg.version.range}",
+
org.wso2.carbon.idp.mgt.model; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.configuration.mgt.core;
@@ -181,6 +194,8 @@
org.wso2.carbon.identity.secret.mgt.core; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.secret.mgt.core.exception; version="${carbon.identity.framework.imp.pkg.version.range}",
org.wso2.carbon.identity.secret.mgt.core.model; version="${carbon.identity.framework.imp.pkg.version.range}",
+
+ org.apache.http.*; version="${httpcore.version.osgi.import.range}"
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml.versionsBackup b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml.versionsBackup
new file mode 100644
index 000000000..6f4336f92
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/pom.xml.versionsBackup
@@ -0,0 +1,221 @@
+
+
+
+ 4.0.0
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../../pom.xml
+
+
+ org.wso2.carbon.identity.notification.sender.tenant.config
+ bundle
+ WSO2 Carbon - Identity Notification Sender Configuration
+ Tenant wise Identity Notification Sender Configuration
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.carbon.identity.governance
+ org.wso2.carbon.identity.tenant.resource.manager
+
+
+ org.apache.felix
+ org.apache.felix.scr.ds-annotations
+ provided
+
+
+ org.wso2.carbon.identity.organization.management.core
+ org.wso2.carbon.identity.organization.management.service
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.configuration.mgt.core
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.mgt
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.core
+
+
+
+ org.testng
+ testng
+ test
+
+
+ org.mockito
+ mockito-inline
+ test
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.identity.notification.sender.tenant.config.internal,
+
+
+ !org.wso2.carbon.identity.notification.sender.tenant.config.internal,
+ org.wso2.carbon.identity.notification.sender.tenant.config.*,
+
+
+ javax.xml.parsers; version="[0.0.0, 1.0.0)",
+ javax.xml.transform; version="[0.0.0, 1.0.0)",
+ javax.xml.transform.dom; version="[0.0.0, 1.0.0)",
+ javax.xml.transform.stream; version="[0.0.0, 1.0.0)",
+ org.w3c.dom; version="[0.0.0, 1.0.0)",
+
+ org.apache.axis2.clustering; version="${axis2.osgi.version.range}",
+ org.apache.axis2.context; version="${axis2.osgi.version.range}",
+ org.apache.axis2.engine; version="${axis2.osgi.version.range}",
+
+ org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}",
+ org.apache.commons.logging; version="${commons.logging.imp.pkg.version.range}",
+
+ org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
+ org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",
+ org.osgi.service.component.annotations; version="${osgi.service.component.imp.pkg.version.range}",
+
+ org.wso2.carbon.base.api; version="${carbon.kernel.carbon.base.pkg.version}",
+ org.wso2.carbon.context; version="${carbon.kernel.imp.pkg.version.range}",
+
+ org.wso2.carbon.email.mgt; version="${identity.event.handler.notification.imp.pkg.version.range}",
+ org.wso2.carbon.email.mgt.model; version="${identity.event.handler.notification.imp.pkg.version.range}",
+
+ org.wso2.carbon.event.publisher.core; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.event.publisher.core.config; version="${carbon.analytics.common.version.range}",
+ org.wso2.carbon.event.publisher.core.exception; version="${carbon.analytics.common.version.range}",
+
+ org.wso2.carbon.identity.application.mgt; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.application.common; version="${carbon.identity.framework.imp.pkg.version.range}",
+ org.wso2.carbon.identity.application.common.util; version="${carbon.identity.framework.imp.pkg.version.range}",
+
+ org.wso2.carbon.idp.mgt.model; 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.wso2.carbon.identity.core.util;
+ version="${carbon.identity.framework.imp.pkg.version.range}",
+
+ org.wso2.carbon.identity.tenant.resource.manager.core; version="${identity.governance.imp.pkg.version.range}",
+ org.wso2.carbon.identity.tenant.resource.manager.exception; version="${identity.governance.imp.pkg.version.range}",
+ org.wso2.carbon.identity.tenant.resource.manager.util; version="${identity.governance.imp.pkg.version.range}",
+ org.wso2.carbon.utils; version="${carbon.kernel.imp.pkg.version.range}",
+
+ org.wso2.carbon.identity.organization.management.service;
+ version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
+ org.wso2.carbon.identity.organization.management.service.util;
+ version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}",
+ org.wso2.carbon.identity.organization.management.service.exception;
+ version="${org.wso2.identity.organization.mgt.core.imp.pkg.version.range}"
+
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+
+ Medium
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+
+ Max
+ Low
+ true
+ ${project.build.directory}/findbugs
+
+ ${mavan.findbugsplugin.exclude.file}
+
+
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ LATEST
+
+
+
+
+
+ analyze-compile
+ compile
+
+ check
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+
+ validate
+ validate
+
+
+ https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/checkstyle.xml
+
+
+ https://raw.githubusercontent.com/wso2/code-quality-tools/master/checkstyle/suppressions.xml
+
+ UTF-8
+ true
+ true
+ true
+
+
+ check
+
+
+
+
+
+
+
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/NotificationSenderManagementConstants.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/NotificationSenderManagementConstants.java
index 3599fca61..161e5ed02 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/NotificationSenderManagementConstants.java
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/NotificationSenderManagementConstants.java
@@ -53,6 +53,12 @@ private NotificationSenderManagementConstants() {
public static final String SMS_PROVIDER = "SMS_PROVIDER";
public static final String PUSH_PROVIDER = "PUSH_PROVIDER";
+ // Notification sender authentication properties
+ public static final String AUTH_HEADER = "authorization";
+ public static final String AUTH_TYPE_PREFIX = "auth.authType";
+ public static final String AUTH_INTERNAL_PROP_PREFIX = "auth.internal.";
+ public static final String AUTH_EXTERNAL_PROP_PREFIX = "auth.external.";
+
// Email Sender's main properties.
public static final String NAME = "name";
public static final String SMTP_SERVER_HOST = "smtpServerHost";
@@ -166,6 +172,14 @@ public enum ErrorMessage {
ERROR_CODE_CONNECTED_APPLICATION_EXISTS("60008",
"Unable to disable.",
"There are applications using this connection."),
+ ERROR_CODE_MISSING_AUTH_TYPE("60009", "Missing authentication type.",
+ "Authentication type must be provided in the authentication configuration."),
+ ERROR_CODE_UNSUPPORTED_AUTH_TYPE("60010", "Unsupported authentication type.",
+ "Unsupported authentication type is provided for authentication configuration."),
+ ERROR_CODE_BLANK_AUTH_PROPERTY("60011", "Blank authentication property value.",
+ "The authentication property %s cannot be blank or empty."),
+ ERROR_CODE_MISSING_AUTH_PROPERTY("60012", "Missing authentication property.",
+ "The property %s must be included as an authentication property."),
// Server errors 650xx.
ERROR_CODE_NO_ACTIVE_PUBLISHERS_FOUND("65001", "No active notification senders found.",
@@ -227,7 +241,14 @@ public enum ErrorMessage {
ERROR_CODE_ERROR_WHILE_DECRYPTING_CREDENTIALS("65024", "Error while decrypting credentials.",
"Error while decrypting credentials for notification sender: %s."),
ERROR_CODE_ERROR_WHILE_DELETING_CREDENTIALS("65025", "Error while deleting credentials.",
- "Error while deleting credentials for notification sender: %s.");
+ "Error while deleting credentials for notification sender: %s."),
+ ERROR_CODE_ERROR_UNSUPPORTED_AUTH_TYPE_FOR_TOKEN_RETRIEVAL("65026",
+ "Unsupported authentication type.", "Unsupported authentication type for access " +
+ "token request, only supported for client credential type"),
+ ERROR_CODE_ERROR_WHILE_TOKEN_REQUEST_BUILDING("65027", "Error while building token request.",
+ "Error while building token request context for Client Credential grant."),
+ ERROR_CODE_ERROR_WHILE_RETRIEVING_TOKEN("65028", "Error while retrieving access token.",
+ "Error occurred while retrieving access token for notification sender.");
private final String code;
private final String message;
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/Authentication.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/Authentication.java
new file mode 100644
index 000000000..1ee0199c9
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/Authentication.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2025, 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
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.notification.sender.tenant.config.dto;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ErrorMessage;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementClientException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementServerException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.utils.NotificationSenderUtils;
+import org.wso2.carbon.identity.notification.sender.tenant.config.utils.TokenManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Authentication configuration for the notification sending provider.
+ */
+public class Authentication {
+
+ private static final Log LOG = LogFactory.getLog(Authentication.class);
+ private final Type type;
+ private final Map authProperties;
+ private final Map internalAuthProperties;
+ private Header authHeader;
+
+ public Authentication(AuthenticationBuilder builder) {
+
+ type = builder.authType;
+ authProperties = builder.resolvedAuthProperties;
+ internalAuthProperties = builder.internalAuthProperties;
+ authHeader = builder.authHeader;
+ }
+
+ public Authentication.Type getType() {
+
+ return type;
+ }
+
+ public Map getProperties() {
+
+ return authProperties;
+ }
+
+ public String getProperty(String propertyName) {
+
+ return authProperties.get(propertyName);
+ }
+
+ public void addInternalProperty(String propKey, String propValue) {
+
+ authProperties.put(propKey, propValue);
+ }
+
+ public Map getInternalProperties() {
+
+ return internalAuthProperties;
+ }
+
+ public Header getAuthHeader() throws NotificationSenderManagementServerException {
+
+ if (type == Type.CLIENT_CREDENTIAL && authHeader == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Auth header is null for CLIENT_CREDENTIAL type. Building new auth header.");
+ }
+ authHeader = rebuildAuthHeader();
+ }
+ return authHeader;
+ }
+
+ public Header rebuildAuthHeader() throws NotificationSenderManagementServerException {
+
+ if (type == Type.CLIENT_CREDENTIAL) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Rebuilding auth header for CLIENT_CREDENTIAL authentication type.");
+ }
+ TokenManager.getInstance().retrieveToken(this);
+ authHeader = NotificationSenderUtils.buildAuthenticationHeader(type, internalAuthProperties);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully rebuilt auth header for CLIENT_CREDENTIAL authentication type.");
+ }
+ }
+ return authHeader;
+ }
+
+ /**
+ * This Builder build endpoint by taking the authentication type and properties as input.
+ */
+ public static class AuthenticationBuilder {
+
+ private final Type authType;
+ private final Map propertiesMap;
+ private final Map resolvedAuthProperties = new HashMap<>();
+ private final Map internalAuthProperties = new HashMap<>();
+ private Header authHeader;
+
+ public AuthenticationBuilder (String type, Map authPropertiesMap)
+ throws NotificationSenderManagementClientException {
+
+ this.authType = Type.valueOfName(type);
+ this.propertiesMap = authPropertiesMap;
+ }
+
+ public AuthenticationBuilder internalAuthProperty(String propKey, String propValue) {
+
+ resolvedAuthProperties.put(propKey, propValue);
+ return this;
+ }
+
+ public Authentication build() throws NotificationSenderManagementException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Building authentication configuration for type: " + authType);
+ }
+
+ switch (authType) {
+ case BASIC:
+ resolvedAuthProperties.put(Property.USERNAME.getName(), getProperty(Property.USERNAME));
+ resolvedAuthProperties.put(Property.PASSWORD.getName(), getProperty(Property.PASSWORD));
+ break;
+ case BEARER:
+ resolvedAuthProperties.put(Property.ACCESS_TOKEN.getName(), getProperty(Property.ACCESS_TOKEN));
+ break;
+ case CLIENT_CREDENTIAL:
+ resolvedAuthProperties.put(Property.CLIENT_ID.getName(), getProperty(Property.CLIENT_ID));
+ resolvedAuthProperties.put(Property.CLIENT_SECRET.getName(), getProperty(Property.CLIENT_SECRET));
+ resolvedAuthProperties.put(Property.SCOPE.getName(), getProperty(Property.SCOPE));
+ resolvedAuthProperties.put(
+ Property.TOKEN_ENDPOINT.getName(), getProperty(Property.TOKEN_ENDPOINT));
+ break;
+ case API_KEY:
+ resolvedAuthProperties.put(Property.HEADER.getName(), getProperty(Property.HEADER));
+ resolvedAuthProperties.put(Property.VALUE.getName(), getProperty(Property.VALUE));
+ break;
+ case NONE:
+ break;
+ }
+ authHeader = NotificationSenderUtils.buildAuthenticationHeader(authType, resolvedAuthProperties);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully built authentication configuration for type: " + authType);
+ }
+ return new Authentication(this);
+ }
+
+ private String getProperty(Property propName) throws NotificationSenderManagementClientException {
+
+ if (propertiesMap != null && propertiesMap.containsKey(propName.getName())) {
+ String propValue = propertiesMap.get(propName.getName());
+ if (StringUtils.isNotBlank(propValue)) {
+ return propValue;
+ }
+ LOG.error("Authentication property '" + propName.getName() + "' is blank.");
+ throw new NotificationSenderManagementClientException(
+ ErrorMessage.ERROR_CODE_BLANK_AUTH_PROPERTY, propName.getName());
+ }
+
+ LOG.error("Required authentication property '" + propName.getName() + "' is missing.");
+ throw new NotificationSenderManagementClientException(
+ ErrorMessage.ERROR_CODE_MISSING_AUTH_PROPERTY, propName.getName());
+ }
+ }
+
+ /**
+ * Authentication Type.
+ */
+ public enum Type {
+
+ NONE("NONE"),
+ BEARER("BEARER"),
+ CLIENT_CREDENTIAL("CLIENT_CREDENTIAL"),
+ BASIC("BASIC"),
+ API_KEY("API_KEY");
+
+ private final String name;
+
+ Type(String name) {
+
+ this.name = name;
+ }
+
+ public String getName() {
+
+ return name;
+ }
+
+
+ public static Type valueOfName(String name) throws NotificationSenderManagementClientException {
+
+ if (name == null || name.isEmpty()) {
+ LOG.error("Authentication type is missing or empty.");
+ throw new NotificationSenderManagementClientException(ErrorMessage.ERROR_CODE_MISSING_AUTH_TYPE, name);
+ }
+
+ for (Type type : Type.values()) {
+ if (type.name.equalsIgnoreCase(name)) {
+ return type;
+ }
+ }
+ LOG.error("Unsupported authentication type: " + name);
+ throw new NotificationSenderManagementClientException(ErrorMessage.ERROR_CODE_UNSUPPORTED_AUTH_TYPE, name);
+ }
+ }
+
+ /**
+ * Authentication Property Enum.
+ */
+ public enum Property {
+
+ USERNAME("username"),
+ PASSWORD("password"),
+ HEADER("header"),
+ VALUE("value"),
+ ACCESS_TOKEN("accessToken"),
+ CLIENT_ID("client_id"),
+ CLIENT_SECRET("client_secret"),
+ SCOPE("scope"),
+ TOKEN_ENDPOINT("token_endpoint");
+
+ private final String name;
+
+ Property(String name) {
+
+ this.name = name;
+ }
+
+ public String getName() {
+
+ return name;
+ }
+ }
+}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTO.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTO.java
index 42efe23e8..547d5c309 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTO.java
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTO.java
@@ -18,14 +18,25 @@
package org.wso2.carbon.identity.notification.sender.tenant.config.dto;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ErrorMessage;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Property;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementClientException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementException;
+
import java.util.HashMap;
import java.util.Map;
+import static org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Type.BASIC;
+
/**
* DTO for SMS sender.
*/
public class SMSSenderDTO {
-
+
+ private static final Log LOG = LogFactory.getLog(SMSSenderDTO.class);
private String name;
private String provider;
private String providerURL;
@@ -34,6 +45,7 @@ public class SMSSenderDTO {
private String sender;
private String contentType;
private Map properties = new HashMap<>();
+ private Authentication authentication = null;
public String getName() {
@@ -114,4 +126,184 @@ public void setProperties(Map properties) {
this.properties = properties;
}
+
+ public void setAuthentication(Authentication authentication) {
+
+ this.authentication = authentication;
+ }
+
+ public Authentication getAuthentication() {
+
+ return authentication;
+ }
+
+ /**
+ * Builder for SMSSenderDTO.
+ */
+ public static class Builder {
+
+ private String name;
+ private String provider;
+ private String providerURL;
+ private String key;
+ private String secret;
+ private String sender;
+ private String contentType;
+ private final Map properties = new HashMap<>();
+ private String authType;
+ private final Map authProperties = new HashMap<>();
+
+ public Builder name(String name) {
+
+ this.name = name;
+ return this;
+ }
+
+ public Builder provider(String provider) {
+
+ this.provider = provider;
+ return this;
+ }
+
+ public Builder providerURL(String providerURL) {
+
+ this.providerURL = providerURL;
+ return this;
+ }
+
+ public Builder key(String key) {
+
+ this.key = key;
+ return this;
+ }
+
+ public Builder secret(String secret) {
+
+ this.secret = secret;
+ return this;
+ }
+
+ public Builder sender(String sender) {
+
+ this.sender = sender;
+ return this;
+ }
+
+ public Builder contentType(String contentType) {
+
+ this.contentType = contentType;
+ return this;
+ }
+
+ public Builder addProperty(String key, String value) {
+
+ properties.put(key, value);
+ return this;
+ }
+
+ public Builder authType(String authType) {
+
+ this.authType = authType;
+ return this;
+ }
+
+ public Builder addAuthProperty(String key, String value) {
+
+ authProperties.put(key, value);
+ return this;
+ }
+
+ public SMSSenderDTO build() throws NotificationSenderManagementException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Building SMSSenderDTO for provider: " + this.provider);
+ }
+
+ SMSSenderDTO smsSenderDTO = new SMSSenderDTO();
+ smsSenderDTO.setAuthentication(buildAuthConfig());
+ smsSenderDTO.setName(this.name);
+ smsSenderDTO.setProvider(this.provider);
+ smsSenderDTO.setProviderURL(this.providerURL);
+ smsSenderDTO.setKey(this.key);
+ smsSenderDTO.setSecret(this.secret);
+ smsSenderDTO.setSender(this.sender);
+ smsSenderDTO.setContentType(this.contentType);
+ smsSenderDTO.setProperties(this.properties);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully built SMSSenderDTO for provider: " + this.provider);
+ }
+ return smsSenderDTO;
+ }
+
+ private Authentication buildAuthConfig() throws NotificationSenderManagementException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Building authentication configuration for SMS sender. Auth type: " + authType);
+ }
+
+ Authentication authentication = null;
+ if (StringUtils.isNotEmpty(authType)) {
+ authentication = new Authentication.AuthenticationBuilder(authType, authProperties).build();
+ }
+
+ if (authentication != null) {
+ boolean isBasic = BASIC.equals(authentication.getType());
+
+ // Non-basic: key or secret updates not allowed
+ if (!isBasic) {
+ if (StringUtils.isNotEmpty(key) || StringUtils.isNotEmpty(secret)) {
+ LOG.error("Key or secret updates not allowed for non-BASIC authentication type: " +
+ authentication.getType());
+ throw new NotificationSenderManagementClientException(
+ ErrorMessage.ERROR_CODE_CHANNEL_TYPE_UPDATE_NOT_ALLOWED);
+ }
+ return authentication;
+ }
+
+ // BASIC: validate or assign key and secret
+ String existingKey = authentication.getProperty(Property.USERNAME.getName());
+ String existingSecret = authentication.getProperty(Property.PASSWORD.getName());
+
+ if (StringUtils.isNotBlank(key) && !StringUtils.equals(key, existingKey)) {
+ LOG.error("Key update not allowed for BASIC authentication. Attempted to change existing key.");
+ throw new NotificationSenderManagementClientException(
+ ErrorMessage.ERROR_CODE_CHANNEL_TYPE_UPDATE_NOT_ALLOWED);
+ }
+ if (StringUtils.isBlank(key)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Key not provided. Using existing key from authentication configuration.");
+ }
+ key(existingKey);
+ }
+
+ if (StringUtils.isNotBlank(secret) && !StringUtils.equals(secret, existingSecret)) {
+ LOG.error("Secret update not allowed for BASIC authentication. " +
+ "Attempted to change existing secret.");
+ throw new NotificationSenderManagementClientException(
+ ErrorMessage.ERROR_CODE_CHANNEL_TYPE_UPDATE_NOT_ALLOWED);
+ }
+ if (StringUtils.isBlank(secret)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Secret not provided. Using existing secret from authentication configuration.");
+ }
+ secret(existingSecret);
+ }
+
+ return authentication;
+ }
+
+ // If authType not provided, then creating BASIC if key and secret provided
+ if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(secret)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Auth type not provided. Creating BASIC authentication with provided key and secret.");
+ }
+ Map authProps = new HashMap<>();
+ authProps.put(Property.USERNAME.getName(), key);
+ authProps.put(Property.PASSWORD.getName(), secret);
+ return new Authentication.AuthenticationBuilder(BASIC.toString(), authProps).build();
+ }
+ return null;
+ }
+ }
}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/handlers/DefaultChannelConfigurationHandler.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/handlers/DefaultChannelConfigurationHandler.java
index 06dd900db..29544ca37 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/handlers/DefaultChannelConfigurationHandler.java
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/handlers/DefaultChannelConfigurationHandler.java
@@ -42,6 +42,7 @@
import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementException;
import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementServerException;
import org.wso2.carbon.identity.notification.sender.tenant.config.internal.NotificationSenderTenantConfigDataHolder;
+import org.wso2.carbon.identity.notification.sender.tenant.config.utils.NotificationSenderUtils;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementClientException;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementException;
import org.wso2.carbon.identity.tenant.resource.manager.exception.TenantResourceManagementServerException;
@@ -258,6 +259,7 @@ private Resource buildResourceFromSmsSender(SMSSenderDTO smsSender)
smsSenderAttributes.put(SENDER, smsSender.getSender());
smsSenderAttributes.put(CONTENT_TYPE, smsSender.getContentType());
smsSenderAttributes.putAll(smsSender.getProperties());
+ NotificationSenderUtils.addAuthenticationProperties(smsSenderAttributes, smsSender.getAuthentication());
List resourceAttributes =
smsSenderAttributes.entrySet().stream().filter(attribute -> attribute.getValue() != null)
.map(attribute -> new Attribute(attribute.getKey(), attribute.getValue()))
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/NotificationSenderUtils.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/NotificationSenderUtils.java
index 0eb6517f4..bd2e2cdff 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/NotificationSenderUtils.java
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/NotificationSenderUtils.java
@@ -19,6 +19,8 @@
package org.wso2.carbon.identity.notification.sender.tenant.config.utils;
import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.message.BasicHeader;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -30,9 +32,12 @@
import org.wso2.carbon.identity.notification.push.provider.PushProvider;
import org.wso2.carbon.identity.notification.push.provider.exception.PushProviderException;
import org.wso2.carbon.identity.notification.push.provider.model.PushSenderData;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Property;
import org.wso2.carbon.identity.notification.sender.tenant.config.dto.EmailSenderDTO;
import org.wso2.carbon.identity.notification.sender.tenant.config.dto.PushSenderDTO;
import org.wso2.carbon.identity.notification.sender.tenant.config.dto.SMSSenderDTO;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementException;
import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementServerException;
import org.wso2.carbon.identity.notification.sender.tenant.config.internal.NotificationSenderTenantConfigDataHolder;
import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
@@ -42,6 +47,8 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -62,6 +69,10 @@
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ADAPTER_TYPE_EMAIL_VALUE;
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ADAPTER_TYPE_HTTP_VALUE;
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ADAPTER_TYPE_KEY;
+import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.AUTH_EXTERNAL_PROP_PREFIX;
+import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.AUTH_HEADER;
+import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.AUTH_INTERNAL_PROP_PREFIX;
+import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.AUTH_TYPE_PREFIX;
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.BASIC;
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.CLIENT_CREDENTIAL;
import static org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.CLIENT_HTTP_METHOD_PROPERTY;
@@ -199,6 +210,25 @@ public static InputStream generateSMSPublisher(SMSSenderDTO smsSender)
return new ByteArrayInputStream(outputStream.toByteArray());
}
+ /**
+ * Convert AuthProperty list to a map with proper prefixes.
+ *
+ * @param authentication Authentication object.
+ * @param mapToBeUpdated Map to be updated with authentication properties.
+ */
+ public static void addAuthenticationProperties(Map mapToBeUpdated, Authentication authentication) {
+
+ if (authentication != null) {
+ mapToBeUpdated.put(AUTH_TYPE_PREFIX, authentication.getType().name());
+ authentication.getProperties().forEach((propKey, propValue) ->
+ mapToBeUpdated.put(AUTH_EXTERNAL_PROP_PREFIX + propKey, propValue)
+ );
+ authentication.getInternalProperties().forEach((propKey, propValue) ->
+ mapToBeUpdated.put(AUTH_INTERNAL_PROP_PREFIX + propKey, propValue)
+ );
+ }
+ }
+
private static void addEventPublisherAttributes(EmailSenderDTO emailSender, Document document, Element root) {
Map eventPublisherAttributes = new HashMap<>();
@@ -375,6 +405,8 @@ private static void addToElementToSMSEventPublisher(SMSSenderDTO smsSender, Map<
} else {
adapterProperties.put(HTTP_URL_PROPERTY, StringUtils.EMPTY);
}
+ addAuthenticationProperties(adapterProperties, smsSender.getAuthentication());
+
// Default client method is httpPost. Can be changed by configuring properties.
adapterProperties.put(CLIENT_HTTP_METHOD_PROPERTY, CONSTANT_HTTP_POST);
for (Map.Entry property : properties.entrySet()) {
@@ -435,39 +467,63 @@ private static String generateSmsSendAPIBody(String smsSendAPIBodyTemplate, SMSS
*/
public static SMSSenderDTO buildSmsSenderFromResource(Resource resource) {
- SMSSenderDTO smsSender = new SMSSenderDTO();
- smsSender.setName(resource.getResourceName());
+ SMSSenderDTO.Builder smsSenderBuilder = new SMSSenderDTO.Builder();
+ smsSenderBuilder.name(resource.getResourceName());
+
// Skip STREAM_NAME, STREAM_VERSION and PUBLISHER_TYPE_PROPERTY properties which are stored for internal use.
Map attributesMap =
resource.getAttributes().stream()
.filter(attribute -> !(INTERNAL_PROPERTIES.contains(attribute.getKey())))
.filter(attribute -> attribute.getValue() != null)
.collect(Collectors.toMap(Attribute::getKey, Attribute::getValue));
+ Map internalAuthProp = new HashMap<>();
attributesMap.forEach((key, value) -> {
switch (key) {
case PROVIDER:
- smsSender.setProvider(value);
+ smsSenderBuilder.provider(value);
break;
case PROVIDER_URL:
- smsSender.setProviderURL(value);
+ smsSenderBuilder.providerURL(value);
break;
case KEY:
- smsSender.setKey(value);
+ smsSenderBuilder.key(value);
break;
case SECRET:
- smsSender.setSecret(value);
+ smsSenderBuilder.secret(value);
break;
case SENDER:
- smsSender.setSender(value);
+ smsSenderBuilder.sender(value);
break;
case CONTENT_TYPE:
- smsSender.setContentType(value);
+ smsSenderBuilder.contentType(value);
+ break;
+ case AUTH_TYPE_PREFIX:
+ smsSenderBuilder.authType(value);
break;
default:
- smsSender.getProperties().put(key, value);
+ if (StringUtils.startsWith(key, AUTH_EXTERNAL_PROP_PREFIX)) {
+ smsSenderBuilder.addAuthProperty(
+ StringUtils.removeStart(key, AUTH_EXTERNAL_PROP_PREFIX), value);
+ } else if (StringUtils.startsWith(key, AUTH_INTERNAL_PROP_PREFIX)) {
+ internalAuthProp.put(StringUtils.removeStart(key, AUTH_INTERNAL_PROP_PREFIX), value);
+ } else {
+ smsSenderBuilder.addProperty(key, value);
+ }
+ break;
}
});
- return smsSender;
+
+ try {
+ SMSSenderDTO smsSenderDTO = smsSenderBuilder.build();
+ internalAuthProp.keySet().forEach(internalAuthProperty ->
+ smsSenderDTO.getAuthentication().addInternalProperty(
+ internalAuthProperty, internalAuthProp.get(internalAuthProperty))
+ );
+ return smsSenderDTO;
+ } catch (NotificationSenderManagementException e) {
+ // This exception won't occur as we are not setting any invalid values.
+ return null;
+ }
}
/**
@@ -634,4 +690,36 @@ public static PushSenderData buildPushSenderData(PushSenderDTO pushSenderDTO) {
pushSenderData.setProviderId(pushSenderDTO.getProviderId());
return pushSenderData;
}
+
+ /**
+ * Build authentication header.
+ *
+ * @param authType Authentication type.
+ * @param authProperties Authentication properties.
+ * @return Header object.
+ */
+ public static Header buildAuthenticationHeader(Authentication.Type authType, Map authProperties) {
+
+ switch (authType) {
+ case BASIC:
+ String credentials = authProperties.get(Property.USERNAME.getName()) + ":" +
+ authProperties.get(Property.PASSWORD.getName());
+ byte[] encodedBytes = Base64.getEncoder().encode(credentials.getBytes(StandardCharsets.UTF_8));
+ return new org.apache.http.message.BasicHeader(
+ AUTH_HEADER,
+ "Basic " + new String(encodedBytes, StandardCharsets.UTF_8));
+ case BEARER:
+ return new BasicHeader(
+ AUTH_HEADER,
+ "Bearer " + authProperties.get(Property.ACCESS_TOKEN.toString())
+ );
+ case API_KEY:
+ return new BasicHeader(
+ authProperties.get(Property.HEADER.toString()),
+ authProperties.get(Property.VALUE.toString())
+ );
+ default:
+ return null;
+ }
+ }
}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManager.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManager.java
new file mode 100644
index 000000000..4477bfa6b
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/main/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManager.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2025, 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
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.notification.sender.tenant.config.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.identity.external.api.client.api.model.APIClientConfig;
+import org.wso2.carbon.identity.external.api.token.handler.api.exception.TokenHandlerException;
+import org.wso2.carbon.identity.external.api.token.handler.api.model.GrantContext;
+import org.wso2.carbon.identity.external.api.token.handler.api.model.TokenRequestContext;
+import org.wso2.carbon.identity.external.api.token.handler.api.model.TokenResponse;
+import org.wso2.carbon.identity.external.api.token.handler.api.service.TokenAcquirerService;
+import org.wso2.carbon.identity.notification.sender.tenant.config.NotificationSenderManagementConstants.ErrorMessage;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementServerException;
+
+/**
+ * Manager class for handling Client Credentials Token acquisition and management.
+ */
+public class TokenManager {
+
+ private static final Log LOG = LogFactory.getLog(TokenManager.class);
+ private final TokenAcquirerService tokenAcquirerService;
+ private static final TokenManager tokenManager = new TokenManager();
+
+ private TokenManager() {
+
+ this.tokenAcquirerService = new TokenAcquirerService(buildAPIClientConfig());
+ }
+
+ public static TokenManager getInstance() {
+
+ return tokenManager;
+ }
+
+ public void retrieveToken(Authentication authentication) throws NotificationSenderManagementServerException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Retrieving token for authentication type: " + authentication.getType());
+ }
+
+ TokenRequestContext tokenRequestContext = buildTokenRequestContext(authentication);
+ tokenAcquirerService.setTokenRequestContext(tokenRequestContext);
+
+ TokenResponse tokenResponse;
+ String refreshToken = authentication.getInternalProperties().get("RefreshToken");
+
+ try {
+ if (refreshToken != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Attempting to retrieve access token using refresh token grant.");
+ }
+ try {
+ tokenResponse = tokenAcquirerService.getNewAccessTokenFromRefreshGrant(refreshToken);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully retrieved access token using refresh token grant.");
+ }
+ } catch (TokenHandlerException e) {
+ LOG.warn("Failed to retrieve access token using refresh token grant. Falling back to client " +
+ "credentials grant.", e);
+ tokenResponse = tokenAcquirerService.getNewAccessToken();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully retrieved access token using client credentials grant.");
+ }
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No refresh token available. Retrieving access token using client credentials grant.");
+ }
+ tokenResponse = tokenAcquirerService.getNewAccessToken();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully retrieved access token using client credentials grant.");
+ }
+ }
+ } catch (TokenHandlerException e) {
+ LOG.error("Error while retrieving token.", e);
+ throw new NotificationSenderManagementServerException(
+ ErrorMessage.ERROR_CODE_ERROR_WHILE_RETRIEVING_TOKEN, null, e);
+ }
+
+ addInternalProperties(tokenResponse, authentication);
+ }
+
+ private void addInternalProperties(TokenResponse tokenResponse, Authentication authentication) {
+
+ authentication.addInternalProperty("RefreshToken", tokenResponse.getRefreshToken());
+ authentication.addInternalProperty("AccessToken", tokenResponse.getAccessToken());
+ }
+
+ private TokenRequestContext buildTokenRequestContext(Authentication authentication)
+ throws NotificationSenderManagementServerException {
+
+ if (authentication.getType() != Authentication.Type.CLIENT_CREDENTIAL) {
+ LOG.error("Unsupported authentication type for token retrieval: " + authentication.getType());
+ throw new NotificationSenderManagementServerException(
+ ErrorMessage.ERROR_CODE_ERROR_UNSUPPORTED_AUTH_TYPE_FOR_TOKEN_RETRIEVAL, null);
+ }
+
+ try {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Building token request context for client credentials grant.");
+ }
+ GrantContext grantContext = new GrantContext.Builder()
+ .grantType(GrantContext.GrantType.CLIENT_CREDENTIAL)
+ .properties(authentication.getProperties())
+ .build();
+
+ TokenRequestContext.Builder builder = new TokenRequestContext.Builder()
+ .grantContext(grantContext)
+ .endpointUrl(authentication.getProperty(Authentication.Property.TOKEN_ENDPOINT.getName()));
+
+ return builder.build();
+ } catch (TokenHandlerException e) {
+ LOG.error("Error while building token request context.", e);
+ throw new NotificationSenderManagementServerException(
+ ErrorMessage.ERROR_CODE_ERROR_WHILE_TOKEN_REQUEST_BUILDING, null, e);
+ }
+ }
+
+ private APIClientConfig buildAPIClientConfig() {
+
+ APIClientConfig.Builder configBuilder = new APIClientConfig.Builder();
+ return configBuilder.build();
+ }
+}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/AuthenticationTest.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/AuthenticationTest.java
new file mode 100644
index 000000000..e98eb2745
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/AuthenticationTest.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2025, 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
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.notification.sender.tenant.config.dto;
+
+import org.apache.http.Header;
+import org.mockito.MockedStatic;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Property;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Type;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementClientException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.utils.NotificationSenderUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+
+/**
+ * Unit tests for {@link Authentication}.
+ */
+public class AuthenticationTest {
+
+ private Map authProperties;
+ private Header mockHeader;
+
+ @BeforeMethod
+ public void setUp() {
+ authProperties = new HashMap<>();
+ mockHeader = mock(Header.class);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ authProperties.clear();
+ }
+
+ @Test
+ public void testAuthenticationBuilderWithBasicAuth() throws Exception {
+ authProperties.put(Property.USERNAME.getName(), "testuser");
+ authProperties.put(Property.PASSWORD.getName(), "testpass");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Type.BASIC);
+ Assert.assertEquals(auth.getProperty(Property.USERNAME.getName()), "testuser");
+ Assert.assertEquals(auth.getProperty(Property.PASSWORD.getName()), "testpass");
+ }
+ }
+
+ @Test
+ public void testAuthenticationBuilderWithBearerAuth() throws Exception {
+ authProperties.put(Property.ACCESS_TOKEN.getName(), "test-access-token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BEARER), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BEARER", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Type.BEARER);
+ Assert.assertEquals(auth.getProperty(Property.ACCESS_TOKEN.getName()), "test-access-token");
+ }
+ }
+
+ @Test
+ public void testAuthenticationBuilderWithClientCredential() throws Exception {
+ authProperties.put(Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.CLIENT_CREDENTIAL), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Type.CLIENT_CREDENTIAL);
+ Assert.assertEquals(auth.getProperty(Property.CLIENT_ID.getName()), "test-client-id");
+ Assert.assertEquals(auth.getProperty(Property.CLIENT_SECRET.getName()), "test-client-secret");
+ Assert.assertEquals(auth.getProperty(Property.SCOPE.getName()), "test-scope");
+ Assert.assertEquals(auth.getProperty(Property.TOKEN_ENDPOINT.getName()), "https://test.com/token");
+ }
+ }
+
+ @Test
+ public void testAuthenticationBuilderWithApiKey() throws Exception {
+ authProperties.put(Property.HEADER.getName(), "X-API-KEY");
+ authProperties.put(Property.VALUE.getName(), "test-api-key-value");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.API_KEY), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("API_KEY", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Type.API_KEY);
+ Assert.assertEquals(auth.getProperty(Property.HEADER.getName()), "X-API-KEY");
+ Assert.assertEquals(auth.getProperty(Property.VALUE.getName()), "test-api-key-value");
+ }
+ }
+
+ @Test
+ public void testAuthenticationBuilderWithNoneType() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.NONE), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("NONE", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Type.NONE);
+ }
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationBuilderWithMissingProperty() throws Exception {
+ authProperties.put(Property.USERNAME.getName(), "testuser");
+ // Missing password property
+
+ new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationBuilderWithBlankProperty() throws Exception {
+ authProperties.put(Property.USERNAME.getName(), "testuser");
+ authProperties.put(Property.PASSWORD.getName(), "");
+
+ new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationBuilderWithNullAuthType() throws Exception {
+ new Authentication.AuthenticationBuilder(null, authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationBuilderWithEmptyAuthType() throws Exception {
+ new Authentication.AuthenticationBuilder("", authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationBuilderWithUnsupportedAuthType() throws Exception {
+ new Authentication.AuthenticationBuilder("UNSUPPORTED_TYPE", authProperties).build();
+ }
+
+ @Test
+ public void testTypeValueOfName() throws Exception {
+ Assert.assertEquals(Type.valueOfName("BASIC"), Type.BASIC);
+ Assert.assertEquals(Type.valueOfName("BEARER"), Type.BEARER);
+ Assert.assertEquals(Type.valueOfName("CLIENT_CREDENTIAL"), Type.CLIENT_CREDENTIAL);
+ Assert.assertEquals(Type.valueOfName("API_KEY"), Type.API_KEY);
+ Assert.assertEquals(Type.valueOfName("NONE"), Type.NONE);
+ }
+
+ @Test
+ public void testTypeValueOfNameCaseInsensitive() throws Exception {
+ Assert.assertEquals(Type.valueOfName("basic"), Type.BASIC);
+ Assert.assertEquals(Type.valueOfName("Bearer"), Type.BEARER);
+ Assert.assertEquals(Type.valueOfName("client_credential"), Type.CLIENT_CREDENTIAL);
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testTypeValueOfNameWithNull() throws Exception {
+ Type.valueOfName(null);
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testTypeValueOfNameWithEmpty() throws Exception {
+ Type.valueOfName("");
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testTypeValueOfNameWithInvalid() throws Exception {
+ Type.valueOfName("INVALID_TYPE");
+ }
+
+ @Test
+ public void testGetters() throws Exception {
+ authProperties.put(Property.USERNAME.getName(), "testuser");
+ authProperties.put(Property.PASSWORD.getName(), "testpass");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+
+ Assert.assertEquals(auth.getType(), Type.BASIC);
+ Assert.assertNotNull(auth.getProperties());
+ Assert.assertEquals(auth.getProperties().size(), 2);
+ Assert.assertEquals(auth.getProperty(Property.USERNAME.getName()), "testuser");
+ }
+ }
+
+ @Test
+ public void testAddInternalProperty() throws Exception {
+ authProperties.put(Property.USERNAME.getName(), "testuser");
+ authProperties.put(Property.PASSWORD.getName(), "testpass");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+
+ auth.addInternalProperty("testKey", "testValue");
+ Assert.assertEquals(auth.getProperty("testKey"), "testValue");
+ }
+ }
+
+ @Test
+ public void testPropertyEnum() {
+ Assert.assertEquals(Property.USERNAME.getName(), "username");
+ Assert.assertEquals(Property.PASSWORD.getName(), "password");
+ Assert.assertEquals(Property.HEADER.getName(), "header");
+ Assert.assertEquals(Property.VALUE.getName(), "value");
+ Assert.assertEquals(Property.ACCESS_TOKEN.getName(), "accessToken");
+ Assert.assertEquals(Property.CLIENT_ID.getName(), "client_id");
+ Assert.assertEquals(Property.CLIENT_SECRET.getName(), "client_secret");
+ Assert.assertEquals(Property.SCOPE.getName(), "scope");
+ Assert.assertEquals(Property.TOKEN_ENDPOINT.getName(), "token_endpoint");
+ }
+
+ @Test
+ public void testTypeEnum() {
+ Assert.assertEquals(Type.NONE.getName(), "NONE");
+ Assert.assertEquals(Type.BEARER.getName(), "BEARER");
+ Assert.assertEquals(Type.CLIENT_CREDENTIAL.getName(), "CLIENT_CREDENTIAL");
+ Assert.assertEquals(Type.BASIC.getName(), "BASIC");
+ Assert.assertEquals(Type.API_KEY.getName(), "API_KEY");
+ }
+}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTOTest.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTOTest.java
new file mode 100644
index 000000000..e31a45086
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/dto/SMSSenderDTOTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2025, 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
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.notification.sender.tenant.config.dto;
+
+import org.apache.http.Header;
+import org.mockito.MockedStatic;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Property;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication.Type;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementClientException;
+import org.wso2.carbon.identity.notification.sender.tenant.config.utils.NotificationSenderUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+
+/**
+ * Unit tests for {@link SMSSenderDTO}.
+ */
+public class SMSSenderDTOTest {
+
+ private SMSSenderDTO.Builder builder;
+ private Header mockHeader;
+
+ @BeforeMethod
+ public void setUp() {
+ builder = new SMSSenderDTO.Builder();
+ mockHeader = mock(Header.class);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ builder = null;
+ }
+
+ @Test
+ public void testBuildSimpleSMSSender() throws Exception {
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .sender("+1234567890")
+ .contentType("application/json")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertEquals(dto.getName(), "TestSender");
+ Assert.assertEquals(dto.getProvider(), "TestProvider");
+ Assert.assertEquals(dto.getProviderURL(), "https://test.provider.com");
+ Assert.assertEquals(dto.getSender(), "+1234567890");
+ Assert.assertEquals(dto.getContentType(), "application/json");
+ Assert.assertNull(dto.getAuthentication());
+ }
+
+ @Test
+ public void testBuildWithBasicAuthUsingKeyAndSecret() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .key("testuser")
+ .secret("testpass")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.BASIC);
+ Assert.assertEquals(dto.getKey(), "testuser");
+ Assert.assertEquals(dto.getSecret(), "testpass");
+ }
+ }
+
+ @Test
+ public void testBuildWithBearerAuth() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BEARER), any())).thenReturn(mockHeader);
+
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BEARER")
+ .addAuthProperty(Property.ACCESS_TOKEN.getName(), "test-token")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.BEARER);
+ }
+ }
+
+ @Test
+ public void testBuildWithClientCredentialAuth() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.CLIENT_CREDENTIAL), any())).thenReturn(mockHeader);
+
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("CLIENT_CREDENTIAL")
+ .addAuthProperty(Property.CLIENT_ID.getName(), "test-client-id")
+ .addAuthProperty(Property.CLIENT_SECRET.getName(), "test-client-secret")
+ .addAuthProperty(Property.SCOPE.getName(), "test-scope")
+ .addAuthProperty(Property.TOKEN_ENDPOINT.getName(), "https://test.com/token")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.CLIENT_CREDENTIAL);
+ }
+ }
+
+ @Test
+ public void testBuildWithApiKeyAuth() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.API_KEY), any())).thenReturn(mockHeader);
+
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("API_KEY")
+ .addAuthProperty(Property.HEADER.getName(), "X-API-KEY")
+ .addAuthProperty(Property.VALUE.getName(), "test-api-key")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.API_KEY);
+ }
+ }
+
+ @Test
+ public void testBuildWithProperties() throws Exception {
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .addProperty("customKey1", "customValue1")
+ .addProperty("customKey2", "customValue2")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getProperties());
+ Assert.assertEquals(dto.getProperties().size(), 2);
+ Assert.assertEquals(dto.getProperties().get("customKey1"), "customValue1");
+ Assert.assertEquals(dto.getProperties().get("customKey2"), "customValue2");
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testBuildWithNonBasicAuthAndKeyProvided() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BEARER), any())).thenReturn(mockHeader);
+
+ builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BEARER")
+ .addAuthProperty(Property.ACCESS_TOKEN.getName(), "test-token")
+ .key("should-not-be-allowed")
+ .build();
+ }
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testBuildWithNonBasicAuthAndSecretProvided() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BEARER), any())).thenReturn(mockHeader);
+
+ builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BEARER")
+ .addAuthProperty(Property.ACCESS_TOKEN.getName(), "test-token")
+ .secret("should-not-be-allowed")
+ .build();
+ }
+ }
+
+ @Test
+ public void testBuildWithBasicAuthUsingExistingCredentials() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ // Build with BASIC auth and existing credentials
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BASIC")
+ .addAuthProperty(Property.USERNAME.getName(), "existinguser")
+ .addAuthProperty(Property.PASSWORD.getName(), "existingpass")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.BASIC);
+ Assert.assertEquals(dto.getKey(), "existinguser");
+ Assert.assertEquals(dto.getSecret(), "existingpass");
+ }
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testBuildWithBasicAuthKeyMismatch() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BASIC")
+ .addAuthProperty(Property.USERNAME.getName(), "existinguser")
+ .addAuthProperty(Property.PASSWORD.getName(), "existingpass")
+ .key("differentuser")
+ .build();
+ }
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testBuildWithBasicAuthSecretMismatch() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .authType("BASIC")
+ .addAuthProperty(Property.USERNAME.getName(), "existinguser")
+ .addAuthProperty(Property.PASSWORD.getName(), "existingpass")
+ .secret("differentpass")
+ .build();
+ }
+ }
+
+ @Test
+ public void testSettersAndGetters() throws Exception {
+ SMSSenderDTO dto = new SMSSenderDTO();
+
+ dto.setName("TestName");
+ dto.setProvider("TestProvider");
+ dto.setProviderURL("https://test.com");
+ dto.setKey("testkey");
+ dto.setSecret("testsecret");
+ dto.setSender("+1234567890");
+ dto.setContentType("application/json");
+
+ Map props = new HashMap<>();
+ props.put("key1", "value1");
+ dto.setProperties(props);
+
+ Assert.assertEquals(dto.getName(), "TestName");
+ Assert.assertEquals(dto.getProvider(), "TestProvider");
+ Assert.assertEquals(dto.getProviderURL(), "https://test.com");
+ Assert.assertEquals(dto.getKey(), "testkey");
+ Assert.assertEquals(dto.getSecret(), "testsecret");
+ Assert.assertEquals(dto.getSender(), "+1234567890");
+ Assert.assertEquals(dto.getContentType(), "application/json");
+ Assert.assertEquals(dto.getProperties().get("key1"), "value1");
+ }
+
+ @Test
+ public void testBuildWithOnlyKeyNoSecret() throws Exception {
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .key("testuser")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNull(dto.getAuthentication(), "Authentication should be null when only key is provided");
+ }
+
+ @Test
+ public void testBuildWithOnlySecretNoKey() throws Exception {
+ SMSSenderDTO dto = builder
+ .name("TestSender")
+ .provider("TestProvider")
+ .providerURL("https://test.provider.com")
+ .secret("testpass")
+ .build();
+
+ Assert.assertNotNull(dto);
+ Assert.assertNull(dto.getAuthentication(), "Authentication should be null when only secret is provided");
+ }
+
+ @Test
+ public void testSetAuthentication() throws Exception {
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Type.BASIC), any())).thenReturn(mockHeader);
+
+ Map authProps = new HashMap<>();
+ authProps.put(Property.USERNAME.getName(), "testuser");
+ authProps.put(Property.PASSWORD.getName(), "testpass");
+ Authentication auth = new Authentication.AuthenticationBuilder("BASIC", authProps).build();
+
+ SMSSenderDTO dto = new SMSSenderDTO();
+ dto.setAuthentication(auth);
+
+ Assert.assertNotNull(dto.getAuthentication());
+ Assert.assertEquals(dto.getAuthentication().getType(), Type.BASIC);
+ }
+ }
+}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManagerTest.java b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManagerTest.java
new file mode 100644
index 000000000..1ad77ad2a
--- /dev/null
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/java/org/wso2/carbon/identity/notification/sender/tenant/config/utils/TokenManagerTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2025, 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
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.identity.notification.sender.tenant.config.utils;
+
+import org.apache.http.Header;
+import org.mockito.MockedStatic;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.notification.sender.tenant.config.dto.Authentication;
+import org.wso2.carbon.identity.notification.sender.tenant.config.exception.NotificationSenderManagementClientException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+
+/**
+ * Unit tests for {@link TokenManager}.
+ * Note: TokenManager is a singleton with complex initialization that depends on external configuration.
+ * These tests focus on testing the authentication building and validation logic through the Authentication class.
+ */
+public class TokenManagerTest {
+
+ private Map authProperties;
+ private Header mockHeader;
+
+ @BeforeMethod
+ public void setUp() {
+ authProperties = new HashMap<>();
+ mockHeader = mock(Header.class);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ authProperties.clear();
+ }
+
+ @Test
+ public void testAuthenticationWithClientCredential() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Authentication.Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Authentication.Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Authentication.Type.CLIENT_CREDENTIAL), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Authentication.Type.CLIENT_CREDENTIAL);
+ Assert.assertEquals(auth.getProperty(Authentication.Property.CLIENT_ID.getName()), "test-client-id");
+ Assert.assertEquals(auth.getProperty(Authentication.Property.CLIENT_SECRET.getName()),
+ "test-client-secret");
+ Assert.assertEquals(auth.getProperty(Authentication.Property.SCOPE.getName()), "test-scope");
+ Assert.assertEquals(auth.getProperty(Authentication.Property.TOKEN_ENDPOINT.getName()),
+ "https://test.com/token");
+ }
+ }
+
+ @Test
+ public void testAuthenticationWithBasicType() throws Exception {
+ authProperties.put(Authentication.Property.USERNAME.getName(), "testuser");
+ authProperties.put(Authentication.Property.PASSWORD.getName(), "testpass");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Authentication.Type.BASIC), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BASIC", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Authentication.Type.BASIC);
+ Assert.assertNotEquals(auth.getType(), Authentication.Type.CLIENT_CREDENTIAL);
+ }
+ }
+
+ @Test
+ public void testAuthenticationWithBearerType() throws Exception {
+ authProperties.put(Authentication.Property.ACCESS_TOKEN.getName(), "test-access-token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Authentication.Type.BEARER), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("BEARER", authProperties).build();
+
+ Assert.assertNotNull(auth);
+ Assert.assertEquals(auth.getType(), Authentication.Type.BEARER);
+ }
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationWithMissingClientId() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Authentication.Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationWithMissingClientSecret() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Authentication.Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+ }
+
+ @Test(expectedExceptions = NotificationSenderManagementClientException.class)
+ public void testAuthenticationWithMissingTokenEndpoint() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Authentication.Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+
+ new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+ }
+
+ @Test
+ public void testAuthenticationInternalProperties() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Authentication.Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Authentication.Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Authentication.Type.CLIENT_CREDENTIAL), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+
+ // Test adding internal properties (simulating what TokenManager would do)
+ auth.addInternalProperty("AccessToken", "test-access-token");
+ auth.addInternalProperty("RefreshToken", "test-refresh-token");
+
+ Assert.assertEquals(auth.getProperty("AccessToken"), "test-access-token");
+ Assert.assertEquals(auth.getProperty("RefreshToken"), "test-refresh-token");
+ }
+ }
+
+ @Test
+ public void testAuthenticationGetInternalProperties() throws Exception {
+ authProperties.put(Authentication.Property.CLIENT_ID.getName(), "test-client-id");
+ authProperties.put(Authentication.Property.CLIENT_SECRET.getName(), "test-client-secret");
+ authProperties.put(Authentication.Property.SCOPE.getName(), "test-scope");
+ authProperties.put(Authentication.Property.TOKEN_ENDPOINT.getName(), "https://test.com/token");
+
+ try (MockedStatic mockedUtils = mockStatic(NotificationSenderUtils.class)) {
+ mockedUtils.when(() -> NotificationSenderUtils.buildAuthenticationHeader(
+ eq(Authentication.Type.CLIENT_CREDENTIAL), any())).thenReturn(mockHeader);
+
+ Authentication auth = new Authentication.AuthenticationBuilder("CLIENT_CREDENTIAL", authProperties).build();
+
+ Map internalProps = auth.getInternalProperties();
+ Assert.assertNotNull(internalProps);
+ }
+ }
+}
diff --git a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/resources/testng.xml b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/resources/testng.xml
index 34b0fbd57..9ef250b60 100644
--- a/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/resources/testng.xml
+++ b/components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config/src/test/resources/testng.xml
@@ -22,8 +22,11 @@
+
+
+
diff --git a/features/org.wso2.carbon.email.mgt.feature/pom.xml.versionsBackup b/features/org.wso2.carbon.email.mgt.feature/pom.xml.versionsBackup
new file mode 100644
index 000000000..a87031f36
--- /dev/null
+++ b/features/org.wso2.carbon.email.mgt.feature/pom.xml.versionsBackup
@@ -0,0 +1,80 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../pom.xml
+
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt.feature
+ pom
+ Email Management Feature
+ http://wso2.org
+ This feature contains the bundles required for Email-Mgt functionality
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.server.feature
+ zip
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.ui.feature
+ zip
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.email.mgt
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.email.mgt.server.feature
+
+
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.email.mgt.ui.feature
+
+
+
+
+
+
+
+
+
+
diff --git a/features/org.wso2.carbon.email.mgt.server.feature/pom.xml.versionsBackup b/features/org.wso2.carbon.email.mgt.server.feature/pom.xml.versionsBackup
new file mode 100644
index 000000000..1db9830d7
--- /dev/null
+++ b/features/org.wso2.carbon.email.mgt.server.feature/pom.xml.versionsBackup
@@ -0,0 +1,131 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt.server.feature
+ pom
+ Email management server feature
+ http://wso2.org
+ This feature contains the core bundles required for Back-end functionality of Email-Mgt
+ management
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.identity.notification.sender.tenant.config
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ prefilter-resources
+ generate-resources
+
+ copy-resources
+
+
+ src/main/resources
+
+
+ resources
+
+ email-admin-config.xml
+ sms-templates-admin-config.xml
+ sms-providers-api-body-templates.xml
+ p2.inf
+
+
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.email.mgt.server
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:server
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.email.mgt
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.identity.notification.sender.tenant.config
+
+
+ org.wso2.carbon.core:compatible:${carbon.kernel.feature.version}
+ org.wso2.carbon.identity.core.server:greaterOrEqual:${carbon.identity.framework.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.1
+
+
+ clean_target
+ install
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+
+
diff --git a/features/org.wso2.carbon.email.mgt.ui.feature/pom.xml.versionsBackup b/features/org.wso2.carbon.email.mgt.ui.feature/pom.xml.versionsBackup
new file mode 100644
index 000000000..f3ef94942
--- /dev/null
+++ b/features/org.wso2.carbon.email.mgt.ui.feature/pom.xml.versionsBackup
@@ -0,0 +1,82 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt.ui.feature
+ pom
+ Email Mgt UI Feature
+ http://wso2.org
+ This feature contains the bundles required for Front-end Email Mgt functionality
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.ui
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.stub
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.email.mgt.ui
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:console
+ org.eclipse.equinox.p2.type.group:false
+
+
+
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.email.mgt.ui
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.email.mgt.stub
+
+
+ org.wso2.carbon.core:compatible:${carbon.kernel.feature.version}
+
+
+
+
+
+
+
+
+
diff --git a/features/org.wso2.carbon.event.handler.notification.server.feature/pom.xml.versionsBackup b/features/org.wso2.carbon.event.handler.notification.server.feature/pom.xml.versionsBackup
new file mode 100644
index 000000000..2ca8a5aff
--- /dev/null
+++ b/features/org.wso2.carbon.event.handler.notification.server.feature/pom.xml.versionsBackup
@@ -0,0 +1,129 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.event.handler.notification.server.feature
+ pom
+ Notification Event management server feature
+ http://wso2.org
+ This feature contains the core bundles required for Back-end functionality of Notification-Event-Handling
+ management
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.identity.event.handler.notification
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ prefilter-resources
+ generate-resources
+
+ copy-resources
+
+
+ src/main/resources
+
+
+ resources
+
+ EmailPublisher.xml
+ SMSPublisher.xml
+ id_gov_notify_stream_1.0.0.json
+ p2.inf
+ id_gov_sms_notify_stream_1.0.0.json
+
+
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.event.handler.notification.server
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:server
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification:org.wso2.carbon.identity.event.handler.notification
+
+
+ org.wso2.carbon.core:compatible:${carbon.kernel.feature.version}
+ org.wso2.carbon.identity.core.server:greaterOrEqual:${carbon.identity.framework.version}
+ org.wso2.carbon.event.output.adapter.server:compatible:${carbon.analytics.common.version}
+ org.wso2.carbon.event.output.adapter.email.server:compatible:${carbon.analytics.common.version}
+ org.wso2.carbon.email.mgt.server:compatible:${identity.event.handler.notification.exp.pkg.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.1
+
+
+ clean_target
+ install
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 7be94e750..78dfb9987 100644
--- a/pom.xml
+++ b/pom.xml
@@ -174,6 +174,11 @@
org.wso2.carbon.identity.secret.mgt.core
${carbon.identity.framework.version}
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.external.api.token.handler
+ ${carbon.identity.framework.version}
+
@@ -290,6 +295,12 @@
${com.fasterxml.jackson.databind.version}
+
+ org.apache.httpcomponents.wso2
+ httpcore
+ ${httpcore.version}
+
+
org.wso2.carbon.identity.organization.management.core
@@ -534,7 +545,7 @@
[2.1.0,3.0.0)
- 7.8.249
+ 7.8.596-SNAPSHOT
[7.1.0, 8.0.0)
@@ -553,6 +564,9 @@
2.9.0
[2.3.1,3.0.0)
+ 4.4.14.wso2v1
+ [4.3.0, 5.0.0)
+
5.1.2
3.8.0
diff --git a/pom.xml.versionsBackup b/pom.xml.versionsBackup
new file mode 100644
index 000000000..91a5fddca
--- /dev/null
+++ b/pom.xml.versionsBackup
@@ -0,0 +1,476 @@
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ pom
+ 1.8.3-SNAPSHOT
+ 4.0.0
+ http://wso2.org
+
+
+ org.wso2
+ wso2
+ 1.4
+
+
+
+ https://github.com/wso2-extensions/identity-event-handler-notification.git
+ scm:git:https://github.com/wso2-extensions/identity-event-handler-notification.git
+ scm:git:https://github.com/wso2-extensions/identity-event-handler-notification.git
+ HEAD
+
+
+
+ components/email-mgt/org.wso2.carbon.email.mgt
+ components/email-mgt/org.wso2.carbon.email.mgt.ui
+ components/event-handler-notification/org.wso2.carbon.identity.event.handler.notification
+ components/notification-sender-config/org.wso2.carbon.identity.notification.sender.tenant.config
+ service-stubs/identity/org.wso2.carbon.email.mgt.stub
+
+ features/org.wso2.carbon.email.mgt.server.feature
+ features/org.wso2.carbon.email.mgt.ui.feature
+ features/org.wso2.carbon.email.mgt.feature
+ features/org.wso2.carbon.event.handler.notification.server.feature
+
+
+
+
+
+
+
+
+
+
+ org.apache.axis2.wso2
+ axis2
+ ${axis2.wso2.version}
+
+
+ org.apache.axis2.wso2
+ axis2-client
+ ${axis2.wso2.version}
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+ ${axiom.wso2.version}
+
+
+ org.apache.axis2.transport
+ axis2-transport-mail
+ ${axis2-transports.version}
+
+
+ org.wso2.orbit.org.owasp.encoder
+ encoder
+ ${encoder.wso2.version}
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+ ${carbon.kernel.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+ ${carbon.kernel.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.core
+ ${carbon.kernel.version}
+
+
+ org.wso2.carbon
+ javax.cache.wso2
+ ${carbon.kernel.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+ ${carbon.kernel.version}
+
+
+ org.wso2.carbon
+ org.wso2.carbon.ui
+ ${carbon.kernel.version}
+
+
+
+
+ org.wso2.carbon.commons
+ org.wso2.carbon.tenant.common
+ ${carbon.commons.version}
+
+
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.base
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.event
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.core
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.authentication.framework
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.central.log.mgt
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.configuration.mgt.core
+ ${carbon.identity.framework.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.mgt
+ ${carbon.identity.framework.version}
+
+
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.output.adapter.core
+ ${carbon.analytics.common.version}
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.stream.core
+ ${carbon.analytics.common.version}
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.event.publisher.core
+ ${carbon.analytics.common.version}
+
+
+ org.wso2.carbon.analytics-common
+ org.wso2.carbon.databridge.commons
+ ${carbon.analytics.common.version}
+
+
+
+
+ org.wso2.carbon.identity.governance
+ org.wso2.carbon.identity.governance
+ ${identity.governance.version}
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.base
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.event
+
+
+
+
+ org.wso2.carbon.identity.governance
+ org.wso2.carbon.identity.tenant.resource.manager
+ ${identity.governance.version}
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt
+ ${project.version}
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.server.feature
+ ${project.version}
+ zip
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.ui.feature
+ ${project.version}
+ zip
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.ui
+ ${project.version}
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.identity.notification.sender.tenant.config
+ ${project.version}
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.email.mgt.stub
+ ${project.version}
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ org.wso2.carbon.identity.event.handler.notification
+ ${project.version}
+
+
+ org.wso2.carbon.identity.branding.preference.management
+ org.wso2.carbon.identity.branding.preference.management.core
+ ${identity.branding.preference.management.version}
+
+
+ commons-lang.wso2
+ commons-lang
+ ${commons-lang.wso2.version}
+
+
+
+ com.google.code.gson
+ gson
+ ${com.google.code.gson.version}
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${com.fasterxml.jackson.databind.version}
+
+
+
+
+ org.wso2.carbon.identity.organization.management.core
+ org.wso2.carbon.identity.organization.management.service
+ ${identity.organization.management.core.version}
+
+
+
+
+ org.testng
+ testng
+ ${testng.version}
+ test
+
+
+ org.powermock
+ powermock-module-testng
+ ${powermock.version}
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ ${powermock.version}
+ test
+
+
+ org.mockito
+ mockito-all
+ ${mockito.version}
+ test
+
+
+ org.mockito
+ mockito-inline
+ ${mockito.inline.version}
+ test
+
+
+
+ org.jacoco
+ org.jacoco.agent
+ runtime
+ ${jacoco.version}
+
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+ ${pax.logging.api.version}
+
+
+ org.apache.felix
+ org.apache.felix.scr.ds-annotations
+ ${apache.felix.scr.ds.annotations.version}
+
+
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ ${maven.bundle.plugin.version}
+ true
+
+ NONE
+
+ ${buildNumber}
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ ${maven.findbugsplugin.version}
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ ${maven.checkstyleplugin.version}
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+
+ clean install
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+
+ org.codehaus.mojo
+ buildnumber-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ 1.8
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+ none
+
+
+
+
+
+
+
+
+
+ 1.5.77
+ [1.0.0, 3.0.0)
+
+
+ ${project.version}
+ [1.2.0, 2.0.0)
+
+ [1.7.0, 2.0.0)
+ [1.2.0, 2.0.0)
+
+ 1.0.8
+ [1.0.1, 2.0.0)
+
+
+ 1.6.1-wso2v38
+ [1.6.1-wso2v38, 2.0.0)
+ 1.2.11-wso2v16
+ [1.2.11, 2.0.0)
+ 2.0.0-wso2v38
+ 1.2.0.wso2v1
+
+ 2.6.0.wso2v1
+ [1.2,2.0)
+ [2.6.0,3.0.0)
+ [2.6.0,3.0.0)
+
+
+ 4.9.10
+ 4.9.10
+ [4.5.0, 5.0.0)
+
+ [1.0.1, 2.0.0)
+ [1.0.1, 2.0.0)
+ [1.0.0, 2.0.0)
+ [1.6.1, 2.0.0)
+
+
+ 4.7.11
+ [4.7.11, 5.0.0)
+
+
+ 5.25.617
+ [5.14.67, 8.0.0)
+
+
+ 1.0.93
+ [1.0.0,2.0.0)
+
+
+
+ 5.2.10
+ [5.2.10,6.0.0)
+
+
+ 2.9.0
+ [2.3.1,3.0.0)
+
+
+ 1.5.3
+ 2.3.1
+ 3.2.0
+ 1.4
+
+
+ 6.9.10
+ 1.7.0
+ 1.10.19
+ 3.8.0
+ 0.7.9
+ 2.18.1
+
+
+ 1.10.1
+
+ 1.2.4
+ 2.17
+ 3.0.5
+ findbugs-exclude-filter.xml
+
+ 2.13.3
+
+
diff --git a/service-stubs/identity/org.wso2.carbon.email.mgt.stub/pom.xml.versionsBackup b/service-stubs/identity/org.wso2.carbon.email.mgt.stub/pom.xml.versionsBackup
new file mode 100644
index 000000000..c35c9e71b
--- /dev/null
+++ b/service-stubs/identity/org.wso2.carbon.email.mgt.stub/pom.xml.versionsBackup
@@ -0,0 +1,113 @@
+
+
+
+
+
+ org.wso2.carbon.identity.event.handler.notification
+ identity-event-handler-notification
+ 1.8.3-SNAPSHOT
+ ../../../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.email.mgt.stub
+ bundle
+ WSO2 Carbon - Email Management Stub
+ http://wso2.org
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.1
+
+
+ source-code-generation
+ process-resources
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ add-source
+ generate-sources
+
+ add-source
+
+
+
+
+ target/generated-code/src
+
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+
+ org.wso2.carbon.email.mgt.model.xsd;version="${identity.event.handler.notification.exp.pkg.version}",
+ org.wso2.carbon.email.mgt.exceptions.xsd;version="${identity.event.handler.notification.exp.pkg.version}",
+ org.wso2.carbon.email.mgt.stub;version="${identity.event.handler.notification.exp.pkg.version}",
+
+
+
+
+
+
+
+
+
+ org.apache.axis2.wso2
+ axis2
+
+
+ org.apache.axis2.wso2
+ axis2-client
+
+
+