Merge branch 'release-3.0.x' of https://github.com/wso2/carbon-device-mgt-plugins into release-3.0.x

This commit is contained in:
ayyoob 2017-01-24 19:46:39 +05:30
commit 4f1f1a3e7e
169 changed files with 1711 additions and 1147 deletions

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -129,7 +129,11 @@ var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush;
var filter = {
"query": luceneQuery,
"start": 0,
"count": limit
"count": limit,
"sortBy" : [{
"field" : "timeStamp",
"sortType" : "ASC"
}]
};
result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage();
} else {

View File

@ -432,7 +432,7 @@
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<h4 id = "title" class="modal-title">
WSO2 Geo Dashboard
</h4>
</div>

View File

@ -29,8 +29,6 @@ $('body').on('hidden.bs.modal', '.modal', function () {
/*Map layer configurations*/
var map;
initialLoad();
function initialLoad() {
if (document.getElementById('map') == null) {
setTimeout(initialLoad, 500); // give everything some time to render
@ -41,10 +39,25 @@ function initialLoad() {
processAfterInitializationMap();
//Access gps and make zoom to server location as map center
//navigator.geolocation.getCurrentPosition(success, error);
setPageTitle();
$("#loading").hide();
}
}
function setPageTitle() {
var hash = window.parent.location.hash;
if(hash) {
var startIdx = hash.indexOf("/") + 1;
var lastIdx = hash.length;
var deviceInfoString = hash.substring(startIdx,lastIdx);
var deviceInfo = JSON.parse(deviceInfoString);
if(deviceInfo) {
var newTitle = "[ " + deviceInfo.device.id + "]" + " - Geo Dashboard [" + deviceInfo.device.type + "]";
window.parent.document.title = newTitle;
$("#title").val(newTitle)
}
}
}
//function success(position) {
// var browserLatitude = position.coords.latitude;
@ -84,12 +97,12 @@ function initializeMap() {
zoom: 14,
center: [6.927078, 79.861243],
layers: [defaultOSM, defaultTFL],
zoomControl: false,
zoomControl: true,
attributionControl: false,
maxZoom: 20,
maxNativeZoom: 18
});
map.zoomControl.setPosition('bottomleft');
map.on('click', function (e) {
$.UIkit.offcanvas.hide();//[force = false] no animation
});
@ -340,6 +353,66 @@ function enableRealTime() {
isBatchModeOn = false;
}
function InitSpatialObject() {
var fromDate = new Date();
fromDate.setHours(fromDate.getHours() - 2);
var toDate = new Date();
console.log(fromDate + " " + toDate);
var tableData = getProviderData(fromDate.valueOf(), toDate.valueOf());
for (var i = 0; i < tableData.length; i++) {
var data = tableData[i];
var geoMessage = {
"messageType": "Point",
"type": "Feature",
"id": data.id,
"deviceId": data.id,
"deviceType": data.type,
"properties": {
"speed": data.speed,
"heading": data.heading,
"state": data.state,
"information": data.information,
"notify": data.notify,
"type": data.type
},
"geometry": {
"type": "Point",
"coordinates": [data.longitude, data.latitude]
}
};
processPointMessage(geoMessage);
}
var spatialObject = currentSpatialObjects[deviceId];// (local)
if (!spatialObject) {
$.UIkit.notify({
message: "Spatial Object <span style='color:red'>" + deviceId + "</span> not in the Map!!",
status: 'warning',
timeout: ApplicationOptions.constance.NOTIFY_WARNING_TIMEOUT,
pos: 'top-center'
});
return false;
}
selectedSpatialObject = deviceId;
if (spatialObject.type == "area") {
spatialObject.focusOn(map);
return true;
}
map.setView(spatialObject.marker.getLatLng(), 15, {animate: true}); // TODO: check the map._layersMaxZoom and set the zoom level accordingly
$('#objectInfo').find('#objectInfoId').html(selectedSpatialObject);
spatialObject.marker.openPopup();
if (!toggled) {
$('#objectInfo').animate({width: 'toggle'}, 100);
toggled = true;
}
spatialObject.drawPath();
setTimeout(function () {
createChart();
chart.load({columns: [spatialObject.speedHistory.getArray()]});
}, 100);
}
function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) {
if (!timeFrom) {
notifyError('No start time provided to show history. Please provide a suitable value' + timeFrom);

View File

@ -602,6 +602,8 @@ var webSocketOnAlertError = function (e) {
var webSocketOnOpen = function () {
websocket.set_opened();
initialLoad();
InitSpatialObject();
$.UIkit.notify({
message: 'You Are Connected to Spatial Stream !!',
status: 'success',

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<eventReceiver name="Geo-Receiver-WSO2Event-LocationStream"
trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
<from eventAdapterType="wso2event">
<property name="events.duplicated.in.cluster">false</property>
</from>
<mapping customMapping="disable" type="wso2event"/>
<to streamName="org.wso2.geo.LocationStream" version="1.0.0"/>
</eventReceiver>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?><!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<artifact name="Geo-Dashboard-WSO2Event-Receiver" version="1.0.0" type="event/receiver" serverRole="GeoDashboard">
<file>Geo-Receiver-WSO2Event-LocationStream.xml</file>
</artifact>

View File

@ -27,6 +27,7 @@
<dependency artifact="ThemeGeoDashboard" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<!-- CEP Artifacts -->
<dependency artifact="Geo-Dashboard-Http-Receiver" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-Dashboard-WSO2Event-Receiver" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-EventSink-FusedStream" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-ExecutionPlan-EventsFusionGenerateNotifications" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-ExecutionPlan-InputStandardizer" version="1.0.0" include="true" serverRole="GeoDashboard"/>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -101,6 +101,7 @@ public class SenseDataReceiverManager {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
intentFilter.setPriority(1000);
context.registerReceiver(callDataReceiver, intentFilter);
}
@ -149,6 +150,7 @@ public class SenseDataReceiverManager {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
intentFilter.addAction(Telephony.Sms.Intents.SMS_DELIVER_ACTION);
intentFilter.setPriority(1000);
context.registerReceiver(smsDataReceiver, intentFilter);
}
}

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -56,13 +56,6 @@
"ishidden": false,
"subordinates": [],
"title": "Communication"
},
{
"id": "test",
"isanon": false,
"ishidden": false,
"title": "Test",
"subordinates": []
}
],
"pages": [
@ -1299,151 +1292,6 @@
"fluidLayout": false
},
"title": "Communication"
},
{
"id": "test",
"title": "Test",
"layout": {
"content": {
"loggedIn": {
"blocks": [
{
"id": "49cada6f023f237c953761b597752212",
"x": 0,
"y": 1,
"width": 5,
"height": 1,
"banner": false
},
{
"id": "a26d2f62dbb0011edf13371a2eb3cdd1",
"x": 0,
"y": 0,
"width": 3,
"height": 1,
"banner": false
}
]
}
},
"fluidLayout": false
},
"isanon": false,
"content": {
"default": {
"49cada6f023f237c953761b597752212": [
{
"id": "date-picker-widget-0",
"content": {
"id": "date-picker-widget",
"title": "Date Picker Widget",
"type": "widget",
"category": "Widgets",
"thumbnail": "fs://gadget/date-picker-widget/index.png",
"data": {
"url": "fs://gadget/date-picker-widget/index.xml"
},
"options": {},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Date Picker Widget"
},
"notify": {
"date-selected": {
"type": "message",
"description": "This notifies selected date"
}
},
"locale_titles": {
"en-US": "Date Picker Widget"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
],
"33faa57accead8af549c70f111face99": [
{
"id": "EsbAnalytics-Gadget-Search_Box-0",
"content": {
"id": "EsbAnalytics-Gadget-Search_Box",
"title": "Search Box",
"type": "widget",
"category": "Widgets",
"thumbnail": "fs://gadget/usa-business-revenue/index.png",
"data": {
"url": "fs://gadget/EsbAnalytics-Gadget-Search_Box/index.xml"
},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Search Box"
},
"toolbarButtons": {
"default": {
"maximize": false,
"configurations": false
},
"custom": [],
"isDropdownView": false
},
"options": {},
"locale_titles": {
"en-US": "Search Box"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
],
"be290fcc084ff118decc23588febc2ed": [],
"a26d2f62dbb0011edf13371a2eb3cdd1": [
{
"id": "Android_Device_SearchBox-0",
"content": {
"id": "Android_Device_SearchBox",
"title": "Search Box",
"type": "gadget",
"category": "Gadgets",
"thumbnail": "fs://gadget/usa-business-revenue/index.png",
"data": {
"url": "fs://gadget/Android_Device_SearchBox/index.xml"
},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Search Box"
},
"toolbarButtons": {
"default": {
"maximize": false,
"configurations": false
},
"custom": [],
"isDropdownView": false
},
"options": {},
"locale_titles": {
"en-US": "Search Box"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
]
},
"anon": {}
}
}
],
"permissions": {

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -69,6 +69,8 @@ import javax.ws.rs.core.Response;
)
}
)
@Api(value = "Android Sense Device Management",
description = "This carries all the resources related to the Android sense device management functionalities.")
public interface AndroidSenseService {
/**

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed 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
*
@ -44,4 +44,9 @@ public class AndroidSenseConstants {
public static final String SCOPE = "scope";
public static final String PERM_ENROLL_ANDROID_SENSE = "/permission/admin/device-mgt/devices/enroll/android-sense";
public static final String PERM_OWNING_DEVICE_VIEW = "/permission/admin/device-mgt/devices/owning-device/view";
public static final String ROLE_NAME = "internal/devicemgt-user";
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.device.mgt.iot.androidsense.service.impl.listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.constants.AndroidSenseConstants;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AndroidSensePermissionUpdateListener implements ServletContextListener {
private static Log log = LogFactory.getLog(AndroidSensePermissionUpdateListener.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
UserStoreManager userStoreManager = getUserStoreManager();
try {
if (userStoreManager != null) {
if (!userStoreManager.isExistingRole(AndroidSenseConstants.ROLE_NAME)) {
userStoreManager.addRole(AndroidSenseConstants.ROLE_NAME, null, getPermissions());
} else {
getAuthorizationManager().authorizeRole(AndroidSenseConstants.ROLE_NAME,
AndroidSenseConstants.PERM_ENROLL_ANDROID_SENSE, CarbonConstants.UI_PERMISSION_ACTION);
getAuthorizationManager().authorizeRole(AndroidSenseConstants.ROLE_NAME,
AndroidSenseConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants.UI_PERMISSION_ACTION);
}
} } catch (UserStoreException e) {
log.error("Error while creating a role and adding a user for Android Sense.", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
public static UserStoreManager getUserStoreManager() {
RealmService realmService;
UserStoreManager userStoreManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return userStoreManager;
}
public static AuthorizationManager getAuthorizationManager() {
RealmService realmService;
AuthorizationManager authorizationManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return authorizationManager;
}
private Permission[] getPermissions() {
Permission androidSense = new Permission(AndroidSenseConstants.PERM_ENROLL_ANDROID_SENSE,
CarbonConstants.UI_PERMISSION_ACTION);
Permission view = new Permission(AndroidSenseConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants
.UI_PERMISSION_ACTION);
return new Permission[]{androidSense, view};
}
}

View File

@ -30,4 +30,8 @@
<param-name>managed-api-enabled</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.wso2.carbon.device.mgt.iot.androidsense.service.impl.listener.AndroidSensePermissionUpdateListener</listener-class>
</listener>
</web-app>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -15,6 +15,7 @@
specific language governing permissions and limitations
under the License.
}}
{{unit "cdmf.unit.device.type.android_sense.leaflet"}}
{{#zone "topCss"}}
<style>
.thumbnail.icon:before {
@ -27,24 +28,18 @@
{{/zone}}
{{#zone "device-opetations"}}
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">
Operations
</div>
<div class="add-margin-top-4x">
{{unit "cdmf.unit.device.operation-bar" device=device autoCompleteParams=autoCompleteParams
encodedFeaturePayloads=encodedFeaturePayloads}}
</div>
{{/zone}}
{{#zone "device-view-tabs"}}
<li class="active"><a class="list-group-item" href="#device_statistics" role="tab"
data-toggle="tab" aria-controls="device_statistics">Device
Statistics</a>
Statistics</a>
</li>
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li>
<li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Map</a></li>
<li><a class="list-group-item location_tab" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Device Location</a></li>
{{/zone}}
{{#zone "device-view-tab-contents"}}
@ -77,18 +72,34 @@
</div>
<div class="panel panel-default tab-pane"
id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard">
<div class="panel-heading">Map</div>
<div class="panel-heading">Device Location</div>
{{#if locationHistory}}
<div id="device-location"
data-locations = "{{locationHistory}}">
</div>
<br/>
<a class="padding-left" target="_blank"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-map-location fw-stack-1x"></i>
</span> Add Geo Fencing
</a>
{{else}}
<div id="map-error" class="message message-warning">
<h4 class="remove-margin">
<i class="icon fw fw-warning"></i>
Device location information is not available.
</h4>
</div>
<p class="add-padding-5x"></p>
<p class="add-padding-5x"></p>
<p class="add-padding-5x"></p>
{{/if}}
<div id="chartWrapper">
</div>
<a class="padding-left"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Location
</a>
</div>
{{/zone}}
{{#zone "bottomJs"}}
{{js "js/load-map.js"}}
{{/zone}}

View File

@ -30,16 +30,17 @@ function onRequest(context) {
var device = deviceModule.viewDevice(deviceType, deviceId);
if (device && device.status != "error") {
var anchor = { "device" : { "id" : device.content.deviceIdentifier, "type" : device.content.type}};
return {
"device": device.content,
"autoCompleteParams": autoCompleteParams,
"encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor)
};
var viewObject = {};
viewObject.device = device.content;
viewObject.autoCompleteParams = autoCompleteParams;
viewObject.encodedFeaturePayloads = "";
viewObject.portalUrl = devicemgtProps['portalURL'];
viewObject.anchor = encodeURI(JSON.stringify(anchor));
viewObject.locationHistory = stringify(device.content.locationHistory);
return viewObject;
} else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");
exit();
}
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.
*/
var map;
function loadLeafletMap() {
var deviceLocationID = "#device-location",
locations = $(deviceLocationID).data("locations"),
container = "device-location",
zoomLevel = 13,
tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution = "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap</a> contributors";
if (locations) {
var locationSets = locations.locations;
map = L.map(container).setView([locationSets[0].lat, locationSets[0].lng], zoomLevel);
L.tileLayer(tileSet, {attribution: attribution}).addTo(map);
var initTime = locations.times[0].time, lastTime = locations.times[locationSets.length - 1].time;
var totalTime = lastTime - initTime;
for (var i = 0; i < locationSets.length; i++) {
var opacVal = (locations.times[i].time - initTime) / totalTime;
var m = L.marker(locationSets[i], {"opacity": opacVal}).addTo(map).bindPopup(new Date(locations.times[i].time).toISOString());
m.on('mouseover', function (e) {
this.openPopup();
});
m.on('mouseout', function (e) {
this.closePopup();
});
}
$("#map-error").hide();
$("#device-location").show();
} else {
$("#device-location").hide();
$("#map-error").show();
}
}
$(document).ready(function () {
$(".location_tab").on("click", function () {
loadLeafletMap();
});
});

View File

@ -0,0 +1,6 @@
{{#zone "topLibCss"}}
<link rel="stylesheet" href="{{@unit.publicUri}}/css/leaflet.css">
{{/zone}}
{{#zone "bottomJs"}}
<script src="{{@unit.publicUri}}/js/leaflet.js"></script>
{{/zone}}

View File

@ -0,0 +1,479 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-tile-container,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile,
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-container,
.leaflet-dragging .leaflet-clickable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a,
.leaflet-bar a:hover {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-control-zoom-out {
font-size: 20px;
}
.leaflet-touch .leaflet-control-zoom-in {
font-size: 22px;
}
.leaflet-touch .leaflet-control-zoom-out {
font-size: 24px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.7);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover {
text-decoration: underline;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 4px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}

View File

@ -67,6 +67,6 @@ function attachEvents() {
function toggleEnrollment(){
$(modalPopupContent).html($("#qr-code-modal").html());
generateQRCode(modalPopupContent + " .qr-code");
showPopup();
modalDialog.show();
}
}

View File

@ -282,16 +282,5 @@
{{#zone "bottomJs"}}
{{js "/js/download.js"}}
<script type="text/javascript">
$(".download-link").click(function () {
toggleEnrollment();
});
function toggleEnrollment() {
$(".modalpopup-content").html($("#qr-code-modal").html());
generateQRCode(".modalpopup-content .qr-code");
showPopup();
}
</script>
{{js "/js/jquery.validate.js"}}
{{/zone}}

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -230,7 +230,7 @@ public class ArduinoServiceImpl implements ArduinoService {
ArduinoConstants.APIM_APPLICATION_TOKEN_VALIDITY_PERIOD);
}
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = " device_" + deviceId;
String scopes = " device_" + deviceId + " perm:arduino:enroll";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
//create token

View File

@ -29,4 +29,9 @@ public class ArduinoConstants {
public static final String SCOPE = "scope";
public static final String PERM_ENROLL_ARDUINO = "/permission/admin/device-mgt/devices/enroll/arduino";
public static final String PERM_OWNING_DEVICE_VIEW = "/permission/admin/device-mgt/devices/owning-device/view";
public static final String ROLE_NAME = "internal/devicemgt-user";
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.device.mgt.iot.arduino.service.impl.listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.constants.ArduinoConstants;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ArduinoPermissionUpdateListener implements ServletContextListener {
private static Log log = LogFactory.getLog(ArduinoPermissionUpdateListener.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
UserStoreManager userStoreManager = getUserStoreManager();
try {
if (userStoreManager != null) {
if (!userStoreManager.isExistingRole(ArduinoConstants.ROLE_NAME)) {
userStoreManager.addRole(ArduinoConstants.ROLE_NAME, null, getPermissions());
} else {
getAuthorizationManager().authorizeRole(ArduinoConstants.ROLE_NAME,
ArduinoConstants.PERM_ENROLL_ARDUINO, CarbonConstants.UI_PERMISSION_ACTION);
getAuthorizationManager().authorizeRole(ArduinoConstants.ROLE_NAME,
ArduinoConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants.UI_PERMISSION_ACTION);
}
} } catch (UserStoreException e) {
log.error("Error while creating a role and adding a user for Arduino.", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
public static UserStoreManager getUserStoreManager() {
RealmService realmService;
UserStoreManager userStoreManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return userStoreManager;
}
public static AuthorizationManager getAuthorizationManager() {
RealmService realmService;
AuthorizationManager authorizationManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return authorizationManager;
}
private Permission[] getPermissions() {
Permission androidSense = new Permission(ArduinoConstants.PERM_ENROLL_ARDUINO,
CarbonConstants.UI_PERMISSION_ACTION);
Permission view = new Permission(ArduinoConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants
.UI_PERMISSION_ACTION);
return new Permission[]{androidSense, view};
}
}

View File

@ -27,4 +27,8 @@
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.wso2.carbon.device.mgt.iot.arduino.service.impl.listener.ArduinoPermissionUpdateListener</listener-class>
</listener>
</web-app>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -35,4 +35,9 @@ public class RaspberrypiConstants {
public static final String SCOPE = "scope";
public static final String PERM_ENROLL_RASPBERRYPI = "/permission/admin/device-mgt/devices/enroll/raspberrypi";
public static final String PERM_OWNING_DEVICE_VIEW = "/permission/admin/device-mgt/devices/owning-device/view";
public static final String ROLE_NAME = "internal/devicemgt-user";
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.device.mgt.iot.raspberrypi.service.impl.listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.constants.RaspberrypiConstants;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class RaspberryPIPermissionUpdateListener implements ServletContextListener {
private static Log log = LogFactory.getLog(RaspberryPIPermissionUpdateListener.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
UserStoreManager userStoreManager = getUserStoreManager();
try {
if (userStoreManager != null) {
if (!userStoreManager.isExistingRole(RaspberrypiConstants.ROLE_NAME)) {
userStoreManager.addRole(RaspberrypiConstants.ROLE_NAME, null, getPermissions());
} else {
getAuthorizationManager().authorizeRole(RaspberrypiConstants.ROLE_NAME,
RaspberrypiConstants.PERM_ENROLL_RASPBERRYPI, CarbonConstants.UI_PERMISSION_ACTION);
getAuthorizationManager().authorizeRole(RaspberrypiConstants.ROLE_NAME,
RaspberrypiConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants.UI_PERMISSION_ACTION);
}
} } catch (UserStoreException e) {
log.error("Error while creating a role and adding a user for Raspberry PI.", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
public static UserStoreManager getUserStoreManager() {
RealmService realmService;
UserStoreManager userStoreManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return userStoreManager;
}
public static AuthorizationManager getAuthorizationManager() {
RealmService realmService;
AuthorizationManager authorizationManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return authorizationManager;
}
private Permission[] getPermissions() {
Permission androidSense = new Permission(RaspberrypiConstants.PERM_ENROLL_RASPBERRYPI,
CarbonConstants.UI_PERMISSION_ACTION);
Permission view = new Permission(RaspberrypiConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants
.UI_PERMISSION_ACTION);
return new Permission[]{androidSense, view};
}
}

View File

@ -31,4 +31,8 @@
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.listener.RaspberryPIPermissionUpdateListener</listener-class>
</listener>
</web-app>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentUtilOperations;
@ -115,8 +116,11 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
try {
receivedMessage = message.toString();
if(!receivedMessage.contains("POLICY")){
if(!receivedMessage.contains("policyDefinition")){
receivedMessage = AgentUtilOperations.extractMessageFromPayload(receivedMessage);
}else{
JSONObject jsonMessage = new JSONObject(receivedMessage);
updateCEPPolicy(jsonMessage.getString("policyDefinition"));
}
log.info(AgentConstants.LOG_APPENDER + "Message [" + receivedMessage + "] was received");
} catch (AgentCoreOperationException e) {
@ -289,6 +293,7 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
String fileLocation = agentManager.getRootPath() + AgentConstants.CEP_FILE_NAME;
message = AgentUtilOperations.formatMessage(message);
AgentUtilOperations.writeToFile(message, fileLocation);
AgentManager.setUpdated(true);
agentManager.addToPolicyLog(message);
}

View File

@ -57,7 +57,7 @@ public class AgentConstants {
--------------------------------------------------------------------------------------- */
public static final int DEFAULT_MQTT_RECONNECTION_INTERVAL = 2; // time in seconds
public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = 0;
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s";
public static final String MQTT_SUBSCRIBE_TOPIC = "%s/" + DEVICE_TYPE + "/%s/#";
public static final String MQTT_PUBLISH_TOPIC = "%s/" + DEVICE_TYPE + "/%s/temperature";
/* ---------------------------------------------------------------------------------------
XMPP Connection specific information

View File

@ -43,7 +43,7 @@ public class CommunicationUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class);
// The Signature Algorithm used.
private static final String SIGNATURE_ALG = "SHA1withRSA";
private static final String SHA_512 = "SHA-512";
// The Encryption Algorithm and the Padding used.
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
@ -108,7 +108,7 @@ public class CommunicationUtils {
String signedEncodedString;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(message));
@ -117,11 +117,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
@ -153,7 +153,7 @@ public class CommunicationUtils {
boolean verified;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data));
@ -161,11 +161,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {

View File

@ -34,6 +34,8 @@ import java.net.ServerSocket;
import java.net.SocketException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
@ -172,27 +174,26 @@ public class TransportUtils {
*/
public static synchronized int getAvailablePort(int randomAttempts) {
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
Random randomNum = new Random();
int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) {
randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) {
return randomPort;
try {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) {
randomPort = secureRandom.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) {
return randomPort;
}
failedPorts.add(randomPort);
randomAttempts--;
}
failedPorts.add(randomPort);
randomAttempts--;
}
randomPort = MAX_PORT_NUMBER;
while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort;
randomPort = MAX_PORT_NUMBER;
while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort;
}
randomPort--;
}
randomPort--;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
}

View File

@ -33,6 +33,8 @@ import javax.sound.sampled.Clip;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* This class use to emulate virtual hardware functionality
@ -188,9 +190,12 @@ public class VirtualHardwareManager {
double mn = current - offset;
min = (mn < min) ? min : (int) Math.round(mn);
}
double rnd = Math.random() * (max - min) + min;
return (int) Math.round(rnd);
try {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
return secureRandom.nextInt(max - min) + min;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
}

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -129,11 +129,8 @@ public class EnrollmentManager {
public void setEnrollmentStatus() {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) &&
keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS) &&
@ -146,21 +143,7 @@ public class EnrollmentManager {
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} catch (CertificateException | NoSuchAlgorithmException e) {
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst trying to [load] the device KeyStore '" +
AgentConstants.DEVICE_KEYSTORE + "'.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} catch (IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"An error occurred whilst trying to load input stream with the keystore file: " +
AgentConstants.DEVICE_KEYSTORE);
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
}
try {
if (this.isEnrolled) {
this.SCEPCertificate = (X509Certificate) keyStore.getCertificate(AgentConstants.DEVICE_CERT_ALIAS);
@ -262,9 +245,6 @@ public class EnrollmentManager {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
keyStore.setCertificateEntry(alias, certificate);
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
@ -285,9 +265,6 @@ public class EnrollmentManager {
KeyStore keyStore;
try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
Certificate[] certChain = new Certificate[1];
certChain[0] = certInCertChain;

View File

@ -43,7 +43,7 @@ public class CommunicationUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class);
// The Signature Algorithm used.
private static final String SIGNATURE_ALG = "SHA1withRSA";
private static final String SHA_512 = "SHA-512";
// The Encryption Algorithm and the Padding used.
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
@ -107,7 +107,7 @@ public class CommunicationUtils {
String signedEncodedString;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(message));
@ -116,11 +116,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {
@ -152,7 +152,7 @@ public class CommunicationUtils {
boolean verified;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data));
@ -160,11 +160,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) {
String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
"Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) {

View File

@ -36,6 +36,8 @@ import java.net.ServerSocket;
import java.net.SocketException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
@ -173,27 +175,26 @@ public class TransportUtils {
*/
public static synchronized int getAvailablePort(int randomAttempts) {
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
Random randomNum = new Random();
int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) {
randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) {
return randomPort;
try {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) {
randomPort = secureRandom.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) {
return randomPort;
}
failedPorts.add(randomPort);
randomAttempts--;
}
failedPorts.add(randomPort);
randomAttempts--;
}
randomPort = MAX_PORT_NUMBER;
while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort;
randomPort = MAX_PORT_NUMBER;
while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort;
}
randomPort--;
}
randomPort--;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
}

View File

@ -33,6 +33,8 @@ import javax.sound.sampled.Clip;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* This class use to emulate virtual hardware functionality
@ -174,19 +176,19 @@ public class VirtualHardwareManager {
}
private int getRandom(int max, int min, int current, boolean isSmoothed, int svf) {
if (isSmoothed) {
int offset = (max - min) * svf / 100;
double mx = current + offset;
max = (mx > max) ? max : (int) Math.round(mx);
double mn = current - offset;
min = (mn < min) ? min : (int) Math.round(mn);
}
double rnd = Math.random() * (max - min) + min;
return (int) Math.round(rnd);
try {
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
return secureRandom.nextInt(max - min) + min;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
}
private void setAudioSequencer() {

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -81,4 +81,9 @@ public class VirtualFireAlarmConstants {
public static final String MQTT_ADAPTER_TOPIC_PROPERTY_NAME = "mqtt.adapter.topic";
public static final String APIM_APPLICATION_TOKEN_VALIDITY_PERIOD = "3600";
public static final String PERM_ENROLL_FIRE_ALARM = "/permission/admin/device-mgt/devices/enroll/firealarm";
public static final String PERM_OWNING_DEVICE_VIEW = "/permission/admin/device-mgt/devices/owning-device/view";
public static final String ROLE_NAME = "internal/devicemgt-user";
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed 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.device.mgt.iot.virtualfirealarm.service.impl.listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.user.core.service.RealmService;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class VirtualFireAlarmPermissionUpdateListener implements ServletContextListener {
private static Log log = LogFactory.getLog(VirtualFireAlarmPermissionUpdateListener.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
UserStoreManager userStoreManager = getUserStoreManager();
try {
if (userStoreManager != null) {
if (!userStoreManager.isExistingRole(VirtualFireAlarmConstants.ROLE_NAME)) {
userStoreManager.addRole(VirtualFireAlarmConstants.ROLE_NAME, null, getPermissions());
} else {
getAuthorizationManager().authorizeRole(VirtualFireAlarmConstants.ROLE_NAME,
VirtualFireAlarmConstants.PERM_ENROLL_FIRE_ALARM, CarbonConstants.UI_PERMISSION_ACTION);
getAuthorizationManager().authorizeRole(VirtualFireAlarmConstants.ROLE_NAME,
VirtualFireAlarmConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants.UI_PERMISSION_ACTION);
}
} } catch (UserStoreException e) {
log.error("Error while creating a role and adding a user for Raspberry PI.", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
public static UserStoreManager getUserStoreManager() {
RealmService realmService;
UserStoreManager userStoreManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return userStoreManager;
}
public static AuthorizationManager getAuthorizationManager() {
RealmService realmService;
AuthorizationManager authorizationManager;
try {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
realmService = (RealmService) ctx.getOSGiService(RealmService.class, null);
if (realmService == null) {
String msg = "Realm service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
int tenantId = ctx.getTenantId();
authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager();
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving current user store manager";
log.error(msg, e);
throw new IllegalStateException(msg);
}
return authorizationManager;
}
private Permission[] getPermissions() {
Permission androidSense = new Permission(VirtualFireAlarmConstants.PERM_ENROLL_FIRE_ALARM,
CarbonConstants.UI_PERMISSION_ACTION);
Permission view = new Permission(VirtualFireAlarmConstants.PERM_OWNING_DEVICE_VIEW, CarbonConstants
.UI_PERMISSION_ACTION);
return new Permission[]{androidSense, view};
}
}

View File

@ -27,6 +27,8 @@
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.listener.VirtualFireAlarmPermissionUpdateListener</listener-class>
</listener>
</web-app>

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -51,7 +51,7 @@ public class VirtualFirealarmSecurityManager {
private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class);
private static PrivateKey serverPrivateKey;
private static final String SIGNATURE_ALG = "SHA1withRSA";
private static final String SHA_512 = "SHA-512";
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
private static CertificateKeystoreConfig certificateKeystoreConfig;
private VirtualFirealarmSecurityManager() {
@ -162,7 +162,7 @@ public class VirtualFirealarmSecurityManager {
String signedEncodedString;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(encryptedData));
@ -170,11 +170,11 @@ public class VirtualFirealarmSecurityManager {
signedEncodedString = Base64.encodeBase64String(signatureBytes);
} catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) {
@ -193,18 +193,18 @@ public class VirtualFirealarmSecurityManager {
boolean verified;
try {
signature = Signature.getInstance(SIGNATURE_ALG);
signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data));
verified = signature.verify(Base64.decodeBase64(signedData));
} catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]";
String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) {

View File

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mb-extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>android-plugin</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -23,13 +23,13 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.mobile.android.ui</artifactId>
<version>3.0.7-SNAPSHOT</version>
<version>3.0.9-SNAPSHOT</version>
<name>WSO2 Carbon - Mobile Android UI</name>
<packaging>pom</packaging>

View File

@ -1,5 +1,5 @@
{
"appName": "WSO2 Enterprise Mobility Manager",
"appName": "WSO2 IoT Server",
"cachingEnabled": true,
"debuggingEnabled": false,
"permissionRoot": "/",
@ -27,10 +27,10 @@
},
"sso": {
"enabled": false,
"issuer" : "emm",
"appName" : "emm",
"issuer" : "devicemgt",
"appName" : "devicemgt",
"identityProviderUrl" : "https://localhost:9443/samlsso",
"acs": "https://localhost:9443/emm/uuf/sso/acs",
"acs": "https://localhost:9443/devicemgt/uuf/sso/acs",
"identityAlias": "wso2carbon",
"responseSigningEnabled" : "true",
"useTenantKey": false
@ -38,8 +38,8 @@
},
"generalConfig" : {
"host" : "https://localhost:9443",
"companyName" : "WSO2 Enterprise Mobility Manager",
"browserTitle" : "WSO2 EMM",
"companyName" : "WSO2 IoT Server",
"browserTitle" : "WSO2 IoT Server",
"copyrightPrefix" : "\u00A9 %date-year%, ",
"copyrightOwner" : "WSO2 Inc.",
"copyrightOwnersSite" : "http://www.wso2.org",

View File

@ -3,11 +3,7 @@
"httpsURL" : "%https.ip%",
"httpURL" : "%http.ip%",
"enrollmentDir": "/android-web-agent/enrollment",
"iOSConfigRoot" : "%https.ip%/ios-enrollment/",
"iOSAPIRoot" : "%https.ip%/api/device-mgt/ios/v1.0/",
"dynamicClientRegistrationEndPoint" : "%https.ip%/dynamic-client-web/register/",
"adminService":"%https.ip%",
"idPServer":"%https.ip%",
"callBackUrl":"%https.ip%/mdm-admin",
"oauthProvider": {
"appRegistration": {
@ -22,24 +18,15 @@
},
"tokenServiceURL": "%https.ip%/oauth2/token"
},
"adminUser":"admin",
"userValidationConfig" : {
"usernameLength":30
},
"device" : {
"ios" : {
"location" : "%http.ip%/android-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa",
"bundleID" : "org.wso2.carbon.emm.iOSMDMAgent",
"version" : "1.0",
"appName" : "EMM iOS Agent"
}
},
"androidAgentApp" : "android-agent.apk",
"windowsConfigRoot" : "%http.ip%/api/device-mgt/windows/v1.0/services/federated/bst/authentication",
"generalConfig" : {
"host" : "%http.ip%",
"companyName" : "WSO2 Enterprise Mobility Manager",
"browserTitle" : "WSO2 EMM",
"companyName" : "WSO2 IoT Server",
"browserTitle" : "WSO2 IoT Server",
"copyrightText" : "\u00A9 %date-year%, WSO2 Inc. (http://www.wso2.org) All Rights Reserved."
},
"isOAuthEnabled" : true,

View File

@ -22,6 +22,7 @@ var conf = function () {
conf = require("/app/conf/config.json");
var pinch = require("/app/modules/conf-reader/pinch.min.js")["pinch"];
var server = require("carbon")["server"];
var process = require("process");
pinch(conf, /^/,
function (path, key, value) {
if ((typeof value === "string") && value.indexOf("%https.ip%") > -1) {
@ -33,8 +34,23 @@ var conf = function () {
} else if ((typeof value === "string") && value.indexOf("%date-year%") > -1) {
var year = new Date().getFullYear();
return value.replace("%date-year%", year);
} else {
var paramPattern = new RegExp("%(.*?)%", "g");
var out = value;
while ((matches = paramPattern.exec(value)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === paramPattern.lastIndex) {
paramPattern.lastIndex++;
}
if (matches.length == 2) {
var property = process.getProperty(matches[1]);
if (property) {
out = out.replace(new RegExp("%" + matches[1] + "%", "g"), property);
}
}
}
return out;
}
return value;
}
);
application.put("CONF", conf);

View File

@ -171,7 +171,7 @@ h2.app-title {
margin:0;
padding:3px 0 0 0;
color:#fafafa;
text-transform: uppercase;
/*text-transform: uppercase;*/
}
.wr-global-header {
@ -208,7 +208,7 @@ h2.app-title {
@media (max-width: 570px) {
h2.app-title:after {
content: "EMM";
content: "IoT Server";
}
h2.app-title span {
display: none;

View File

@ -22,7 +22,7 @@
{{#zone "overview-section"}}
<div class="media-body asset-desc add-padding-left-5x">
<div style="background: #11375B; color: #fff; padding: 10px; margin-bottom: 5px">Device
Overview
Overview
</div>
<table class="table table-responsive table-striped" id="members">
<tbody>
@ -89,7 +89,7 @@
{{#if device.osBuildDate}}
<tr role="row" class="even">
<td class="sorting_1" style="padding:10px 15px; width: 15%;">Firmware Build
Date
Date
</td>
<td style="padding:10px 15px;">{{device.osBuildDate}}</td>
</tr>
@ -131,7 +131,7 @@
<i class="icon fw fw-policy"></i><span class="hidden-sm">Policy Compliance</span>
</a>
</li>
<li role="presentation" class="list-group-item">
<li role="presentation" class="list-group-item location_tab">
<a href="#device_location_tab" role="tab" data-toggle="tab"
data-lat="{{device.location.latitude}}"
data-long="{{device.location.longitude}}"
@ -185,19 +185,19 @@
</div>
{{/if}}
<!--{{#if device.cpuUsage}}-->
<!--<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">-->
<!--<div class="col-md-12">-->
<!--<div class="wr-stats-board-tile">-->
<!--<div class="tile-name">CPU Usage</div>-->
<!--<div>-->
<!--<div class="tile-icon"><i class="fw fw-dashboard"></i></div>-->
<!--<div class="tile-stats">-->
<!--{{device.cpuUsage.value}} %-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">-->
<!--<div class="col-md-12">-->
<!--<div class="wr-stats-board-tile">-->
<!--<div class="tile-name">CPU Usage</div>-->
<!--<div>-->
<!--<div class="tile-icon"><i class="fw fw-dashboard"></i></div>-->
<!--<div class="tile-stats">-->
<!--{{device.cpuUsage.value}} %-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--{{/if}}-->
{{#if device.ramUsage}}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
@ -228,9 +228,9 @@
<div class="tile-stats">
{{device.internalMemory
.usage}} %
<span class="tile-stats-free">
<span class="tile-stats-free">
TOTAL OF {{device.internalMemory
.total}} GB
.total}} GB
</span>
</div>
</div>
@ -249,9 +249,9 @@
<div class="tile-stats">
{{device.externalMemory
.usage}} %
<span class="tile-stats-free">
<span class="tile-stats-free">
TOTAL OF {{device.externalMemory
.total}} GB
.total}} GB
</span>
</div>
</div>
@ -291,7 +291,7 @@
<div class="panel-heading display-none-xs">
Policy Compliance
<span>
<span>
<a href="javascript:void(0);" id="refresh-policy">
<i class="fw fw-refresh"></i>
</a>
@ -308,7 +308,7 @@
<div id="policy-spinner"
class="wr-advance-operations-init add-padding-bottom-2x add-padding-bottom-4x hidden">
<i class="fw fw-settings fw-spin fw-2x"></i>Loading Policy
Compliance...
Compliance...
</div>
<div id="policy-list-container">
</div>
@ -335,11 +335,12 @@
{{#if device.location}}
<div id="device-location"
data-lat="{{device.location.latitude}}"
data-long="{{device.location.longitude}}">
data-long="{{device.location.longitude}}"
data-locations = "{{device.locationHistory}}">
</div>
<br/>
<a class="padding-left" target="_blank"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{deviceId}},{{deviceType}}">
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-map-location fw-stack-1x"></i>
@ -375,7 +376,7 @@
<div class="panel-heading display-none-xs">
Installed Applications
<span>
<span>
<a href="javascript:void(0);" id="refresh-apps">
<i class="fw fw-refresh"></i>
</a>
@ -391,7 +392,7 @@
</span>
<div id="apps-spinner" class="wr-advance-operations-init hidden">
<i class="fw fw-settings fw-spin fw-2x"></i> Loading Applications
List...
List...
</div>
<div id="applications-list-container">
<div class="message message-info">

View File

@ -17,7 +17,7 @@
*/
function onRequest(context) {
// var log = new Log("device-view.js");
// var log = new Log("device-view.js");
var deviceType = context["uriParams"]["deviceType"];
var deviceId = request.getParameter("id");
var deviceViewData = {};
@ -32,7 +32,7 @@ function onRequest(context) {
var filteredDeviceData = response["content"];
// creating deviceView information model from filtered device data
// creating deviceView information model from filtered device data
var viewModel = {};
if (filteredDeviceData["type"]) {
viewModel["type"] = filteredDeviceData["type"];
@ -194,7 +194,7 @@ function onRequest(context) {
if (!filteredDeviceData["initialDeviceInfo"] && !filteredDeviceData["latestDeviceInfo"]) {
viewModel["deviceInfoAvailable"] = false;
}
viewModel.locationHistory = stringify(filteredDeviceData["locationHistory"]);
deviceViewData["device"] = viewModel;
} else if (response["status"] == "unauthorized") {
deviceViewData["deviceFound"] = true;
@ -213,7 +213,6 @@ function onRequest(context) {
deviceViewData["autoCompleteParams"] = autoCompleteParams;
deviceViewData["portalUrl"] = devicemgtProps['portalURL'];
deviceViewData["deviceId"] = deviceId;
deviceViewData["deviceType"] = deviceType;
deviceViewData["anchor"] = encodeURI(JSON.stringify({ "device" : { "id" : deviceId, "type" : deviceType}}));
return deviceViewData;
}

View File

@ -20,17 +20,29 @@ var map;
function loadLeafletMap() {
var deviceLocationID = "#device-location",
lat = $(deviceLocationID).data("lat"),
long = $(deviceLocationID).data("long"),
locations = $(deviceLocationID).data("locations"),
container = "device-location",
zoomLevel = 13,
tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution = "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap</a> contributors";
if (locations) {
if (lat && long) {
map = L.map(container).setView([lat, long], zoomLevel);
var locationSets = locations.locations;
map = L.map(container).setView([locationSets[0].lat, locationSets[0].lng], zoomLevel);
L.tileLayer(tileSet, {attribution: attribution}).addTo(map);
L.marker([lat, long]).addTo(map).bindPopup("Device is here...").openPopup();
var initTime = locations.times[0].time, lastTime = locations.times[locationSets.length - 1].time;
var totalTime = lastTime - initTime;
for (var i = 0; i < locationSets.length; i++) {
var opacVal = (locations.times[i].time - initTime) / totalTime;
var m = L.marker(locationSets[i], {"opacity": opacVal}).addTo(map).bindPopup(new Date(locations.times[i].time).toISOString());
m.on('mouseover', function (e) {
this.openPopup();
});
m.on('mouseout', function (e) {
this.closePopup();
});
}
$("#map-error").hide();
$("#device-location").show();
@ -41,14 +53,7 @@ function loadLeafletMap() {
}
$(document).ready(function () {
$("a[data-toggle='tab']").on("shown.bs.tab", function() {
var url = $(this).prop("href");
var hash = url.substring(url.indexOf("#") + 1);
if (hash == "device_location_tab") {
if (!map) {
loadLeafletMap();
}
}
$(".location_tab").on("click", function () {
loadLeafletMap();
});
});

Some files were not shown because too many files have changed in this diff Show More