Merge pull request #593 from wso2/cloud-3.1.0

Merging to 3.1.0-test from Cloud 3.1.0 - Till Feb-28
revert-dabc3590
Susinda Perera 8 years ago committed by GitHub
commit 6f9ea52218

@ -67,7 +67,8 @@
feign.gson, feign.gson,
org.json.simple.*, org.json.simple.*,
org.wso2.carbon.appmgt.mobile.beans, org.wso2.carbon.appmgt.mobile.beans,
org.wso2.carbon.context org.wso2.carbon.context,
javax.net.ssl
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.appmgt.mdm.restconnector.internal, !org.wso2.carbon.appmgt.mdm.restconnector.internal,

@ -17,6 +17,7 @@
*/ */
package org.wso2.carbon.appmgt.mdm.restconnector; package org.wso2.carbon.appmgt.mdm.restconnector;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.gson.GsonDecoder; import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder; import feign.gson.GsonEncoder;
@ -44,6 +45,14 @@ import org.wso2.carbon.appmgt.mobile.utils.MobileApplicationException;
import org.wso2.carbon.appmgt.mobile.utils.MobileConfigurations; import org.wso2.carbon.appmgt.mobile.utils.MobileConfigurations;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -62,12 +71,12 @@ public class ApplicationOperationsImpl implements ApplicationOperations {
public ApplicationOperationsImpl() { public ApplicationOperationsImpl() {
String authorizationConfigManagerServerURL = AuthorizationConfigurationManager.getInstance().getServerURL(); String authorizationConfigManagerServerURL = AuthorizationConfigurationManager.getInstance().getServerURL();
OAuthRequestInterceptor oAuthRequestInterceptor = new OAuthRequestInterceptor(); OAuthRequestInterceptor oAuthRequestInterceptor = new OAuthRequestInterceptor();
deviceManagementAdminService = Feign.builder() deviceManagementAdminService = Feign.builder().client(getSSLClient())
.requestInterceptor(oAuthRequestInterceptor) .requestInterceptor(oAuthRequestInterceptor)
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceManagementAdminService.class, .target(DeviceManagementAdminService.class,
authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT); authorizationConfigManagerServerURL + CDMF_SERVER_BASE_CONTEXT);
applicationManagementAdminService = Feign.builder() applicationManagementAdminService = Feign.builder().client(getSSLClient())
.requestInterceptor(oAuthRequestInterceptor) .requestInterceptor(oAuthRequestInterceptor)
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApplicationManagementAdminService.class, .target(ApplicationManagementAdminService.class,
@ -271,4 +280,37 @@ public class ApplicationOperationsImpl implements ApplicationOperations {
log.error(errorMessage); log.error(errorMessage);
} }
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -17,6 +17,7 @@
*/ */
package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client; package org.wso2.carbon.appmgt.mdm.restconnector.authorization.client;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.RequestInterceptor; import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
@ -33,6 +34,15 @@ import org.wso2.carbon.appmgt.mdm.restconnector.authorization.client.dto.TokenIs
import org.wso2.carbon.appmgt.mdm.restconnector.config.AuthorizationConfigurationManager; import org.wso2.carbon.appmgt.mdm.restconnector.config.AuthorizationConfigurationManager;
import org.wso2.carbon.appmgt.mdm.restconnector.internal.AuthorizationDataHolder; import org.wso2.carbon.appmgt.mdm.restconnector.internal.AuthorizationDataHolder;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
/** /**
* This is a request interceptor to add oauth token header. * This is a request interceptor to add oauth token header.
*/ */
@ -54,7 +64,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset(); refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset();
String username = AuthorizationConfigurationManager.getInstance().getUserName(); String username = AuthorizationConfigurationManager.getInstance().getUserName();
String password = AuthorizationConfigurationManager.getInstance().getPassword(); String password = AuthorizationConfigurationManager.getInstance().getPassword();
apiApplicationRegistrationService = Feign.builder().requestInterceptor( apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(username, password)) new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class, .target(ApiApplicationRegistrationService.class,
@ -82,7 +92,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String consumerSecret = apiApplicationKey.getConsumerSecret(); String consumerSecret = apiApplicationKey.getConsumerSecret();
String username = AuthorizationConfigurationManager.getInstance().getUserName(); String username = AuthorizationConfigurationManager.getInstance().getUserName();
String password = AuthorizationConfigurationManager.getInstance().getPassword(); String password = AuthorizationConfigurationManager.getInstance().getPassword();
tokenIssuerService = Feign.builder().requestInterceptor( tokenIssuerService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenApiURL()); .target(TokenIssuerService.class, AuthorizationConfigurationManager.getInstance().getTokenApiURL());
@ -98,4 +108,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String headerValue = Constants.RestConstants.BEARER + tokenInfo.getAccess_token(); String headerValue = Constants.RestConstants.BEARER + tokenInfo.getAccess_token();
template.header(Constants.RestConstants.AUTHORIZATION, headerValue); template.header(Constants.RestConstants.AUTHORIZATION, headerValue);
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -160,7 +160,8 @@
org.wso2.carbon.core.util, org.wso2.carbon.core.util,
org.wso2.carbon.identity.oauth2.*, org.wso2.carbon.identity.oauth2.*,
org.wso2.carbon.utils, org.wso2.carbon.utils,
org.wso2.carbon.utils.multitenancy org.wso2.carbon.utils.multitenancy,
javax.net.ssl
</Import-Package> </Import-Package>
<Embed-Dependency> <Embed-Dependency>
jsr311-api, jsr311-api,

@ -17,6 +17,7 @@
*/ */
package org.wso2.carbon.device.mgt.input.adapter.http.authorization; package org.wso2.carbon.device.mgt.input.adapter.http.authorization;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.FeignException; import feign.FeignException;
import feign.gson.GsonDecoder; import feign.gson.GsonDecoder;
@ -33,6 +34,14 @@ import org.wso2.carbon.device.mgt.input.adapter.http.util.AuthenticationInfo;
import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils; import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -50,7 +59,7 @@ public class DeviceAuthorizer {
public DeviceAuthorizer(Map<String, String> globalProperties) { public DeviceAuthorizer(Map<String, String> globalProperties) {
try { try {
deviceAccessAuthorizationAdminService = Feign.builder() deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient())
.requestInterceptor(new OAuthRequestInterceptor(globalProperties)) .requestInterceptor(new OAuthRequestInterceptor(globalProperties))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties) .target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties)
@ -98,4 +107,37 @@ public class DeviceAuthorizer {
} }
return deviceMgtServerUrl; return deviceMgtServerUrl;
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -14,6 +14,7 @@
package org.wso2.carbon.device.mgt.input.adapter.http.authorization.client; package org.wso2.carbon.device.mgt.input.adapter.http.authorization.client;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.RequestInterceptor; import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
@ -31,6 +32,14 @@ import org.wso2.carbon.device.mgt.input.adapter.http.authorization.client.dto.To
import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils; import org.wso2.carbon.device.mgt.input.adapter.http.util.PropertyUtils;
import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException; import org.wso2.carbon.event.input.adapter.core.exception.InputEventAdapterException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
/** /**
@ -76,7 +85,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
username = getUsername(globalProperties); username = getUsername(globalProperties);
password = getPassword(globalProperties); password = getPassword(globalProperties);
tokenEndpoint = getTokenEndpoint(globalProperties); tokenEndpoint = getTokenEndpoint(globalProperties);
apiApplicationRegistrationService = Feign.builder().requestInterceptor( apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(username, password)) new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class, .target(ApiApplicationRegistrationService.class,
@ -99,7 +108,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile); ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile);
String consumerKey = apiApplicationKey.getConsumerKey(); String consumerKey = apiApplicationKey.getConsumerKey();
String consumerSecret = apiApplicationKey.getConsumerSecret(); String consumerSecret = apiApplicationKey.getConsumerSecret();
tokenIssuerService = Feign.builder().requestInterceptor( tokenIssuerService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, tokenEndpoint); .target(TokenIssuerService.class, tokenEndpoint);
@ -158,4 +167,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
return refreshTimeOffset; return refreshTimeOffset;
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -169,7 +169,8 @@
feign.auth, feign.auth,
feign.codec, feign.codec,
feign.gson, feign.gson,
javax.cache javax.cache,
javax.net.ssl
</Import-Package> </Import-Package>
<DynamicImport-Package>*</DynamicImport-Package> <DynamicImport-Package>*</DynamicImport-Package>
<Embed-Dependency> <Embed-Dependency>

@ -17,6 +17,7 @@
*/ */
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization; package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.FeignException; import feign.FeignException;
import feign.gson.GsonDecoder; import feign.gson.GsonDecoder;
@ -35,7 +36,15 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils;
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest; import org.wso2.carbon.device.mgt.output.adapter.websocket.util.WebSocketSessionRequest;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.websocket.Session; import javax.websocket.Session;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -67,7 +76,7 @@ public class DeviceAuthorizer implements Authorizer {
} }
} }
try { try {
deviceAccessAuthorizationAdminService = Feign.builder() deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient())
.requestInterceptor(new OAuthRequestInterceptor(globalProperties)) .requestInterceptor(new OAuthRequestInterceptor(globalProperties))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties) .target(DeviceAccessAuthorizationAdminService.class, getDeviceMgtServerUrl(globalProperties)
@ -130,4 +139,37 @@ public class DeviceAuthorizer implements Authorizer {
} }
return null; return null;
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -14,6 +14,7 @@
package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client; package org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.RequestInterceptor; import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
@ -31,6 +32,14 @@ import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.client.
import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils; import org.wso2.carbon.device.mgt.output.adapter.websocket.util.PropertyUtils;
import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException; import org.wso2.carbon.event.output.adapter.core.exception.OutputEventAdapterException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
/** /**
@ -77,7 +86,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
username = getUsername(globalProperties); username = getUsername(globalProperties);
password = getPassword(globalProperties); password = getPassword(globalProperties);
tokenEndpoint = getTokenEndpoint(globalProperties); tokenEndpoint = getTokenEndpoint(globalProperties);
apiApplicationRegistrationService = Feign.builder().requestInterceptor( apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(username, password)) new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class, .target(ApiApplicationRegistrationService.class,
@ -100,7 +109,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile); ApiApplicationKey apiApplicationKey = apiApplicationRegistrationService.register(apiRegistrationProfile);
String consumerKey = apiApplicationKey.getConsumerKey(); String consumerKey = apiApplicationKey.getConsumerKey();
String consumerSecret = apiApplicationKey.getConsumerSecret(); String consumerSecret = apiApplicationKey.getConsumerSecret();
tokenIssuerService = Feign.builder().requestInterceptor( tokenIssuerService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, tokenEndpoint); .target(TokenIssuerService.class, tokenEndpoint);
@ -159,4 +168,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
return refreshTimeOffset; return refreshTimeOffset;
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -123,7 +123,8 @@
javax.xml.namespace, javax.xml.namespace,
javax.xml.stream, javax.xml.stream,
org.wso2.carbon.base, org.wso2.carbon.base,
org.wso2.carbon.utils org.wso2.carbon.utils,
javax.net.ssl
</Import-Package> </Import-Package>
<Embed-Dependency> <Embed-Dependency>
jsr311-api, jsr311-api,

@ -18,6 +18,7 @@
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization; package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.FeignException; import feign.FeignException;
import feign.gson.GsonDecoder; import feign.gson.GsonDecoder;
@ -45,6 +46,14 @@ import javax.cache.Cache;
import javax.cache.CacheConfiguration; import javax.cache.CacheConfiguration;
import javax.cache.CacheManager; import javax.cache.CacheManager;
import javax.cache.Caching; import javax.cache.Caching;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -68,7 +77,7 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
public DeviceAccessBasedMQTTAuthorizer() { public DeviceAccessBasedMQTTAuthorizer() {
this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance(); this.MQTTAuthorizationConfiguration = AuthorizationConfigurationManager.getInstance();
deviceAccessAuthorizationAdminService = Feign.builder() deviceAccessAuthorizationAdminService = Feign.builder().client(getSSLClient())
.requestInterceptor(new OAuthRequestInterceptor()) .requestInterceptor(new OAuthRequestInterceptor())
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DeviceAccessAuthorizationAdminService.class, .target(DeviceAccessAuthorizationAdminService.class,
@ -224,4 +233,37 @@ public class DeviceAccessBasedMQTTAuthorizer implements IAuthorizer {
} }
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -14,6 +14,7 @@
package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client; package org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client;
import feign.Client;
import feign.Feign; import feign.Feign;
import feign.RequestInterceptor; import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
@ -30,6 +31,15 @@ import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.TokenIssuerService; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.client.dto.TokenIssuerService;
import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager; import org.wso2.carbon.andes.extensions.device.mgt.mqtt.authorization.config.AuthorizationConfigurationManager;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
/** /**
* This is a request interceptor to add oauth token header. * This is a request interceptor to add oauth token header.
*/ */
@ -53,7 +63,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset() * 1000; refreshTimeOffset = AuthorizationConfigurationManager.getInstance().getTokenRefreshTimeOffset() * 1000;
String username = AuthorizationConfigurationManager.getInstance().getUsername(); String username = AuthorizationConfigurationManager.getInstance().getUsername();
String password = AuthorizationConfigurationManager.getInstance().getPassword(); String password = AuthorizationConfigurationManager.getInstance().getPassword();
apiApplicationRegistrationService = Feign.builder().requestInterceptor( apiApplicationRegistrationService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(username, password)) new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(ApiApplicationRegistrationService.class, .target(ApiApplicationRegistrationService.class,
@ -75,7 +85,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String consumerSecret = apiApplicationKey.getConsumerSecret(); String consumerSecret = apiApplicationKey.getConsumerSecret();
String username = AuthorizationConfigurationManager.getInstance().getUsername(); String username = AuthorizationConfigurationManager.getInstance().getUsername();
String password = AuthorizationConfigurationManager.getInstance().getPassword(); String password = AuthorizationConfigurationManager.getInstance().getPassword();
tokenIssuerService = Feign.builder().requestInterceptor( tokenIssuerService = Feign.builder().client(getSSLClient()).requestInterceptor(
new BasicAuthRequestInterceptor(consumerKey, consumerSecret)) new BasicAuthRequestInterceptor(consumerKey, consumerSecret))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(TokenIssuerService.class, .target(TokenIssuerService.class,
@ -93,4 +103,37 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
template.header("Authorization", headerValue); template.header("Authorization", headerValue);
} }
private static Client getSSLClient() {
return new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
} }

@ -367,6 +367,7 @@
data-locations="{{device.locationHistory}}"> data-locations="{{device.locationHistory}}">
</div> </div>
<br/> <br/>
{{#unless isCloud}}
<a class="padding-left" target="_blank" <a class="padding-left" target="_blank"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}"> href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack"> <span class="fw-stack">
@ -374,6 +375,7 @@
<i class="fw fw-map-location fw-stack-1x"></i> <i class="fw fw-map-location fw-stack-1x"></i>
</span> Add Geo Fencing </span> Add Geo Fencing
</a> </a>
{{/unless}}
{{else}} {{else}}
<div id="map-error" class="message message-warning"> <div id="map-error" class="message message-warning">
<h4 class="remove-margin"> <h4 class="remove-margin">

@ -216,6 +216,7 @@ function onRequest(context) {
deviceViewData["permissions"] = permissions; deviceViewData["permissions"] = permissions;
deviceViewData["portalUrl"] = devicemgtProps['portalURL']; deviceViewData["portalUrl"] = devicemgtProps['portalURL'];
deviceViewData["isCloud"] = devicemgtProps['isCloud'];
deviceViewData["anchor"] = encodeURI(JSON.stringify({ "device" : { "id" : deviceId, "type" : deviceType}})); deviceViewData["anchor"] = encodeURI(JSON.stringify({ "device" : { "id" : deviceId, "type" : deviceType}}));
return deviceViewData; return deviceViewData;
} }

@ -26,12 +26,14 @@ var InitiateViewOption = null;
var payload = [deviceIdentifier]; var payload = [deviceIdentifier];
var operationTable; var operationTable;
var serviceUrl; var serviceUrl;
var serviceUrlLocal = "/api/device-mgt/android/v1.0/admin/devices/location";
if (deviceType == "ios") { if (deviceType == "ios") {
serviceUrl = "/ios/operation/deviceinfo"; serviceUrl = "/ios/operation/deviceinfo";
} else if (deviceType == "android") { } else if (deviceType == "android") {
//var serviceUrl = "/mdm-android-agent/operation/device-info"; //var serviceUrl = "/mdm-android-agent/operation/device-info";
serviceUrl = "/api/device-mgt/android/v1.0/admin/devices/info"; serviceUrl = "/api/device-mgt/android/v1.0/admin/devices/info";
serviceUrlLocal = "/api/device-mgt/android/v1.0/admin/devices/location";
} }
if (serviceUrl) { if (serviceUrl) {
@ -49,6 +51,23 @@ var InitiateViewOption = null;
$(".panel-body").append(defaultInnerHTML); $(".panel-body").append(defaultInnerHTML);
} }
); );
invokerUtil.post(
serviceUrlLocal,
payload,
// success-callback
function () {
$(".panel-body").show();
},
// error-callback
function () {
var defaultInnerHTML =
"<br><p class='fw-warning'>Device data may not have been updated. Please refresh to try again.<p>";
$(".panel-body").append(defaultInnerHTML);
}
);
} }

@ -28,7 +28,7 @@ function loadLeafletMap() {
zoomLevel = 13, zoomLevel = 13,
tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution = "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap</a> contributors"; attribution = "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap</a> contributors";
if (locations) { if (locations && locations.locations.length > 0) {
var locationSets = locations.locations; var locationSets = locations.locations;
map = L.map(container).setView([locationSets[0].lat, locationSets[0].lng], zoomLevel); map = L.map(container).setView([locationSets[0].lat, locationSets[0].lng], zoomLevel);

@ -349,6 +349,9 @@ $.fn.collapse_nav_sub = function () {
$(document).ready(function () { $(document).ready(function () {
$.sidebar_toggle(); $.sidebar_toggle();
generateQRCode(".enrollment-qr-container");
if (typeof $.fn.collapse == 'function') { if (typeof $.fn.collapse == 'function') {
$('.navbar-collapse.tiles').on('shown.bs.collapse', function () { $('.navbar-collapse.tiles').on('shown.bs.collapse', function () {
$(this).collapse_nav_sub(); $(this).collapse_nav_sub();

@ -2,31 +2,98 @@
{{unit "cdmf.unit.device.type.qr-modal" enrollmentURL=enrollmentURL deviceTypeName="Android"}} {{unit "cdmf.unit.device.type.qr-modal" enrollmentURL=enrollmentURL deviceTypeName="Android"}}
{{unit "cdmf.unit.device.type.email.invite-modal" deviceTypeView="android"}} {{unit "cdmf.unit.device.type.email.invite-modal" deviceTypeView="android"}}
<div class="col-lg-12 margin-top-double"> <div class="row">
<h1 class="grey ">Android Mobile</h1> <div class="col-lg-12">
<h1 class="grey ">DOWNLOAD THE ANDROID AGENT</h1>
<hr> <hr>
</div> </div>
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 padding-top">
<img src="{{@unit.publicUri}}/images/android-icon.png" class="img-responsive">
</div> </div>
<div class="col-xs-12 col-sm-8 col-md-9 col-lg-9 padding-top"> <div class="row">
<!--<div class="col-xs-12 col-sm-4 col-md-3 col-lg-3 add-padding-top-2x">
<img src="{{@unit.publicUri}}/images/android-icon.png" class="img-responsive">
</div>-->
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 add-padding-top-2x">
<h3 class="text-center">Scan to download the Android Agent.</h3>
<div class="enrollment-qr-container text-center"></div>
<h3 class="text-center add-margin-bottom-2x add-margin-top-2x">or</h3>
<div class="text-center"><a
href="{{host}}/android-web-agent/public/mdm.page.enrollments.android.download-agent/asset/android-agent.apk"
class="btn-operations remove-margin download_agent">
<i class="fw fw-download fw-inverse fw-lg add-margin-1x"></i> Download APK</a></div>
<h3 class="uppercase">What it Does</h3> <!--<p class="doc-link">Please scan the QR code to download the APK on to your android device or click
<a href="{{host}}/android-web-agent/public/mdm.page.enrollments.android.download-agent/asset/android-agent.apk">here</a>
to save it to your computer.</p>
<p class="doc-link">For further instructions and troubleshooting please visit the following <a href="https://docs.wso2.com/display/IoTS300/Android"
target="_blank">link</a>.</p>-->
<p class="doc-link text-center">Need help? Read <a
href="https://docs.wso2.com/display/DeviceCloud/Enrolling+an+Android+Device" target="_blank">WSO2 Device
Cloud documentation.</a></p>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-12 add-padding-top-2x ">
<h3 class="uppercase">START ENROLLING YOUR DEVICE</h3>
<hr> <hr>
<p class="grey margin-top">Connect and manage your Android device with WSO2 IoT Server.</p> </div>
<br> </div>
<a href="javascript:toggleEnrollment()" class="download-link btn-operations"><i class="fw fw-mobile fw-inverse fw-lg add-margin-1x"></i> Enroll Device</a> <div class="row grey-bg">
<a href="{{host}}/android-web-agent/public/mdm.page.enrollments.android.download-agent/asset/android-agent.apk" class="btn-operations"><i class="fw fw-download fw-inverse fw-lg add-margin-1x"></i> Download APK</a> {{#if isCloud}}
<a href="javascript:toggleEmailInvite()" class="btn-operations"><i class="fw fw-mail fw-inverse fw-lg add-margin-1x"></i> Invite by Email</a> <div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 add-padding-top-2x add-padding-bottom-2x">
{{#if displayStatus}} {{else}}
<a href="javascript:artifactUpload()" class="btn-operations"><i class="fw fw-upload fw-inverse fw-lg add-margin-1x"></i> Deploy Analytics Artifacts</a> <div class="col-xs-12 col-sm-6 col-md-3 col-lg-3 add-padding-top-2x add-padding-bottom-2x">
{{/if}}
<h5><strong>Step 1</strong></h5>
<p>Let's start by installing the Android agent on your device. Open the downloaded file, and tap <b>INSTALL</b>.</p>
<img src="{{@unit.publicUri}}/images/install_agent.png" class="img-responsive">
</div>
{{#if isCloud}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 add-padding-top-2x add-padding-bottom-2x">
<h5><strong>Step 2</strong></h5>
<p>Enter your:
<p>
<ul>
<li>Username: username/email that you used to sign in.</li>
<li>Password: the WSO2 Cloud password.</li>
<li>Organization: the name of the organization.</li>
</ul>
<img src="{{@unit.publicUri}}/images/login.png" class="img-responsive">
</div>
{{else}}
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-3 add-padding-top-2x add-padding-bottom-2x">
<h5><strong>Step 2</strong></h5>
<p>Tap Skip to proceed with the default enrollment process.</p>
<img src="{{@unit.publicUri}}/images/set_profile.png" class="img-responsive">
</div>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-3 add-padding-top-2x add-padding-bottom-2x">
<h5><strong>Step 3</strong></h5>
<p>Enter the server address based on your environment, in the text box provided.</p>
<img src="{{@unit.publicUri}}/images/registration.png" class="img-responsive">
</div>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-3 add-padding-top-2x add-padding-bottom-2x">
<h5><strong>Step 4</strong></h5>
<p>Enter your:
<p>
<ul>
<li>Username: username/email that you used to sign in to IoT server.</li>
<li>Password: the WSO2 Iot server password.</li>
<li>Domain: the name of the domain.</li>
</ul>
<img src="{{@unit.publicUri}}/images/install_agent.png" class="img-responsive">
</div>
{{/if}} {{/if}}
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Android" </div>
target="_blank">here</a> for latest instructions and troubleshooting.</p>
<!--<div class="row">
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-12 padding-double ">
<h3 class="uppercase">What You Need</h3> <h3 class="uppercase">What You Need</h3>
<hr> <hr>
<ul class="list-unstyled"> <ul class="list-unstyled">
@ -41,31 +108,27 @@
</li> </li>
</ul> </ul>
<br> <br>
</div>
</div> </div>
<div id="android-statistic-response-template" style="display: none">
<div class="content">
<div class="row"> <div class="row">
<div class="col-lg-5 col-md-6 col-centered"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-9">
<h3>
<span class="fw-stack"> <h3 class="uppercase">What it Does</h3>
<i class="fw fw-circle-outline fw-stack-2x"></i> <hr>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i> <p class="grey margin-top">Connect and manage your Android device with WSO2 IoT Server.</p>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br> <br>
</h4>
<span id="description"></span> <a href="javascript:toggleEnrollment()" class="download-link btn-operations"><i class="fw fw-mobile fw-inverse fw-lg add-margin-1x"></i> Enroll Device</a>
</div> <a href="{{host}}/android-web-agent/public/mdm.page.enrollments.android.download-agent/asset/android-agent.apk" class="btn-operations"><i class="fw fw-download fw-inverse fw-lg add-margin-1x"></i> Download APK</a>
</div> <a href="javascript:toggleEmailInvite()" class="btn-operations"><i class="fw fw-mail fw-inverse fw-lg add-margin-1x"></i> Invite by Email</a>
<p class="doc-link">Click <a href="https://docs.wso2.com/display/IoTS300/Android" target="_blank">here</a> for further instructions and troubleshooting.</p>
</div> </div>
</div> </div>
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-12 padding-double grey-bg"> <div class="col-xs-12 col-sm-12 col-md-8 col-lg-12 padding-double grey-bg">
<h3 class="uppercase">Prepare</h3><hr> <h3 class="uppercase">Prepare</h3><hr>
<ul class="list-unstyled"> <ul class="list-unstyled">
@ -75,16 +138,16 @@
</ul> </ul>
<br> <br>
</div> </div>-->
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 padding-double"> <!--<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6 padding-double">
<p class="grey margin-top">Click on the image to zoom</p> <p class="grey margin-top">Click on the image to zoom</p>
<center> <center>
<a href="{{@unit.publicUri}}/images/android_device.png" target="_blank"> <a href="{{@unit.publicUri}}/images/android_device.png" target="_blank">
<img src="{{@unit.publicUri}}/images/android_device.png" class="img-responsive"> <img src="{{@unit.publicUri}}/images/android_device.png" class="img-responsive">
</a> </a>
</center> </center>
</div> </div>-->
<br/> <br/>

@ -34,6 +34,7 @@ function onRequest(context){
// //do nothing. // //do nothing.
// } // }
//); //);
viewModel["isCloud"] = devicemgtProps["isCloud"];
viewModel["hostName"] = devicemgtProps["httpsURL"]; viewModel["hostName"] = devicemgtProps["httpsURL"];
viewModel["enrollmentURL"] = devicemgtProps["generalConfig"]["host"] + devicemgtProps["androidEnrollmentDir"]; viewModel["enrollmentURL"] = devicemgtProps["generalConfig"]["host"] + devicemgtProps["androidEnrollmentDir"];
return viewModel; return viewModel;

@ -1,7 +1,7 @@
<div id="errorOperations" class="operation"> <div id="errorOperations" class="operation">
<div class="modal-header"> <div class="modal-header">
<h3 class="pull-left modal-title"> <h3 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack add-margin-right-2x">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i> <i class="fw fw-error fw-stack-1x"></i>
</span> </span>
@ -23,7 +23,7 @@
<div id="errorOperationUnexpected" class="operation"> <div id="errorOperationUnexpected" class="operation">
<div class="modal-header"> <div class="modal-header">
<h3 class="pull-left modal-title"> <h3 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack add-margin-right-2x">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-error fw-stack-1x"></i> <i class="fw fw-error fw-stack-1x"></i>
</span> </span>
@ -45,7 +45,7 @@
<div id="operationSuccess" class="operation"> <div id="operationSuccess" class="operation">
<div class="modal-header"> <div class="modal-header">
<h3 class="pull-left modal-title"> <h3 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack add-margin-right-2x">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-check fw-stack-1x"></i> <i class="fw fw-check fw-stack-1x"></i>
</span> </span>
@ -68,7 +68,7 @@
<div id="messageSuccess" class="operation"> <div id="messageSuccess" class="operation">
<div class="modal-header"> <div class="modal-header">
<h3 class="pull-left modal-title"> <h3 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack add-margin-right-2x">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-check fw-stack-1x"></i> <i class="fw fw-check fw-stack-1x"></i>
</span> </span>
@ -95,7 +95,7 @@
<div class="modal-content clearfix"> <div class="modal-content clearfix">
<div class="modal-header"> <div class="modal-header">
<h3 class="pull-left modal-title"> <h3 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack add-margin-right-2x">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw {{icon}} fw-stack-1x"></i> <i class="fw {{icon}} fw-stack-1x"></i>
</span> </span>

Loading…
Cancel
Save