From f8d113f3bf59e967e401aabbcb8b19a43faa97e0 Mon Sep 17 00:00:00 2001 From: dorian Date: Mon, 29 Jul 2019 00:24:01 +0200 Subject: [PATCH] - added new measvalue submit api - started to implement login --- README.md | 26 ++++- api/blueweather.php | 192 ++++++++++++++++++++++++++++++- api/json.php | 6 + api/submitSensorDataExample.json | 5 + css/dashboard.css | 12 +- dashboard.html | 51 ++++++-- index.html | 10 +- js/blueweather.js | 71 ++++++++++-- js/dashboard.js | 2 +- loginmodal2.html | 151 ++++++++++++++++++++++++ 10 files changed, 490 insertions(+), 36 deletions(-) create mode 100644 api/submitSensorDataExample.json create mode 100644 loginmodal2.html diff --git a/README.md b/README.md index 36b62eb..459cf7f 100755 --- a/README.md +++ b/README.md @@ -81,11 +81,11 @@ triggered by setting GET parameter 'locId' to a vaild location id - added - userid - sensorname - - property ('indoor' || 'sunny' || 'shadow' ) + - property ('indoor' || 'sunny' || 'shadow') - valuetypeid - valuetypes - id - - valuetype ('temperature' || 'humidity') + - valuetype ('temperature' || 'humidity' || 'pressure' || 'fine dust') - valueunit (html coding) - displayproperty - widget (properties for small widget) @@ -98,4 +98,26 @@ triggered by setting GET parameter 'locId' to a vaild location id - from - to +## submit sensor data +triggered by setting POST parameter 'submitSensorData' to a JSON encoded string containing the request +### Request +- identity: identity of the api token (given by webinterface) +- signature: SHA1 Hash of the JSON encoded string of 'data' rsa encrypted with the API Key as private key +- data: JSON array[array[ + sensorId, + measvalue, + timestamp + ]] + CAUTION!! This MUST be a string and NOT direct JSON!! +### Reply +- status: + - 200: was inserted + - 400: format of request was wrong + - 401: signture verify failed + - 404: key identity was not found + - 500: internal error + - 900: format of data JSON string was invalid + - 901: signature was fine but one or more sensors have been ignored due to some error (see 'data') all other sensors were processes successfully +- data: Array[Array[sensorId, errorCode]] sensors which were ignored due to some error (401: user doesn't own sensor; 404: senso wasn't found) + only set if status is 901 diff --git a/api/blueweather.php b/api/blueweather.php index e4f814f..0744b77 100755 --- a/api/blueweather.php +++ b/api/blueweather.php @@ -1,5 +1,4 @@ _con->query($sql); + } + + /** + * Function to validate and insert submited sensor data + * + * @param mixed $sensorData object containing + * - identity (int) + * - signature (string) + * - data (string: JSON array[array[sensorId,measvalue,timestamp]]) + * + * @return array + * 'status': 200: was inserted + * 400: format of request was wrong + * 401: signture verify failed + * 404: key identity was not found + * 500: internal error + * 900: format of data JSON string was invalid + * 901: signature was fine but one or more sensors have been ignored due to some error (see 'data') all other sensors were processes successfully + * 'data': Array[Array[sensorId, errorCode]] sensors which were ignored due to some error (401: user doesn't own sensor; 404: senso wasn't found) + * only set if status is 901 + */ + function processSensorData($sensorData) + { + + // check if request structure is valid + if (!isset($sensorData['identity']) || !isset($sensorData['signature']) || !isset($sensorData['data'])) { + return array("status"=>400); + } + + // get private key from database + $thisIdentity = $this->_con->real_escape_string($sensorData['identity']); + $thisData = $sensorData['data']; + + // get public key of user + $sql = "SELECT * FROM `apikeys` WHERE id=$thisIdentity"; + + $result = $this->_con->query($sql); + if ($result->num_rows < 1) { + // public key was not found + return array("status"=>404); + } + + // only one row will be returned + $data = $result->fetch_assoc(); + $key = $data['apikey']; + $thisUserId = $data["userid"]; + + // check signature + $signedHash = hash_hmac("sha256", $thisData, $key); + + if ($signedHash !== strtolower($sensorData['signature'])) { + return array("status"=>401); + } + + // signature is valid + + $measvalues = json_decode($thisData, true); + + if (!$measvalues) { + // the format of the data JSON is invalid + return array("status"=>901, "data"=>"malformed data JSON"); + } + + $allSensors = array(); + $validSensors = array(); + $ignoredSensors = array(); + + // find all sensors + foreach ($measvalues as $measvalue) { + $thisSensorId = $this->_con->real_escape_string($measvalue[0]); + if (!in_array($thisSensorId, $allSensors)) { + array_push($allSensors, $thisSensorId); + } + } + + // check if all sensors are valid and belong to the user + foreach ($allSensors as $sensor) { + // check if sensor belongs to user + $sql = "SELECT userid FROM `sensors` WHERE id=\"$sensor\""; + + $result = $this->_con->query($sql); + + if ($result->num_rows < 1) { + // sensor was not found + array_push($ignoredSensors, array($sensor, 404)); + continue; + } + + // only one row will be returned + $data = $result->fetch_assoc(); + + if ($data['userid'] !== $thisUserId) { + // sensor does not belong to user + array_push($ignoredSensors, array($sensor, 401)); + continue; + } + + array_push($validSensors, $sensor); + } + + // iterate through all measvalues + // and insert them into the database if the sensor is valid + foreach ($measvalues as $measvalue) { + if (!in_array($measvalue[0], $validSensors)) { + // if the sensor is not valid -> continue + continue; + } + + $thisSensorId = $this->_con->real_escape_string($measvalue[0]); + $thisMeasvalue = $this->_con->real_escape_string($measvalue[1]); + $thisTimestamp = $this->_con->real_escape_string($measvalue[2]); + + $sql = "INSERT INTO `measvalues` (sensorid,measvalue,timestamp) + VALUES (\"$thisSensorId\", \"$thisMeasvalue\", \"$thisTimestamp\")"; + + $this->_con->query($sql); + } + + if (count($ignoredSensors) > 0) { + return array("status"=>901, "data"=>$ignoredSensors); + } + return array("status"=>200); + } + + // -------------------- + // - Helper functions - + // -------------------- + + /** + * Function to convert a string to hex + * + * @param string $string the string to be converted + * + * @return string + */ + function strToHex($string) + { + $hex = ''; + for ($i=0; $igetLocationData( $_GET['locId'], $_GET['range'], $_GET['maxVals'] ); +} elseif (isset($_POST['submitSensorData'])) { + // sensor data is being submited + $sensorData = json_decode($_POST['submitSensorData'], true); + $ret = $blueweather->processSensorData($sensorData); + $data = $ret; } else { $data = $blueweather->getAllLocations(); } diff --git a/api/submitSensorDataExample.json b/api/submitSensorDataExample.json new file mode 100644 index 0000000..dd06aa5 --- /dev/null +++ b/api/submitSensorDataExample.json @@ -0,0 +1,5 @@ +{ + "identity": 1, + "signature": "0AC7734264ADF2EC0633E37A635A52E6A4B4A588B27B4EA5AA172CF8BB9E762BFA442AFA1ED3B0F1479B580374AD7F28886362766972043E160B6FD02521440CC38845B3FEA45D17C7188B0BDF8C6E23F5E1BB4429D9EB405E2F944301844A000EFD5908D5BAA788918ED136132B7D406313D3C496EDD27514C1C0A2CF0525BCF7F14E70F2FE7A50CDD0E6385166E2FC86A1B6DE05F35634EE3CE73F478B002FB7F994912EB24A8CDFA7835B90C6B2EFDECCD1CEB5F309F165418AD1359D0A02948F85E935D8F527EDEC015E46520DE44F1775AF5CA87AA85FE90DEAD407D859CEE9B8D9E047CBC3E8A95D6216F58610E7A891F0AF9E16E6032D4E0D3E8F3BB0EE2A94F72AD4D05ED15919175A3F2031C14EA6F51B38961CBED14CE9472B9F22A7D89BA48255A2F9AFC3743E77E68C210F006EB1AB4FA75674897EFAFBF82B7D33F78D353EAD67B460CA5EB5FD552D58558CA481AA69880C5E1A6BE90180126E663496BDA5C92B2DE8060C3E353CEC56278F77D063ADB330229BEF875D2D80057A08926FBF61CDBD43DE1CA55B88297FC712F5C776D9D278C22399E84E33BC68E3B7A2F408D7A0C601559B6D53E9B4286E36F12A454041E6EAEA820B9BA456F0415A0FFA726803F9800C9D0FA9E24CFA9DB780758A132ACEAC229EC69577080C179B18344B4EB01709BF1EC209F70739D47ECC391874EC559E6CAE97F21A544F", + "data": "{\"1\": [ [15.0,1575863], [16.0,1575873] ], \"2\": [ [15.0,1575863], [16.0,1575873] ]}" +} \ No newline at end of file diff --git a/css/dashboard.css b/css/dashboard.css index c364135..77c7bf6 100755 --- a/css/dashboard.css +++ b/css/dashboard.css @@ -80,14 +80,6 @@ body { * Navbar */ -.navbar-brand { - padding-top: .75rem; - padding-bottom: .75rem; - font-size: 1rem; - background-color: rgba(0, 0, 0, .25); - box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); -} - .navbar .form-control { padding: .75rem 1rem; border-width: 0; @@ -120,6 +112,10 @@ body { } } +.dropdown-toggle::after { + display:none; +} + /* * */ diff --git a/dashboard.html b/dashboard.html index 52736dc..74e72f2 100755 --- a/dashboard.html +++ b/dashboard.html @@ -26,20 +26,51 @@ -