/* * * Headwind MDM: Open Source Android MDM Software * https://h-mdm.com * * Copyright (C) 2019 Headwind Solutions LLC (http://h-sms.com) * * 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 com.hmdm.plugins.devicelog.rest.resource; import javax.inject.Inject; import javax.inject.Singleton; import com.hmdm.notification.PushService; import com.hmdm.persistence.ConfigurationDAO; import com.hmdm.persistence.DeviceDAO; import com.hmdm.persistence.GroupDAO; import com.hmdm.persistence.domain.Device; import com.hmdm.persistence.domain.DeviceSearchRequest; import com.hmdm.plugins.devicelog.model.DeviceLogPluginSettings; import com.hmdm.plugins.devicelog.model.DeviceLogRule; import com.hmdm.plugins.devicelog.persistence.DeviceLogPluginSettingsDAO; import com.hmdm.plugins.devicelog.rest.json.DeviceLogFilter; import com.hmdm.rest.json.LookupItem; import com.hmdm.rest.json.Response; import com.hmdm.security.SecurityContext; import com.hmdm.security.SecurityException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.Authorization; import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * <p>A resource to be used for accessing the settings for <code>Photo Plugin</code>.</p> * * @author isv */ @Api(tags = {"Plugin - Device Log"}) @Singleton @Path("/plugins/devicelog/devicelog-plugin-settings") public class DeviceLogPluginSettingsResource { /** * <p>A logger to be used for logging the events.</p> */ private static final Logger log = LoggerFactory.getLogger("plugin-photo"); /** * <p>A DAO for managing the plugin settings.</p> */ private DeviceLogPluginSettingsDAO settingsDAO; private DeviceDAO deviceDAO; private PushService pushService; /** * <p>A constructor required by Swagger.</p> */ public DeviceLogPluginSettingsResource() { } /** * <p>Constructs new <code>PhotoPluginSettingsResource</code> instance. This implementation does nothing.</p> */ @Inject public DeviceLogPluginSettingsResource(DeviceLogPluginSettingsDAO settingsDAO, DeviceDAO deviceDAO, PushService pushService) { this.settingsDAO = settingsDAO; this.deviceDAO = deviceDAO; this.pushService = pushService; } /** * <p>Gets the plugin settings for customer account associated with current user. If there are none found in DB * then returns default ones.</p> * * @return plugin settings for current customer account. */ @ApiOperation( value = "Get settings", notes = "Gets the plugin settings for current user. If there are none found in DB then returns default ones.", response = DeviceLogPluginSettings.class, authorizations = {@Authorization("Bearer Token")} ) @GET @Path("/private") @Produces(MediaType.APPLICATION_JSON) public Response getSettings() { try { DeviceLogPluginSettings pluginSettings = this.settingsDAO.getPluginSettings(); if (pluginSettings != null) { return Response.OK(pluginSettings); } else { DeviceLogPluginSettings defaultPluginSettings = this.settingsDAO.getDefaultSettings(); this.settingsDAO.insertPluginSettings(defaultPluginSettings); pluginSettings = this.settingsDAO.getPluginSettings(); if (pluginSettings != null) { return Response.OK(pluginSettings); } else { log.error("Failed to save default device log plugin settings"); return Response.INTERNAL_ERROR(); } } } catch (Exception e) { log.error("Failed to retrieve device log plugin settings", e); return Response.INTERNAL_ERROR(); } } @ApiOperation( value = "Create or update plugin settings", notes = "Creates a new plugin settings record (if id is not provided) or updates existing one otherwise", authorizations = {@Authorization("Bearer Token")} ) @PUT @Path("/private") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response saveMainSettings(String settingsJSON) { try { ObjectMapper mapper = new ObjectMapper(); DeviceLogPluginSettings settings = mapper.readValue(settingsJSON, this.settingsDAO.getSettingsClass()); if (settings.getIdentifier() == null) { this.settingsDAO.insertPluginSettings(settings); } else { this.settingsDAO.updatePluginSettings(settings); } return Response.OK(); } catch (Exception e) { log.error("Failed to create or update device log plugin settings", e); return Response.INTERNAL_ERROR(); } } @ApiOperation( value = "Create or update plugin settings rule", notes = "Creates a new plugin settings rule record (if id is not provided) or updates existing one otherwise", authorizations = {@Authorization("Bearer Token")} ) @PUT @Path("/private/rule") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response saveSettingsRule(String ruleJSON) { try { ObjectMapper mapper = new ObjectMapper(); DeviceLogRule rule = mapper.readValue(ruleJSON, this.settingsDAO.getSettingsRuleClass()); this.settingsDAO.savePluginSettingsRule(rule); notifyRuleDevices(rule); return Response.OK(); } catch (Exception e) { log.error("Failed to create or update device log plugin settings rule", e); return Response.INTERNAL_ERROR(); } } // ================================================================================================================= @ApiOperation( value = "Delete rule", notes = "Delete an existing plugin settings rule" ) @DELETE @Path("/private/rule/{id}") @Produces(MediaType.APPLICATION_JSON) public Response removeRule(@PathParam("id") @ApiParam("Rule ID") Integer id) { try { DeviceLogRule rule = this.settingsDAO.getPluginSettingsRuleById(id); if (rule != null) { this.settingsDAO.deletePluginSettingRule(id); notifyRuleDevices(rule); } return Response.OK(); } catch (SecurityException e) { log.error("Prohibited to delete device log plugin settings rule #{} by current user", id, e); return Response.PERMISSION_DENIED(); } catch (Exception e) { log.error("Failed to delete device log plugin settings rule #{} due to unexpected error", id, e); return Response.INTERNAL_ERROR(); } } private void notifyRuleDevices(DeviceLogRule rule) { if (rule.getDevices() != null && rule.getDevices().size() > 0) { for (LookupItem item : rule.getDevices()) { pushService.notifyDeviceOnSettingUpdate(item.getId()); } } else { List<Device> devices = getDevicesByRule(rule); for (Device device : devices) { pushService.notifyDeviceOnSettingUpdate(device.getId()); } } } // Applicable only to rules which do not contain explicit list of devices! private List<Device> getDevicesByRule(DeviceLogRule rule) { DeviceSearchRequest dsr = new DeviceSearchRequest(); dsr.setPageSize(1000000); // No page limitations dsr.setCustomerId(SecurityContext.get().getCurrentCustomerId().get()); dsr.setUserId(SecurityContext.get().getCurrentUser().get().getId()); if (rule.getConfigurationId() != null) { dsr.setConfigurationId(rule.getConfigurationId()); } if (rule.getGroupId() != null) { dsr.setGroupId(rule.getGroupId()); } return deviceDAO.getAllDevices(dsr).getItems(); } }