diff --git a/keycloak/sms-provider/dependency-reduced-pom.xml b/keycloak/sms-provider/dependency-reduced-pom.xml new file mode 100644 index 00000000..d7f9ecd5 --- /dev/null +++ b/keycloak/sms-provider/dependency-reduced-pom.xml @@ -0,0 +1,156 @@ + + + 4.0.0 + org.sunbird + keycloak-email-phone-autthenticator + 1.0-SNAPSHOT + + + + maven-shade-plugin + 3.0.0 + + + package + + shade + + + + + classworlds:classworlds + junit:junit + jmock:* + *:xml-apis + org.apache.maven:lib:tests + + + + + + + + + + + org.keycloak + keycloak-core + 3.2.0.Final + provided + + + keycloak-common + org.keycloak + + + bcprov-jdk15on + org.bouncycastle + + + bcpkix-jdk15on + org.bouncycastle + + + + + org.keycloak + keycloak-server-spi + 3.2.0.Final + provided + + + org.keycloak + keycloak-server-spi-private + 3.2.0.Final + provided + + + org.jboss.logging + jboss-logging + 3.3.1.Final + provided + + + org.keycloak + keycloak-services + 3.2.0.Final + provided + + + javax.mail-api + javax.mail + + + jboss-servlet-api_3.0_spec + org.jboss.spec.javax.servlet + + + twitter4j-core + org.twitter4j + + + resteasy-jaxrs + org.jboss.resteasy + + + jboss-jaxrs-api_2.0_spec + org.jboss.spec.javax.ws.rs + + + jboss-transaction-api_1.2_spec + org.jboss.spec.javax.transaction + + + resteasy-multipart-provider + org.jboss.resteasy + + + javase + com.google.zxing + + + bcprov-jdk15on + org.bouncycastle + + + bcpkix-jdk15on + org.bouncycastle + + + + + org.apache.httpcomponents + httpclient + 4.5 + provided + + + httpcore + org.apache.httpcomponents + + + commons-codec + commons-codec + + + + + junit + junit + 4.12 + test + + + hamcrest-core + org.hamcrest + + + + + + UTF-8 + 1.8 + 1.8 + + + diff --git a/keycloak/sms-provider/keycloak-email-phone-autthenticator.iml b/keycloak/sms-provider/keycloak-email-phone-autthenticator.iml index 8c11a5d4..9063f681 100644 --- a/keycloak/sms-provider/keycloak-email-phone-autthenticator.iml +++ b/keycloak/sms-provider/keycloak-email-phone-autthenticator.iml @@ -6,6 +6,7 @@ + @@ -56,5 +57,8 @@ + + + \ No newline at end of file diff --git a/keycloak/sms-provider/pom.xml b/keycloak/sms-provider/pom.xml index 47c17cf8..38dfb19e 100644 --- a/keycloak/sms-provider/pom.xml +++ b/keycloak/sms-provider/pom.xml @@ -86,6 +86,11 @@ aws-java-sdk-sns 1.11.173 + + com.google.code.gson + gson + 2.3.1 + junit junit diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorConstants.java b/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorConstants.java index edd6b353..90e6b458 100644 --- a/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorConstants.java +++ b/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorConstants.java @@ -21,4 +21,7 @@ public class KeycloakSmsAuthenticatorConstants { // User credentials (used to persist the sent sms code + expiration time cluster wide) public static final String USR_CRED_MDL_SMS_CODE = "sms-auth.code"; public static final String USR_CRED_MDL_SMS_EXP_TIME = "sms-auth.exp-time"; + + public static final String AMAZON_SNS_PROVIDER_CONFIGURATIONS_PATH = "sms-provider/awsSnsCreds.json"; + public static final String MSG91_SMS_PROVIDER_CONFIGURATIONS_PATH = "sms-provider/Msg91Creds.json"; } diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorUtil.java b/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorUtil.java index 60254461..f8e3dba4 100644 --- a/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorUtil.java +++ b/keycloak/sms-provider/src/main/java/org/sunbird/keycloak/KeycloakSmsAuthenticatorUtil.java @@ -1,12 +1,16 @@ package org.sunbird.keycloak; -import com.amazonaws.services.sns.model.PublishResult; +import com.amazonaws.util.StringUtils; import org.jboss.logging.Logger; import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.UserModel; -import org.sunbird.aws.snsclient.SnsNotificationService; +import org.sunbird.sms.msg91.Msg91SmsProviderFactory; +import org.sunbird.sms.provider.ISmsProvider; +import org.sunbird.utils.JsonUtil; +import java.io.File; import java.util.List; +import java.util.Map; import java.util.Random; /** @@ -84,20 +88,32 @@ public static String setDefaultCountryCodeIfZero(String mobileNumber) { } static boolean sendSmsCode(String mobileNumber, String code, AuthenticatorConfigModel config) { - // Send an SMS - KeycloakSmsAuthenticatorUtil.logger.debug("Sending " + code + " to mobileNumber " + mobileNumber); + String smsText = createMessage(code, mobileNumber, config); + logger.debug("KeycloakSmsAuthenticatorUtil@sendSmsCode : smsText - " + smsText); - String smsUsr = getConfigString(config, KeycloakSmsAuthenticatorConstants.CONF_PRP_SMS_CLIENTTOKEN); - String smsPwd = getConfigString(config, KeycloakSmsAuthenticatorConstants.CONF_PRP_SMS_CLIENTSECRET); + Boolean msg91SmsProviderStatus = send(mobileNumber, smsText); + if (msg91SmsProviderStatus != null) return msg91SmsProviderStatus; - String smsText = createMessage(code, mobileNumber, config); - try { - PublishResult send_result = new SnsNotificationService().send(setDefaultCountryCodeIfZero(mobileNumber), smsText, smsUsr, smsPwd); - return true; - } catch (Exception e) { - //Just like pokemon - return false; + return false; + } + + private static Boolean send(String mobileNumber, String code) { + String filePath = new File(KeycloakSmsAuthenticatorConstants.MSG91_SMS_PROVIDER_CONFIGURATIONS_PATH).getAbsolutePath(); + logger.debug("KeycloakSmsAuthenticatorUtil@sendSmsCode : filePath - " + filePath); + + if (!StringUtils.isNullOrEmpty(filePath)) { + Map configurations = JsonUtil.readFromJson(filePath); + logger.debug("KeycloakSmsAuthenticatorUtil@sendSmsCode : configurations - " + configurations); + + Msg91SmsProviderFactory msg91SmsProviderFactory = new Msg91SmsProviderFactory(); + + ISmsProvider msg91SmsProvider = msg91SmsProviderFactory.create(configurations); + + if (msg91SmsProvider != null) { + return msg91SmsProvider.send(mobileNumber, code); + } } + return null; } static String getSmsCode(long nrOfDigits) { diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/SMSConfigurationUtil.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/SMSConfigurationUtil.java new file mode 100644 index 00000000..fe860d12 --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/SMSConfigurationUtil.java @@ -0,0 +1,23 @@ +package org.sunbird.sms; + +import java.util.Map; + +public class SMSConfigurationUtil { + + public static String getConfigString(Map config, String configName) { + return getConfigString(config, configName, null); + } + + public static String getConfigString(Map config, String configName, String defaultValue) { + + String value = defaultValue; + + if (config.containsKey(configName)) { + // Get value + value = config.get(configName); + } + + return value; + } + +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/SmsConfigurationConstants.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/SmsConfigurationConstants.java new file mode 100644 index 00000000..7c38711a --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/SmsConfigurationConstants.java @@ -0,0 +1,23 @@ +package org.sunbird.sms; + +public final class SmsConfigurationConstants { + public static final String CONF_SMS_TOKEN = "token"; + public static final String CONF_SMS_SECRET = "secret"; + public static final String CONF_SMS_BASE_URL = "sms_base_url"; + public static final String CONF_SMS_GET_URL = "sms_get_url"; + public static final String CONF_SMS_POST_URL = "sms_post_url"; + public static final String CONF_SMS_METHOD_TYPE = "sms_method_type"; + public static final String CONF_SMS_USERNAME = "sms_username"; + public static final String CONF_SMS_PASSWORD = "sms_password"; + public static final String CONF_SMS_AUTHTYPE = "sms_authtype"; + public static final String CONF_SMS_CONTENT_TYPE = "sms_content_type"; + public static final String CONF_SMS_PROXY_URL = "sms_proxy_url"; + public static final String CONF_SMS_PROXY_USERNAME = "sms_proxy_username"; + public static final String CONF_SMS_PROXY_PASSWORD = "sms_proxy_password"; + public static final String CONF_AUTH_METHOD_BASIC = "basic_authentication"; + public static final String CONF_AUTH_METHOD_INMESSAGE = "in_message_authentication"; + public static final String CONF_AUTH_KEY = "auth_key"; + public static final String CONF_SMS_SENDER = "sender"; + public static final String CONF_SMS_COUNTRY = "country"; + public static final String CONF_SMS_ROUTE = "route"; +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsFactory.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsFactory.java new file mode 100644 index 00000000..a7e0fc08 --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsFactory.java @@ -0,0 +1,21 @@ +package org.sunbird.sms.amazonsns; + + +import org.sunbird.sms.provider.ISmsProvider; +import org.sunbird.sms.provider.ISmsProviderFactory; + +import java.util.Map; + +public class AmazonSnsFactory implements ISmsProviderFactory { + private static AmazonSnsProvider amazonSnsProvider = null; + + @Override + public ISmsProvider create(Map configurations) { + if (amazonSnsProvider == null) { + amazonSnsProvider = new AmazonSnsProvider(); + amazonSnsProvider.configure(configurations); + } + + return amazonSnsProvider; + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsProvider.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsProvider.java new file mode 100644 index 00000000..314ba57b --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/amazonsns/AmazonSnsProvider.java @@ -0,0 +1,52 @@ +package org.sunbird.sms.amazonsns; + +import com.amazonaws.services.sns.model.MessageAttributeValue; +import com.amazonaws.services.sns.model.PublishRequest; +import org.jboss.logging.Logger; +import org.sunbird.aws.snsclient.SnsClientFactory; +import org.sunbird.sms.SMSConfigurationUtil; +import org.sunbird.sms.SmsConfigurationConstants; +import org.sunbird.sms.provider.ISmsProvider; + +import java.util.HashMap; +import java.util.Map; + +public class AmazonSnsProvider implements ISmsProvider { + + private static Logger logger = Logger.getLogger(AmazonSnsProvider.class); + + private Map configurations; + + @Override + public boolean send(String phoneNumber, String smsText) { + logger.debug("AmazonSnsProvider@send : phoneNumber - " + phoneNumber + " & Sms text - " + smsText); + + Map smsAttributes = new HashMap(); + smsAttributes.put("AWS.SNS.SMS.SenderID", new MessageAttributeValue() + .withStringValue("HomeOffice") + .withDataType("String")); + + String clientToken = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_TOKEN); + String clientSecret = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_SECRET); + + logger.debug("AmazonSnsProvider@send : clientToken - " + clientToken + " & clientSecret - " + clientSecret); + + + try { + SnsClientFactory.getSnsClient(clientToken, clientSecret).publish(new PublishRequest() + .withMessage(smsText) + .withPhoneNumber(phoneNumber) + .withMessageAttributes(smsAttributes)); + + return true; + } catch (Exception e) { + logger.debug("AmazonSnsProvider@Send : Exception Caught -" + e.getMessage()); + return false; + } + } + + @Override + public void configure(Map configurations) { + this.configurations = configurations; + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProvider.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProvider.java new file mode 100644 index 00000000..13f27cb4 --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProvider.java @@ -0,0 +1,318 @@ +package org.sunbird.sms.msg91; + +import com.amazonaws.util.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.StatusLine; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.jboss.logging.Logger; +import org.sunbird.keycloak.KeycloakSmsAuthenticatorUtil; +import org.sunbird.sms.SMSConfigurationUtil; +import org.sunbird.sms.SmsConfigurationConstants; +import org.sunbird.sms.provider.ISmsProvider; +import org.sunbird.utils.JsonUtil; + +import javax.ws.rs.HttpMethod; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Msg91SmsProvider implements ISmsProvider { + + private static Logger logger = Logger.getLogger(Msg91SmsProvider.class); + + private Map configurations; + + @Override + public void configure(Map configurations) { + this.configurations = configurations; + } + + @Override + public boolean send(String phoneNumber, String smsText) { + return sendSms(phoneNumber, smsText); + } + + private boolean sendSms(String mobileNumber, String smsText) { + // Send an SMS + logger.debug("Msg91SmsProvider@Sending " + smsText + " to mobileNumber " + mobileNumber); + + String gateWayUrl = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_BASE_URL); + String authKey = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_AUTH_KEY); + String sender = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_SENDER); + String country = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_COUNTRY); + String smsMethodType = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_METHOD_TYPE); + String smsRoute = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_ROUTE); + String httpMethod = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_METHOD_TYPE); + String getUrlPoint = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_GET_URL); + String getPostPoint = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_POST_URL); + + logger.debug("Msg91SmsProvider@SMS Provider parameters \n" + + "Gateway - " + gateWayUrl + "\n" + + "authKey - " + authKey + "\n" + + "sender - " + sender + "\n" + + "country - " + country + "\n" + + "smsMethodType - " + smsMethodType + "\n" + + "smsRoute - " + smsRoute + "\n" + ); + + + CloseableHttpClient httpClient = null; + try { + URL smsURL = (gateWayUrl != null && gateWayUrl.length() > 0) ? new URL(gateWayUrl) : null; + + if (smsURL == null) { + logger.error("Msg91SmsProvider@ SMS gateway URL is not configured."); + return false; + } + + httpClient = HttpClients.createDefault(); + + String path = null; + + if (!StringUtils.isNullOrEmpty(gateWayUrl) && !StringUtils.isNullOrEmpty(sender) && !StringUtils.isNullOrEmpty(smsRoute) + && !StringUtils.isNullOrEmpty(mobileNumber) && !StringUtils.isNullOrEmpty(authKey) && !StringUtils.isNullOrEmpty(country) + && !StringUtils.isNullOrEmpty(smsText)) { + + if (httpMethod.equals(HttpMethod.GET)) { + logger.debug("Inside GET"); + path = getCompletePath(gateWayUrl + getUrlPoint, sender, smsRoute, KeycloakSmsAuthenticatorUtil.setDefaultCountryCodeIfZero(mobileNumber), authKey, country, URLEncoder.encode(smsText, "UTF-8")); + + logger.debug("Msg91SmsProvider -Executing request - " + path); + + HttpGet httpGet = new HttpGet(path); + + CloseableHttpResponse response = httpClient.execute(httpGet); + StatusLine sl = response.getStatusLine(); + response.close(); + if (sl.getStatusCode() != 200) { + logger.error("SMS code for " + mobileNumber + " could not be sent: " + sl.getStatusCode() + " - " + sl.getReasonPhrase()); + } + return sl.getStatusCode() == 200; + } else if (httpMethod.equals(HttpMethod.POST)) { + logger.debug("Inside POST"); + + path = gateWayUrl + getPostPoint; + logger.debug("Msg91SmsProvider -Executing request - " + path); + + HttpPost httpPost = new HttpPost(path); + + //add content-type headers + httpPost.setHeader("content-type", "application/json"); + + //add authkey header + httpPost.setHeader("authkey", authKey); + + List mobileNumbers = new ArrayList<>(); + mobileNumbers.add(mobileNumber); + + //create sms + Sms sms = new Sms(URLEncoder.encode(smsText, "UTF-8"), mobileNumbers); + + List smsList = new ArrayList<>(); + smsList.add(sms); + + //create body + ProviderDetails providerDetails = new ProviderDetails(sender, smsRoute, country, smsList); + + String providerDetailsString = JsonUtil.toJson(providerDetails); + + if (!StringUtils.isNullOrEmpty(providerDetailsString)) { + logger.debug("Msg91SmsProvider - Body - " + providerDetailsString); + + HttpEntity entity = new ByteArrayEntity(providerDetailsString.getBytes("UTF-8")); + httpPost.setEntity(entity); + + CloseableHttpResponse response = httpClient.execute(httpPost); + StatusLine sl = response.getStatusLine(); + response.close(); + if (sl.getStatusCode() != 200) { + logger.error("SMS code for " + mobileNumber + " could not be sent: " + sl.getStatusCode() + " - " + sl.getReasonPhrase()); + } + return sl.getStatusCode() == 200; + } else { + return false; + } + } + + } else { + logger.debug("Msg91SmsProvider - Some mandatory parameters are empty!"); + return false; + } + } catch (IOException e) { + logger.error(e); + return false; + } finally { + if (httpClient != null) { + try { + httpClient.close(); + } catch (IOException ignore) { + // Ignore ... + } + } + } + return false; + } + + private String getCompletePath(String gateWayUrl, String sender, String smsRoute, String mobileNumber, String authKey, String country, String smsText) { + String completeUrl = gateWayUrl + + "sender=" + sender + + "&route=" + smsRoute + + "&mobiles=" + mobileNumber + + "&authkey=" + authKey + + "&country=" + country + + "&message=" + smsText; + return completeUrl; + } + + + private boolean sendSmsCode(String mobileNumber, String smsText) { + // Send an SMS + logger.debug("Sending " + smsText + " to mobileNumber " + mobileNumber); + + String smsUrl = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_BASE_URL); + String smsUsr = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_USERNAME); + String smsPwd = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_PASSWORD); + + String proxyUrl = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_PROXY_URL); + String proxyUsr = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_PROXY_USERNAME); + String proxyPwd = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_PROXY_PASSWORD); + String contentType = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_CONTENT_TYPE); + + CloseableHttpClient httpClient = null; + try { + URL smsURL = (smsUrl != null && smsUrl.length() > 0) ? new URL(smsUrl) : null; + URL proxyURL = (proxyUrl != null && proxyUrl.length() > 0) ? new URL(proxyUrl) : null; + + if (smsURL == null) { + logger.error("SMS gateway URL is not configured."); + return false; + } + + + CredentialsProvider credsProvider; + if (SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_AUTHTYPE, "").equals(SmsConfigurationConstants.CONF_AUTH_METHOD_INMESSAGE)) { + credsProvider = getCredentialsProvider(null, null, proxyUsr, proxyPwd, smsURL, proxyURL); + } else { + credsProvider = getCredentialsProvider(smsUsr, smsPwd, proxyUsr, proxyPwd, smsURL, proxyURL); + } + + HttpHost target = new HttpHost(smsURL.getHost(), smsURL.getPort(), smsURL.getProtocol()); + HttpHost proxy = (proxyURL != null) ? new HttpHost(proxyURL.getHost(), proxyURL.getPort(), proxyURL.getProtocol()) : null; + + httpClient = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider) + .build(); + + RequestConfig requestConfig; + requestConfig = RequestConfig.custom() + .setProxy(proxy) + .build(); + + String httpMethod = SMSConfigurationUtil.getConfigString(configurations, SmsConfigurationConstants.CONF_SMS_METHOD_TYPE); + if (httpMethod.equals(HttpMethod.GET)) { + + String path = getPath(mobileNumber, smsURL, smsText); + + HttpGet httpGet = new HttpGet(path); + httpGet.setConfig(requestConfig); + if (isNotEmpty(contentType)) { + httpGet.addHeader("Content-type", contentType); + } + + logger.debug("Executing request " + httpGet.getRequestLine() + " to " + target + " via " + proxy); + + CloseableHttpResponse response = httpClient.execute(target, httpGet); + StatusLine sl = response.getStatusLine(); + response.close(); + if (sl.getStatusCode() != 200) { + logger.error("SMS code for " + mobileNumber + " could not be sent: " + sl.getStatusCode() + " - " + sl.getReasonPhrase()); + } + return sl.getStatusCode() == 200; + + } else if (httpMethod.equals(HttpMethod.POST)) { + + String path = getPath(mobileNumber, smsURL, smsText); + String uri = smsURL.getProtocol() + "://" + smsURL.getHost() + ":" + smsURL.getPort() + path; + + HttpPost httpPost = new HttpPost(uri); + httpPost.setConfig(requestConfig); + if (isNotEmpty(contentType)) { + httpPost.addHeader("Content-type", contentType); + } + + HttpEntity entity = new ByteArrayEntity(smsText.getBytes("UTF-8")); + httpPost.setEntity(entity); + + CloseableHttpResponse response = httpClient.execute(httpPost); + StatusLine sl = response.getStatusLine(); + response.close(); + if (sl.getStatusCode() != 200) { + logger.error("SMS code for " + mobileNumber + " could not be sent: " + sl.getStatusCode() + " - " + sl.getReasonPhrase()); + } + return sl.getStatusCode() == 200; + } + return true; + } catch (IOException e) { + logger.error(e); + return false; + } finally { + if (httpClient != null) { + try { + httpClient.close(); + } catch (IOException ignore) { + // Ignore ... + } + } + } + } + + private CredentialsProvider getCredentialsProvider(String smsUsr, String smsPwd, String proxyUsr, String proxyPwd, URL smsURL, URL proxyURL) { + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + + // If defined, add BASIC Authentication parameters + if (isNotEmpty(smsUsr) && isNotEmpty(smsPwd)) { + credsProvider.setCredentials( + new AuthScope(smsURL.getHost(), smsURL.getPort()), + new UsernamePasswordCredentials(smsUsr, smsPwd)); + + } + + // If defined, add Proxy Authentication parameters + if (isNotEmpty(proxyUsr) && isNotEmpty(proxyPwd)) { + credsProvider.setCredentials( + new AuthScope(proxyURL.getHost(), proxyURL.getPort()), + new UsernamePasswordCredentials(proxyUsr, proxyPwd)); + + } + return credsProvider; + } + + private String getPath(String mobileNumber, URL smsURL, String smsText) throws UnsupportedEncodingException { + String path = smsURL.getPath(); + if (smsURL.getQuery() != null && smsURL.getQuery().length() > 0) { + path += smsURL.getQuery(); + } + path = path.replaceFirst("\\{message\\}", URLEncoder.encode(smsText, "UTF-8")); + path = path.replaceFirst("\\{phonenumber\\}", URLEncoder.encode(mobileNumber, "UTF-8")); + return path; + } + + private boolean isNotEmpty(String s) { + return (s != null && s.length() > 0); + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProviderFactory.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProviderFactory.java new file mode 100644 index 00000000..73b4f4d2 --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Msg91SmsProviderFactory.java @@ -0,0 +1,21 @@ +package org.sunbird.sms.msg91; + +import org.sunbird.sms.provider.ISmsProvider; +import org.sunbird.sms.provider.ISmsProviderFactory; + +import java.util.Map; + +public class Msg91SmsProviderFactory implements ISmsProviderFactory { + + private static Msg91SmsProvider msg91SmsProvider = null; + + @Override + public ISmsProvider create(Map configurations) { + if (msg91SmsProvider == null){ + msg91SmsProvider = new Msg91SmsProvider(); + msg91SmsProvider.configure(configurations); + } + + return msg91SmsProvider; + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/ProviderDetails.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/ProviderDetails.java new file mode 100644 index 00000000..5668de4d --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/ProviderDetails.java @@ -0,0 +1,18 @@ +package org.sunbird.sms.msg91; + +import java.io.Serializable; +import java.util.List; + +public class ProviderDetails implements Serializable { + private String sender; + private String route; + private String country; + private List sms; + + public ProviderDetails(String sender, String route, String country, List sms) { + this.sender = sender; + this.route = route; + this.country = country; + this.sms = sms; + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Sms.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Sms.java new file mode 100644 index 00000000..f5b692c1 --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/msg91/Sms.java @@ -0,0 +1,15 @@ +package org.sunbird.sms.msg91; + +import java.io.Serializable; +import java.util.List; + +public class Sms implements Serializable{ + + private String message; + private List to; + + public Sms(String message, List to) { + this.message = message; + this.to = to; + } +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProvider.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProvider.java new file mode 100644 index 00000000..987d926a --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProvider.java @@ -0,0 +1,10 @@ +package org.sunbird.sms.provider; + +import java.util.Map; + +public interface ISmsProvider { + + void configure(Map configurations); + + boolean send(String phoneNumber, String smsText); +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProviderFactory.java b/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProviderFactory.java new file mode 100644 index 00000000..a0497ddf --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/sms/provider/ISmsProviderFactory.java @@ -0,0 +1,8 @@ +package org.sunbird.sms.provider; + +import java.util.Map; + +public interface ISmsProviderFactory { + + ISmsProvider create(Map configurations); +} diff --git a/keycloak/sms-provider/src/main/java/org/sunbird/utils/JsonUtil.java b/keycloak/sms-provider/src/main/java/org/sunbird/utils/JsonUtil.java new file mode 100644 index 00000000..66972a6c --- /dev/null +++ b/keycloak/sms-provider/src/main/java/org/sunbird/utils/JsonUtil.java @@ -0,0 +1,38 @@ +package org.sunbird.utils; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +public class JsonUtil { + + public static Map readFromJson(String jsonFile) { + ObjectMapper mapper = new ObjectMapper(); + + // read JSON from a file + Map map = null; + + try { + map = mapper.readValue( + new File(jsonFile), + new TypeReference>() { + }); + } catch (IOException e) { + e.printStackTrace(); + } + + return map; + } + + + public static String toJson(Object object) { + Gson gsonObj = new Gson(); + + return gsonObj.toJson(object); + } + +}