Skip to content

Commit

Permalink
Re added the NoSQL features to the current Development Branch
Browse files Browse the repository at this point in the history
  • Loading branch information
J12934 committed Jun 17, 2017
1 parent 3f25e44 commit eaa65f1
Show file tree
Hide file tree
Showing 23 changed files with 644 additions and 2 deletions.
6 changes: 5 additions & 1 deletion app/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
padding-top: 0;
}

.label-button{
.label-button {
cursor: pointer;
}

.capitalize {
text-transform: capitalize;
}
7 changes: 7 additions & 0 deletions app/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,10 @@ angular.module('juiceShop').config(['$translateProvider', function ($translatePr
$translateProvider.determinePreferredLanguage()
$translateProvider.fallbackLanguage('en')
}])

angular.module('juiceShop').filter('emailName', function () {
return function (email) {
// Returns only the name of a mail address
return email.split('@')[0].split('.').join(' ')
}
})
20 changes: 20 additions & 0 deletions app/js/controllers/ProductCommentEditController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
angular.module('juiceShop').controller('ProductCommentEditController', [
'$scope',
'$uibModalInstance',
'ProductReviewService',
'comment',
function ($scope, $uibModalInstance, productReviewService, comment) {
'use strict'

$scope.id = comment._id
$scope.message = comment.message

$scope.editComment = function () {
productReviewService.patch({id: $scope.id, message: $scope.message}).success(function (result) {
$uibModalInstance.close($scope.message)
}).error(function (err) {
console.log(err)
$scope.err = err
})
}
}])
69 changes: 68 additions & 1 deletion app/js/controllers/ProductDetailsController.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
angular.module('juiceShop').controller('ProductDetailsController', [
'$scope',
'$sce',
'$q',
'$uibModal',
'ProductService',
'ProductReviewService',
'UserService',
'id',
function ($scope, $sce, $uibModal, productService, id) {
function ($scope, $sce, $q, $uibModal, productService, productReviewService, userService, id) {
'use strict'

productService.get(id).then(function (product) {
Expand All @@ -13,4 +16,68 @@ angular.module('juiceShop').controller('ProductDetailsController', [
}).catch(function (err) {
console.log(err)
})

$q.all([
productService.get(id),
productReviewService.get(id),
userService.whoAmI()
]).then(function (result) {
var product = result[0]
var reviews = result[1].data
var user = result[2]

$scope.product = product
$scope.product.description = $sce.trustAsHtml($scope.product.description)

if (reviews.msg !== undefined && reviews.msg === 'No NoSQL Database availible') {
$scope.reviewsDisabled = true
} else {
$scope.reviewsDisabled = false
$scope.productReviews = reviews.data
}
console.log('user', user)
if (user === undefined || user.email === undefined) {
$scope.author = 'Anonymous'
} else {
$scope.author = user.email
}
},
function (err) {
console.log(err)
}
)

$scope.addComment = function () {
var review = { message: $scope.message, author: $scope.author }
$scope.productReviews.push(review)
productReviewService.create(id, review)
}

$scope.refreshComments = function () {
productReviewService.get(id).then(function (result) {
$scope.productReviews = result.data.data
})
}

$scope.editComment = function (comment) {
$uibModal.open({
templateUrl: 'views/ProductCommentEdit.html',
controller: 'ProductCommentEditController',
bindings: {
resolve: '<',
close: '&',
dismiss: '&'
},
size: 'lg',
resolve: {
comment: function () {
return comment
}
}
}).result.then(function (value) {
$scope.refreshComments()
}, function () {
console.log('Cancelled')
})
}
}])
23 changes: 23 additions & 0 deletions app/js/services/ProductReviewService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
angular.module('juiceShop').factory('ProductReviewService', ['$http', function ($http) {
'use strict'

var host = '/rest/product'

function get (id) {
return $http.get(host + '/' + id + '/reviews')
}

function create (id, review) {
return $http.put(host + '/' + id + '/reviews', review)
}

function patch (review) {
return $http.patch(host + '/reviews', review)
}

return {
get: get,
create: create,
patch: patch
}
}])
36 changes: 36 additions & 0 deletions app/views/ProductCommentEdit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="modal-header">
<h3 class="modal-title">Edit Comment</h3>
</div>
<div class="modal-body">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form role="form" name="form" novalidate>
<div class="form-group">
<label for="feedbackComment" translate="LABEL_COMMENT"></label>
<textarea class="form-control input-sm"
id="feedbackComment"
ng-model="message"
name="feedbackComment"
required
ng-minlength="5"
ng-maxlength="160"></textarea>
</div>
<div class="form-group">
<button type="submit" ng-click="editComment()" id="submitButton" class="btn btn-primary"
ng-disabled="form.$invalid" ng-click="save()">
<i class="fa fa-send fa-lg"></i>
<span translate="BTN_SUBMIT"></span>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" ng-click="$close()">
<i class="fa fa-arrow-circle-left fa-lg"></i>
<span translate="BTN_CLOSE"></span>
</button>
</div>
24 changes: 24 additions & 0 deletions app/views/ProductDetail.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ <h3 class="modal-title"><span translate="LABEL_PRODUCT"></span> #{{product.id}}<
<p><img src="/public/images/products/{{product.image}}" class="img-responsive img-thumbnail"/></p>
</div>
</div>
<div class="row" ng-hide="reviewsDisabled">
<div class="col-md-12">
<strong translate="LABEL_COMMENT"></strong>
<p ng-show="productReviews.length === 0">No Comments yet.</p>
<blockquote data-ng-repeat="review in productReviews">
<p>{{ review.message }}</p>

<button ng-show="review.author !== 'Anonymous' && review.author === author" ng-click="editComment(review)" type="button" name="edit" class="btn btn-default"><i class="fa fa-pencil"></i> Edit</button>

<footer class="capitalize">{{ review.author | emailName }}</footer>
</blockquote>
</div>
<div class="col-md-12">
<form role="form" name="form" novalidate>
<div class="form-group">
<label for="feedbackComment" translate="LABEL_COMMENT"></label>
<textarea class="form-control input-sm" id="feedbackComment" ng-model="message" name="feedbackComment" required ng-minlength="5" ng-maxlength="160"></textarea>
</div>
<div class="form-group">
<button type="submit" ng-click="addComment()" id="submitButton" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="save()"><i class="fa fa-send fa-lg"></i> <span translate="BTN_SUBMIT"></span></button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="modal-footer">
Expand Down
28 changes: 28 additions & 0 deletions data/datacreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,34 @@ function createChallenges () {
}).success(function (challenge) {
challenges.jwtSecretChallenge = challenge
})
models.Challenge.create({
name: 'NoSql Command Injection',
category: 'NoSQL Injections',
description: 'Let the server sleep for some time. It has done more then enough for you.',
// TODO See if hint are required
difficulty: 2,
solved: false
}).success(function (challenge) {
challenges.noSqlCommandChallenge = challenge
})
models.Challenge.create({
name: 'NoSql Injection',
category: 'NoSQL Injections',
description: 'Change more than one comment for a product at a time.',
difficulty: 2,
solved: false
}).success(function (challenge) {
challenges.noSqlInjectionChallenge = challenge
})
models.Challenge.create({
name: 'NoSql Direct Access',
category: 'NoSQL Injections',
description: 'Write any Message in the Secrets Collection of the MongoDB',
difficulty: 4,
solved: false
}).success(function (challenge) {
challenges.noSqlDirectAccess = challenge
})
}

function createUsers () {
Expand Down
2 changes: 2 additions & 0 deletions mongoose/data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
34 changes: 34 additions & 0 deletions mongoose/datacreator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
var Review = require('./reviews').Review
var Secret = require('./secrets').Secret

module.exports = function datacreator () {
Review.remove().then(function () {
console.log('Emptied the review collection (NoSql Database)')
}, function () {
console.log('Error while trying to empty the review collection (NoSql Database)')
})

Secret.remove().then(function () {
console.log('Emptied the secret collection (NoSql Database)')
}, function () {
console.log('Error while trying to empty the review collection (NoSql Database)')
})

// resetting the counter which is detemening the models id on each startup
Review.resetCount(function (err, count) {
if (err) {
console.log(err)
} else {
console.log('Reseted the counter for the review collection')
}
})

new Review({ product: 1, message: 'One of my favorites!', author: '[email protected]' }).save()
new Review({ product: 17, message: 'Has a nice flavor!', author: '[email protected]' }).save()
new Review({ product: 3, message: 'I bought it, would buy again. 5/7', author: '[email protected]' }).save()
new Review({ product: 14, message: 'Fresh out of a replicator.', author: '[email protected]' }).save()
new Review({ product: 6, message: 'Fry liked it too.', author: '[email protected]' }).save()
new Review({ product: 19, message: 'A vital ingredient for a succesful playthrough.', author: '[email protected]' }).save()

new Secret({ message: 'This is a totaly safe place to store data because no user could possibly access it.' }).save()
}
23 changes: 23 additions & 0 deletions mongoose/directAccessCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var connection = require('mongoose').connection
var Secret = require('./secrets').Secret

var utils = require('../lib/utils')
var challenges = require('../data/datacache').challenges

module.exports = function (req, res, next) {
if (connection.readyState === 1) {
Secret.find({}).then(function (result) {
if (result.length > 1) {
if (utils.notSolved(challenges.noSqlDirectAccess)) {
utils.solve(challenges.noSqlDirectAccess)
}
}
}, function (err) {
if (err) {
console.log('Could not reach MongoDB to check for direct access...')
}
})
}

next()
}
62 changes: 62 additions & 0 deletions mongoose/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
var mongoose = require('mongoose')
var autoIncrement = require('mongoose-auto-increment')

var path = require('path')
var mongod = require('mongodb-prebuilt')

var dbPath = path.join(__dirname, 'data')

var mongoUrl = 'mongodb://localhost:1337/test'
var retriesLeft = 5

var connectWithRetry = function () {
return mongoose.connect(mongoUrl).catch(function () {
console.error('Failed to connect to mongo on startup - retrying in 1 sec')
console.error('Retires left:', retriesLeft)
if ((retriesLeft--) > 0) {
setTimeout(connectWithRetry, 1000)
}
})
}

mongod.start_server({
args: {
storageEngine: 'ephemeralForTest',
bind_ip: '127.0.0.1',
port: 1337,
dbpath: dbPath
},
auto_shutdown: true
},
function (err) {
if (err) {
console.log('mongod didnt start:', err)
console.log('Try reinstalling your node dependencies.')
console.log('The right mongodb binaries might be missing.')
console.log('If that does not help check the mongo documentation for the error code above.')
} else {
console.log('mongod is started')
}
})

mongoose.Promise = global.Promise

// if the connection failed the server will retry retriesLeft times in case the database didnt start in time
// this code can't be placed in the mongod.start_server callback due to an bug which will trap
// the whole server process in an infinite loop :(
connectWithRetry()

var db = mongoose.connection
// using a autoincrement plugin to enable attacks using $gt, $ne ...
autoIncrement.initialize(db)

db.on('open', function () {
console.log('Connection to MongoDB established!')
})

db.on('error', function () {
console.log('Could not establish connection to MongoDB!')
})

// writing initial data to the collection
db.once('open', require('./datacreator'))
16 changes: 16 additions & 0 deletions mongoose/reviews.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var mongoose = require('mongoose')
var autoIncrement = require('mongoose-auto-increment')

var ReviewSchema = new mongoose.Schema({
product: Number,
message: String,
author: String
}, {safe: false})

ReviewSchema.plugin(autoIncrement.plugin, 'Review')

var Review = mongoose.model('Review', ReviewSchema)

module.exports = {
Review: Review
}
Loading

0 comments on commit eaa65f1

Please sign in to comment.