diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js index 50c9ae7e7f..12074a611e 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js @@ -123,6 +123,12 @@ class App extends React.Component { ) .then(res => { config.deviceTypes = JSON.parse(res.data.data); + config.supportedOStypes = []; + config.deviceTypes.forEach(type => { + if (['ios', 'android'].includes(type.name)) { + config.supportedOStypes.push(type); + } + }); this.setState({ config: config, loading: false, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js index 94b2c91c00..07b2222a9c 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -31,6 +31,7 @@ import DeviceStatusReport from './scenes/Home/scenes/Reports/scenes/DeviceStatus import AppNotInstalledDevicesReport from './scenes/Home/scenes/Reports/scenes/AppNotInstalledDevices'; import Geo from './scenes/Home/scenes/Geo'; import EncryptionStatus from './scenes/Home/scenes/Reports/scenes/EncryptionStatus'; +import OutdatedOSversionReport from './scenes/Home/scenes/Reports/scenes/OutdatedOSVersion'; const routes = [ { @@ -113,6 +114,11 @@ const routes = [ component: EnrollmentsVsUnenrollmentsReport, exact: true, }, + { + path: '/entgra/reports/expired-devices', + component: OutdatedOSversionReport, + exact: true, + }, { path: '/entgra/reports/enrollment-type', component: EnrollmentTypeReport, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/components/DevicesTable/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/components/DevicesTable/index.js index ecd3956fa7..8be97a11b1 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/components/DevicesTable/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/components/DevicesTable/index.js @@ -116,6 +116,12 @@ const columns = [ }, // todo add filtering options }, + { + title: 'OS Version', + dataIndex: 'deviceInfo', + key: 'osVersion', + render: deviceInfo => deviceInfo.osVersion, + }, ]; const getTimeAgo = time => { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/index.js index d2d80bc52e..2963289c4f 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Reports/index.js @@ -157,6 +157,35 @@ class Reports extends React.Component { +
Report based on device OS version
+Value is generated by isolating each position of OS version then adding Zeros up until + * Minor version and Revision have a constant number of digits. + * Eg: 5.1.1 will be 50000100001, 9 will be 90000000000 + *
+ * + *Above conversion is done in order to fail proof in situations where 6.0.0 can be + * smaller than 5.12.1. + * Eg: 5.12.1 will be 5121 and 6.0.0 will be 600 and 5121 > 600(this statement is incorrect) + *
+ * + * @param osVersion os version(eg: 5.1.1) + * @return {@link Long} generated value + */ + public static Long generateOSVersionValue(String osVersion) { + Matcher osMatcher = Pattern.compile("[0-9]+([.][0-9]+)*").matcher(osVersion); + if (!osMatcher.find()) { + if (log.isDebugEnabled()) { + log.debug("Unable to read OS version. OS version: " + osVersion + "is invalid. " + + "Please follow the following convention [0-9]+([.][0-9]+)*"); + } + return null; + } + osVersion = osMatcher.group(); + + String[] osVersions = osVersion.split("[.]"); + int osVersionsLength = osVersions.length; + + /* + *+ Eg: {@code osVersion == "5.1.1"} will generate an array of {@code ["5","1","1"]} + Following loop for the above result can be broken down as below + * Iteration 1 : {@code Math.pow} result = 5 00000 00000, {@code sum} = 5 00000 00000 + * Iteration 2 : {@code Math.pow} result = 1 00000, {@code sum} = 5 00001 00000 + * Iteration 3 : {@code Math.pow} result = 1, {@code sum} = 5 00001 00001 + To generate the above results I have multiplied the array values with powers of 10. + The constraints used to generate the power of 10 is explained below, + *
+ * + *+ {@code Constants.NUM_OF_OS_VERSION_POSITIONS - (i + 1)} was done in-order to identify + which position of the OS version is been used for generation process, so correct number + of Zeros can be generated. + *
+ * + *+ {@code Constants.NUM_OF_OS_VERSION_DIGITS} this multiplication will make sure that the + values generated will reduce in following order main OS version, minor OS version, Revision. + *
+ */ + return IntStream + .range(0, osVersionsLength) + .mapToLong(i -> (long) (Math.pow(10, (Constants.NUM_OF_OS_VERSION_POSITIONS - (i + 1)) + * Constants.NUM_OF_OS_VERSION_DIGITS) + * Integer.parseInt(osVersions[i]))).sum(); + } + + /** + * Revert a generated value back to a OS version + * + * @param osVersionValue value that should be reverted + * @return {@link String} OS version + */ + /* Following method is unused but was still included in case a requirement occurs to revert the + * generated values in DM_DEVICE_INFO back to a OS versions */ + public static String reverseOSVersionValue(Long osVersionValue) { + StringJoiner joiner = new StringJoiner("."); + + /* + *+ Eg: {@code osVersionValue == "5 00001 00001"} + Following loop will divide to break down the above number to regenerate the os version + * Iteration 1 : {@code osVersion} = 5 , {@code osVersionValue} = 00001 00001 + * Iteration 2 : {@code osVersion} = 1 , {@code osVersionValue} = 00001 + * Iteration 3 : {@code osVersion} = 1 , {@code osVersionValue} = 0 + Final array = {@code ["5","1","1"]} + To generate the above results I have divided the generated value with powers of 10. + The constraints used to generate the power of 10 is explained below, + *
+ * + *+ {@code 10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS} this will break the generated value + creating each OS version position in following order main OS version, minor OS version, + Revision. + *
+ * + */ + for (int i = Constants.NUM_OF_OS_VERSION_POSITIONS; i > 0; i--) { + long osVersion = Double.valueOf( + osVersionValue / Math.pow(10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS)) + .longValue(); + osVersionValue = Double.valueOf( + osVersionValue % Math.pow(10, (i - 1) * Constants.NUM_OF_OS_VERSION_DIGITS)) + .longValue(); + joiner.add(String.valueOf(osVersion)); + } + return joiner.toString(); + } } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java index a17e3dcb70..f35c0700ee 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java @@ -27,6 +27,7 @@ import org.apache.http.Consts; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -53,7 +54,7 @@ public class HandlerUtil { * @throws IOException IO exception returns if error occurs when executing the httpMethod */ public static ProxyResponse execute(HttpRequestBase httpRequest) throws IOException { - try (CloseableHttpClient client = HttpClients.createDefault()) { + try (CloseableHttpClient client = getHttpClient()) { HttpResponse response = client.execute(httpRequest); ProxyResponse proxyResponse = new ProxyResponse(); @@ -217,4 +218,18 @@ public class HandlerUtil { return gatewayPort; } + /** + * Retrieve Http client based on hostname verification. + * @return {@link CloseableHttpClient} http client + */ + public static CloseableHttpClient getHttpClient() { + boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System. + getProperty("org.wso2.ignoreHostnameVerification")); + if (isIgnoreHostnameVerification) { + return HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build(); + } else { + return HttpClients.createDefault(); + } + } + } diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml index a8f2325821..e8375b32ad 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml @@ -258,6 +258,8 @@