Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete for products and devices and an initial update for devices #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Environmental Sensor Data Repository.iml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/datastore" />
</content>
Expand Down
63 changes: 16 additions & 47 deletions Environmental Sensor Data Repository.ipr
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,10 @@
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="true" />
<inspection_tool class="CStyleArrayDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NullableProblems" enabled="true" level="ERROR" enabled_by_default="true">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
<inspection_tool class="ObjectEquality" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreEnums" value="true" />
<option name="m_ignoreClassObjects" value="false" />
<option name="m_ignorePrivateConstructors" value="false" />
</inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
<inspection_tool class="SubtractionInCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuspiciousIndentAfterControlStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="VariableNotUsedInsideIf" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</component>
<component name="JavaScriptLibraryMappings">
<file url="file://$PROJECT_DIR$" libraries="{EnvironmentalSensorDataRepository node_modules}" />
<file url="PROJECT" libraries="{EnvironmentalSensorDataRepository node_modules, Superagent, jQuery 1.11.1, mocha-DefinitelyTyped, nconf-DefinitelyTyped, should-DefinitelyTyped}" />
<file url="PROJECT" libraries="{EnvironmentalSensorDataRepository node_modules, Superagent, jQuery 1.11.1}" />
<includedPredefinedLibrary name="Node.js Globals" />
</component>
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
Expand Down Expand Up @@ -158,18 +126,12 @@
<option name="SPACE_BEFORE_COLON" value="true" />
<option name="ARRAY_WRAPPING" value="5" />
</JSON>
<JavaCodeStyleSettings>
<option name="CLASS_NAMES_IN_JAVADOC" value="3" />
</JavaCodeStyleSettings>
<XML>
<option name="XML_ATTRIBUTE_WRAP" value="0" />
<option name="XML_TEXT_WRAP" value="0" />
<option name="XML_KEEP_BLANK_LINES" value="1" />
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
<option name="INDENT_SIZE" value="2" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="rb">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
Expand All @@ -193,6 +155,19 @@
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="Dart">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="BRACE_STYLE" value="3" />
<option name="METHOD_BRACE_STYLE" value="3" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
Expand Down Expand Up @@ -427,9 +402,7 @@
<module fileurl="file://$PROJECT_DIR$/Environmental Sensor Data Repository.iml" filepath="$PROJECT_DIR$/Environmental Sensor Data Repository.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="ProjectRootManager" version="2" />
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="true">
<option name="arguments" value="$FileName$ $FileNameWithoutExtension$.css" />
Expand Down Expand Up @@ -494,7 +467,6 @@
<CLASSES>
<root url="file://$PROJECT_DIR$/node_modules" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
<library name="Generated files" type="javaScript">
Expand All @@ -506,7 +478,6 @@
<CLASSES>
<root url="file://$PROJECT_DIR$/public/js/handlebars_templates.js" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
<library name="jQuery 1.11.1" type="javaScript">
Expand All @@ -519,7 +490,6 @@
<root url="file://$PROJECT_DIR$/public/lib/jquery/jquery-1.11.1.min.js" />
<root url="file://$PROJECT_DIR$/public/lib/jquery/jquery-1.11.1.js" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
<library name="Superagent" type="javaScript">
Expand All @@ -531,7 +501,6 @@
<CLASSES>
<root url="file://$PROJECT_DIR$/public/lib/superagent/superagent.js" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
Expand Down
16 changes: 16 additions & 0 deletions models/Devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ module.exports = function(databaseHelper) {
// now validate
jsonValidator.validate(device, JSON_SCHEMA, function(err1) {
if (err1) {
console.log('* VALIDATION ERROR *');
console.dir(err1);
return callback(new ValidationError(err1));
}

// now that we have the hashed secret, try to insert
databaseHelper.execute("INSERT INTO Devices SET ?", device, function(err2, result) {
if (err2) {
console.log('* INSERTION ERROR *');
console.dir(err2);
return callback(err2);
}

Expand All @@ -106,6 +110,18 @@ module.exports = function(databaseHelper) {
});
};

this.remove = function(deviceId, userId, callback) {
databaseHelper.execute("DELETE FROM Devices WHERE id = "+deviceId+" and userId = "+userId, null, function(err, result) {
if (err) {
return callback(err);
} else {
return callback(null, {
deviceId : deviceId
});
}
});
};

/**
* Tries to find the device with the given <code>deviceId</code> for the given authenticated user and returns it to
* the given <code>callback</code>. If successful, the device is returned as the 2nd argument to the
Expand Down
31 changes: 31 additions & 0 deletions models/Products.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,37 @@ module.exports = function(databaseHelper) {
});
};

this.update = function(productId, userId, body, callback) {
var setstring = "";
console.log("-- update called for product id "+productId+", and userId = "+userId);
//console.dir(body);
for(var k in body){
var v = body[k];
setstring += +"="+v+",";
}
setstring = setstring.substring(0, setstring.length-1);
console.log("setstring is "+setstring);
databaseHelper.execute("UPDATE Products SET "+setstring+" WHERE id = "+productId+" and userId = "+userId, null, function(err, result) {
if (err) {
return callback(err);
} else {
return callback(null, result);
}
});
};

this.remove = function(productId, userId, callback) {
databaseHelper.execute("DELETE FROM Products WHERE id = "+productId+" and userId = "+userId, null, function(err, result) {
if (err) {
return callback(err);
} else {
return callback(null, {
productId : productId
});
}
});
};

/**
* Tries to find the product with the given <code>name</code> and returns it to the given <code>callback</code>. If
* successful, the product is returned as the 2nd argument to the <code>callback</code> function. If unsuccessful,
Expand Down
26 changes: 26 additions & 0 deletions routes/api/devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,32 @@ module.exports = function(DeviceModel, FeedModel) {
});
});

router.delete('/:id',
passport.authenticate('bearer', { session : false }),
function(req, res, next) {
var userId = req.user.id;
var deviceId = req.params.id;
log.debug("Received DELETE for device [" + deviceId + "]");
DeviceModel.findByIdForUser(deviceId, userId, "id,userId", function(err, prod){
//console.log("delete find err = "+err+", prod = "+prod);
//console.dir(prod);
if (err){
console.dir(err);
console.log("Access Denied");
res.jsendClientError("Access denied", err.data);
}
else if (prod.userId != userId) {
console.log("Access Denied, since creator userId is "+prod.userId+" and attempted deletor userId is "+userId);
res.jsendClientError("Access denied", null, httpStatus.FORBIDDEN);
} else {
console.log("Device removed.");
DeviceModel.remove(deviceId, userId, function(result) {
res.jsendSuccess(result);
});
}
});
});

// create a feed for the specified device (specified by device ID)
router.post('/:deviceId/feeds',
passport.authenticate('bearer', { session : false }),
Expand Down
37 changes: 35 additions & 2 deletions routes/api/products.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ module.exports = function(ProductModel, DeviceModel) {
});
});

// update a product
router.put('/:id',
passport.authenticate('bearer', { session : false }),
function(req, res, next) {
var id = req.params.id;
var userId = req.user.id;
var newProduct = req.body;
log.debug("Received PUT from user ID [" + userId + "] to update product [" + (newProduct && newProduct.name ? newProduct.name : null) + "]");
findProductByNameOrId(res, id, 'id', function(product) {
ProductModel.update(id, userId, newProduct, function(err, result){
res.jsendSuccess(result, httpStatus.ACCEPTED);
});
});
});

// find products
router.get('/',
function(req, res, next) {
Expand Down Expand Up @@ -85,6 +100,25 @@ module.exports = function(ProductModel, DeviceModel) {
});
});

// delete a specific product
// TODO: Guard against products being deleted when there are devices that refer to them
router.delete('/:id',
passport.authenticate('bearer', { session : false }),
function(req, res, next) {
var userId = req.user.id;
var productId = req.params.id;
log.debug("Received DELETE for product [" + productId + "]");
ProductModel.findById(productId, "id,creatorUserId", function(err, prod){
if (prod.creatorUserId != userId) {
res.jsendClientError("Access denied", null, httpStatus.FORBIDDEN);
} else {
ProductModel.remove(productId, userId, function(result) {
res.jsendSuccess(result);
});
}
});
});

// create a new device
router.post('/:productNameOrId/devices',
passport.authenticate('bearer', { session : false }),
Expand All @@ -110,11 +144,10 @@ module.exports = function(ProductModel, DeviceModel) {
return res.jsendServerError(message);
}

log.debug("Created new device [" + result.serialNumber + "] with id [" + result.insertId + "] ");

return res.jsendSuccess({
id : result.insertId,
name : result.name,
userId: req.user.id,
serialNumber : result.serialNumber
}, httpStatus.CREATED); // HTTP 201 Created
});
Expand Down
Loading