From 8d15d0a0fb9bc94c9ca099472d605ae06f1353f8 Mon Sep 17 00:00:00 2001 From: Admin Date: Thu, 9 Jun 2016 16:44:11 -0500 Subject: [PATCH] Tested api changes --- pom.xml | 2 +- .../bwssystems/HABridge/BridgeSettings.java | 23 ++- .../HABridge/BridgeSettingsDescriptor.java | 10 + .../com/bwssystems/HABridge/HABridge.java | 3 +- .../HABridge/api/hue/HueConfig.java | 1 - .../bwssystems/HABridge/hue/HueMulator.java | 174 ++++++++++++++---- src/main/java/com/bwssystems/hal/HalHome.java | 6 +- src/main/java/com/bwssystems/hal/HalInfo.java | 2 + 8 files changed, 176 insertions(+), 45 deletions(-) diff --git a/pom.xml b/pom.xml index e8c94e8..b2e9c3c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 2.0.7-hal-g + 2.0.7-hal-h jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 40245bd..b1236ef 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -20,6 +20,7 @@ import com.bwssystems.util.JsonTransformer; import com.google.gson.Gson; public class BridgeSettings extends BackupHandler { + private static final Logger log = LoggerFactory.getLogger(BridgeSettings.class); private BridgeSettingsDescriptor theBridgeSettings; private BridgeControlDescriptor bridgeControl; @@ -35,7 +36,6 @@ public class BridgeSettings extends BackupHandler { return theBridgeSettings; } public void buildSettings() { - Logger log = LoggerFactory.getLogger(BridgeSettings.class); InetAddress address = null; String addressString = null; String theVeraAddress = null; @@ -146,9 +146,15 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setUpnpDeviceDb(Configuration.DEVICE_DB_DIRECTORY); if(theBridgeSettings.getNumberoflogmessages() == null) - theBridgeSettings.setNumberoflogmessages(Configuration.NUMBER_OF_LOG_MESSAGES); + theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES)); + + if(theBridgeSettings.getNumberoflogmessages() <= 0) + theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES)); + + if(theBridgeSettings.getButtonsleep() == null) + theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP)); - if(theBridgeSettings.getButtonsleep() <= 0) + if(theBridgeSettings.getButtonsleep() < 0) theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP)); theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera()); @@ -172,11 +178,17 @@ public class BridgeSettings extends BackupHandler { private void _loadConfig(Path aPath) { String jsonContent = configReader(aPath); + try { theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class); + } catch (Exception e) { + log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed."); + theBridgeSettings = new BridgeSettingsDescriptor(); + theBridgeSettings.setConfigfile(aPath.toString()); + } + } public void save(BridgeSettingsDescriptor newBridgeSettings) { - Logger log = LoggerFactory.getLogger(BridgeSettings.class); log.debug("Save HA Bridge settings."); Path configPath = Paths.get(theBridgeSettings.getConfigfile()); JsonTransformer aRenderer = new JsonTransformer(); @@ -187,7 +199,6 @@ public class BridgeSettings extends BackupHandler { private void configWriter(String content, Path filePath) { - Logger log = LoggerFactory.getLogger(BridgeSettings.class); if(Files.exists(filePath) && !Files.isWritable(filePath)){ log.error("Error file is not writable: " + filePath); return; @@ -216,8 +227,6 @@ public class BridgeSettings extends BackupHandler { } private String configReader(Path filePath) { - Logger log = LoggerFactory.getLogger(BridgeSettings.class); - String content = null; if(Files.notExists(filePath) || !Files.isReadable(filePath)){ log.warn("Error reading the file: " + filePath + " - Does not exist or is not readable. continuing..."); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index c2c1f2a..b6066db 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -31,6 +31,7 @@ public class BridgeSettingsDescriptor { private String haltoken; private boolean halconfigured; private Map whitelist; + private boolean settingsChanged; public BridgeSettingsDescriptor() { super(); @@ -40,7 +41,10 @@ public class BridgeSettingsDescriptor { this.veraconfigured = false; this.harmonyconfigured = false; this.hueconfigured = false; + this.halconfigured = false; this.farenheit = true; + this.whitelist = null; + this.settingsChanged = false; } public String getUpnpConfigAddress() { return upnpconfigaddress; @@ -198,6 +202,12 @@ public class BridgeSettingsDescriptor { public void setWhitelist(Map whitelist) { this.whitelist = whitelist; } + public boolean isSettingsChanged() { + return settingsChanged; + } + public void setSettingsChanged(boolean settingsChanged) { + this.settingsChanged = settingsChanged; + } public Boolean isValidVera() { if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0) return false; diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 7e67655..928570c 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -87,7 +87,8 @@ public class HABridge { log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted...."); else bridgeSettings.getBridgeControl().setStop(true); - + if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged()) + bridgeSettings.save(bridgeSettings.getBridgeSettingsDescriptor()); bridgeSettings.getBridgeControl().setReinit(false); stop(); nestHome.closeTheNest(); diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java index e0cac47..4562a26 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java @@ -6,7 +6,6 @@ import java.net.SocketException; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.HashMap; import java.util.Map; import java.util.TimeZone; diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 3a6d7dd..c6a0cb1 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -65,8 +65,10 @@ import java.net.InetAddress; import java.net.Socket; import java.nio.charset.Charset; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.UUID; @@ -146,6 +148,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue groups list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); // http://ip_address:port/api/{userId}/groups/0 returns json objects of all groups configured @@ -154,6 +163,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue group 0 list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "[{\"error\":{\"type\":\"3\", \"address\": \"/api/" + userId + "/groups/" + "0" + "\",\"description\": \"Object not found\"}}]"; }); // http://ip_address:port/api/{userId}/scenes returns json objects of all scenes configured @@ -162,6 +178,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue scenes list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); // http://ip_address:port/api/{userId}/schedules returns json objects of all schedules configured @@ -170,6 +193,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue schedules list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); // http://ip_address:port/api/{userId}/sensors returns json objects of all sensors configured @@ -178,6 +208,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue sensors list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); // http://ip_address:port/api/{userId}/rules returns json objects of all rules configured @@ -186,6 +223,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue rules list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); // http://ip_address:port/api/{userId}/resourcelinks returns json objects of all resourcelinks configured @@ -194,6 +238,13 @@ public class HueMulator implements HueErrorStringSet { log.debug("hue resourcelinks list requested: " + userId + " from " + request.ip()); response.status(HttpStatus.SC_OK); response.header("Access-Control-Allow-Origin", request.headers("Origin")); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } + return "{}"; }); get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> { @@ -201,15 +252,22 @@ public class HueMulator implements HueErrorStringSet { if(bridgeSettings.isTraceupnp()) log.info("Traceupnp: hue lights list requested: " + userId + " from " + request.ip()); log.debug("hue lights list requested: " + userId + " from " + request.ip()); + response.type("application/json; charset=utf-8"); + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.status(HttpStatus.SC_OK); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return theErrorResp.getTheErrors(); + } + List deviceList = repository.findAll(); Map deviceResponseMap = new HashMap<>(); for (DeviceDescriptor device : deviceList) { DeviceResponse deviceResponse = DeviceResponse.createResponse(device); deviceResponseMap.put(device.getId(), deviceResponse); } - response.type("application/json; charset=utf-8"); - response.header("Access-Control-Allow-Origin", request.headers("Origin")); - response.status(HttpStatus.SC_OK); return deviceResponseMap; } , new JsonTransformer()); @@ -238,8 +296,9 @@ public class HueMulator implements HueErrorStringSet { aDeviceType = aNewUser.getDevicetype(); } if(newUser == null) - newUser = getNewUserID(request.ip()); + newUser = getNewUserID(); + validateWhitelistUser(newUser, false); if(aDeviceType == null) aDeviceType = ""; if(bridgeSettings.isTraceupnp()) @@ -276,8 +335,8 @@ public class HueMulator implements HueErrorStringSet { aDeviceType = aNewUser.getDevicetype(); } if(newUser == null) - newUser = getNewUserID(request.ip()); - + newUser = getNewUserID(); + validateWhitelistUser(newUser, false); if(aDeviceType == null) aDeviceType = ""; log.debug("HH trace: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser); @@ -303,14 +362,20 @@ public class HueMulator implements HueErrorStringSet { // http://ip_address:port/api/{userId}/config returns json objects for the config get(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> { String userId = request.params(":userid"); - if(bridgeSettings.isTraceupnp()) - log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + request.ip()); - log.debug("hue api config requested: " + userId + " from " + request.ip()); - HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist()); - response.type("application/json; charset=utf-8"); response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.status(HttpStatus.SC_OK); + if(bridgeSettings.isTraceupnp()) + log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + request.ip()); + log.debug("hue api config requested: " + userId + " from " + request.ip()); + if(validateWhitelistUser(userId, true) == null) { + log.debug("Valudate user, No User supplied, returning public config"); + HuePublicConfig apiResponse = HuePublicConfig.createConfig("Philips hue", bridgeSettings.getUpnpConfigAddress()); + return apiResponse; + } + + HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist()); + return apiResponse.getConfig(); }, new JsonTransformer()); @@ -321,28 +386,25 @@ public class HueMulator implements HueErrorStringSet { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json; charset=utf-8"); response.status(HttpStatus.SC_OK); - if(userId == null || userId.equalsIgnoreCase("undefined") || userId.equalsIgnoreCase("null") || userId.equalsIgnoreCase("")) { - log.debug("hue api full state requested: " + userId + " from " + request.ip() + ". No User supplied"); + log.debug("hue api full state requested: " + userId + " from " + request.ip()); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); HueErrorResponse theErrorResp = new HueErrorResponse(); theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); return theErrorResp.getTheErrors(); } - else - log.debug("hue api full state requested: " + userId + " from " + request.ip()); - List descriptorList = repository.findAll(); - if (descriptorList == null) { - response.status(HttpStatus.SC_NOT_FOUND); - return null; - } + + HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist()); Map deviceList = new HashMap<>(); - - descriptorList.forEach(descriptor -> { - DeviceResponse deviceResponse = DeviceResponse.createResponse(descriptor); - deviceList.put(descriptor.getId(), deviceResponse); - } - ); - HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist()); - apiResponse.setLights(deviceList); + List descriptorList = repository.findAll(); + if (descriptorList != null) { + descriptorList.forEach(descriptor -> { + DeviceResponse deviceResponse = DeviceResponse.createResponse(descriptor); + deviceList.put(descriptor.getId(), deviceResponse); + } + ); + apiResponse.setLights(deviceList); + } return apiResponse; }, new JsonTransformer()); @@ -355,7 +417,14 @@ public class HueMulator implements HueErrorStringSet { response.type("application/json; charset=utf-8"); response.status(HttpStatus.SC_OK); log.debug("hue light requested: " + lightId + " for user: " + userId + " from " + request.ip()); - DeviceDescriptor device = repository.findOne(lightId); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return theErrorResp.getTheErrors(); + } + + DeviceDescriptor device = repository.findOne(lightId); if (device == null) { response.status(HttpStatus.SC_NOT_FOUND); HueErrorResponse theErrorResp = new HueErrorResponse(); @@ -392,6 +461,12 @@ public class HueMulator implements HueErrorStringSet { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json; charset=utf-8"); response.status(HttpStatus.SC_OK); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } theStateChanges = new Gson().fromJson(request.body(), StateChangeBody.class); if (theStateChanges == null) { log.warn("Could not parse state change body. Light state not changed."); @@ -469,6 +544,12 @@ public class HueMulator implements HueErrorStringSet { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json; charset=utf-8"); response.status(HttpStatus.SC_OK); + if(validateWhitelistUser(userId, false) == null) { + log.debug("Valudate user, No User supplied"); + HueErrorResponse theErrorResp = new HueErrorResponse(); + theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null))); + return new Gson().toJson(theErrorResp.getTheErrors()); + } theStateChanges = new Gson().fromJson(request.body(), StateChangeBody.class); if (theStateChanges == null) { @@ -1064,8 +1145,8 @@ public class HueMulator implements HueErrorStringSet { return responseString; } - private String getNewUserID(String seed) { - UUID uid = UUID.fromString(seed); + private String getNewUserID() { + UUID uid = UUID.randomUUID(); StringTokenizer st = new StringTokenizer(uid.toString(), "-"); String newUser = ""; while(st.hasMoreTokens()) { @@ -1074,8 +1155,35 @@ public class HueMulator implements HueErrorStringSet { return newUser; } - private String lookupWhitelistUser() { - + private String validateWhitelistUser(String aUser, boolean strict) { + if(aUser == null ||aUser.equalsIgnoreCase("undefined") || aUser.equalsIgnoreCase("null") || aUser.equalsIgnoreCase("")) + return null; + + String validUser = null; + boolean found = false; + if(bridgeSettings.getWhitelist() != null) { + Set theUserIds = bridgeSettings.getWhitelist().keySet(); + Iterator userIterator = theUserIds.iterator(); + while(userIterator.hasNext()) { + validUser = userIterator.next(); + if(validUser.equals(aUser)) + found = true; + } + } + + if(!found && strict) + return null; + + if(!found) { + if(bridgeSettings.getWhitelist() == null) { + Map awhitelist = new HashMap<>(); + bridgeSettings.setWhitelist(awhitelist); + } + bridgeSettings.getWhitelist().put(aUser, WhitelistEntry.createEntry("auto insert user")); + bridgeSettings.setSettingsChanged(true); + + } + return aUser; } @Override public void setErrorString(String anError) { diff --git a/src/main/java/com/bwssystems/hal/HalHome.java b/src/main/java/com/bwssystems/hal/HalHome.java index 0546339..17c8169 100644 --- a/src/main/java/com/bwssystems/hal/HalHome.java +++ b/src/main/java/com/bwssystems/hal/HalHome.java @@ -43,8 +43,10 @@ public class HalHome { theResponse = hals.get(key).getLights(); if(theResponse != null) addHalDevices(deviceList, theResponse, key); - else - log.warn("Cannot get lights for Hal with name: " + key); + else { + log.warn("Cannot get lights for Hal with name: " + key + ", skipping this HAL."); + continue; + } theResponse = hals.get(key).getAppliances(); if(theResponse != null) addHalDevices(deviceList, theResponse, key); diff --git a/src/main/java/com/bwssystems/hal/HalInfo.java b/src/main/java/com/bwssystems/hal/HalInfo.java index 4acd36b..450fa2f 100644 --- a/src/main/java/com/bwssystems/hal/HalInfo.java +++ b/src/main/java/com/bwssystems/hal/HalInfo.java @@ -143,6 +143,8 @@ public class HalInfo { String theUrl = null; String theData; + if(theIrDevices == null) + return null; Iterator theHalDevices = theIrDevices.iterator(); deviceList = new ArrayList(); while (theHalDevices.hasNext()) {