Skip to content

Commit afa614f

Browse files
committed
added and fixed tests
1 parent a91071f commit afa614f

File tree

6 files changed

+229
-9
lines changed

6 files changed

+229
-9
lines changed

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test/
2+
README.md

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
language: node_js
2+
node_js:
3+
- "6.11"
4+
script: npm test

index.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@ module.exports = function (schema) {
2222
update(this, next);
2323
});
2424

25+
schema.query.setAuthLevel = function(authLevel) {
26+
this.options.authLevel = authLevel;
27+
return this;
28+
};
29+
2530
function hasPermission(vm, action) {
26-
if (!vm.schema.permissions[vm.options.authLevel]) {
27-
return false;
28-
}
2931
var authLevel = vm.options.authLevel;
3032

3133
if (Array.isArray(authLevel)) {
3234
return authLevel.filter(function (level) {
33-
return !!vm.schema.permissions[level][action];
35+
return vm.schema.permissions[level] && !!vm.schema.permissions[level][action];
3436
}).length > 0;
3537
} else {
36-
return vm.schema.permissions[authLevel][action];
38+
return vm.schema.permissions[authLevel] && vm.schema.permissions[authLevel][action];
3739
}
3840
}
3941

@@ -92,7 +94,7 @@ module.exports = function (schema) {
9294
var vm = schema;
9395
var authorizedFields = [];
9496
if (authOptionPresent(vm)) {
95-
if (vm.schema.permissions[vm.options.authLevel] && vm.schema.permissions[vm.options.authLevel].read) {
97+
if (hasPermission(vm, 'read')) {
9698
//check to see if the group has any read permissions and add to the authorizedFields array
9799
authorizedFields = authorizedFields.concat(getAuthorizedFields(vm, 'read'));
98100
}
@@ -136,7 +138,7 @@ module.exports = function (schema) {
136138
reason: 'you do not have access to the following permissions: [save]'
137139
});
138140
}
139-
if (vm.schema.permissions[vm.options.authLevel] && vm.schema.permissions[vm.options.authLevel].write) {
141+
if (hasPermission(vm, 'write')) {
140142
//check to see if group has any write permissions and add to the authorizedFields array
141143
authorizedFields = authorizedFields.concat(getAuthorizedFields(vm, 'write'));
142144
}
@@ -162,7 +164,7 @@ module.exports = function (schema) {
162164
} else {
163165

164166
//Detect which fields can be returned if 'new: true' is set
165-
if (vm.schema.permissions[vm.options.authLevel] && vm.schema.permissions[vm.options.authLevel].read) {
167+
if (hasPermission(vm, 'read')) {
166168

167169
//check to see if the group has any read permissions and add to the authorizedFields array
168170
authorizedReturnFields = authorizedReturnFields.concat(getAuthorizedFields(vm, 'read'));

package.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Data level authorization for Mongoose",
55
"main": "index.js",
66
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1"
7+
"test": "nodeunit test/*.test.js"
88
},
99
"repository": {
1010
"type": "git",
@@ -33,5 +33,15 @@
3333
"homepage": "https://github.com/352Media/mongoose-authorization#readme",
3434
"dependencies": {
3535
"lodash": "^3.10.1"
36+
},
37+
"peerDependencies": {
38+
"mongoose": "^4.5.0"
39+
},
40+
"devDependencies": {
41+
"async": "^2.6.0",
42+
"mongodb": "^3.0.1",
43+
"mongoose": "^4.13.9",
44+
"nodeunit": "^0.11.2",
45+
"uuid": "^3.2.1"
3646
}
3747
}

test/index.test.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
'use strict';
2+
3+
var mongoose = require('mongoose');
4+
var lodash = require('lodash');
5+
var async = require('async');
6+
var User = require('./user.schema');
7+
8+
var dbUri = 'mongodb://localhost:27017/mongooseAuthorization';
9+
10+
var userSeed = {
11+
email: 'foo@test.com',
12+
first_name: 'Archer',
13+
last_name: 'Sterling',
14+
password: 'guest',
15+
last_login_date: new Date(),
16+
login_attempts: 1,
17+
avatar: 'http://someurl.com'
18+
};
19+
20+
var userValues;
21+
22+
var permissions = User.schema.permissions;
23+
24+
var levelPermissions = Object.assign({}, permissions);
25+
26+
delete levelPermissions.defaults;
27+
28+
mongoose.connect(dbUri);
29+
mongoose.connection.on('error', function(err) {
30+
console.error('Failed to connect to mongo at ' + dbUri);
31+
console.error('MongoDB connection error: ' + err);
32+
throw err;
33+
});
34+
35+
module.exports = {
36+
setUp: function(callback) {
37+
User.remove({}, function(error) {
38+
if (error) {
39+
callback(error);
40+
}
41+
42+
User.create(userSeed, function(error, user) {
43+
userValues = user.toJSON();
44+
callback(error);
45+
});
46+
});
47+
},
48+
49+
'should return everything for no authLevel': function(test) {
50+
User.findOne({})
51+
.exec()
52+
.then(function(user) {
53+
test.ok(user);
54+
55+
Object.keys(userValues).forEach(function(pathKey) {
56+
test.deepEqual(user[pathKey], userValues[pathKey]);
57+
});
58+
59+
test.done();
60+
}).catch(test.done);
61+
},
62+
63+
'should only return projection for authLevel merged with defaults': function(test) {
64+
65+
function testAuthLevel(fields, level, callback) {
66+
fields = fields.read.concat(permissions.defaults.read);
67+
User.findOne({}, null, {authLevel: level})
68+
.exec()
69+
.then(function(user) {
70+
test.ok(user);
71+
72+
fields.forEach(function(field) {
73+
test.deepEqual(user[field], userValues[field]);
74+
});
75+
76+
var returnedKeys = Object.keys(user.toJSON());
77+
test.equal(lodash.difference(returnedKeys, fields).length, 0);
78+
79+
callback();
80+
}).catch(callback);
81+
}
82+
83+
async.forEachOf(levelPermissions, testAuthLevel, test.done);
84+
},
85+
86+
'should work with query extension function': function(test) {
87+
88+
function testAuthLevel(fields, level, callback) {
89+
fields = fields.read.concat(permissions.defaults.read);
90+
User.findOne({})
91+
.setAuthLevel(level)
92+
.exec()
93+
.then(function(user) {
94+
test.ok(user);
95+
96+
fields.forEach(function(field) {
97+
test.deepEqual(user[field], userValues[field]);
98+
});
99+
100+
var returnedKeys = Object.keys(user.toJSON());
101+
test.equal(lodash.difference(returnedKeys, fields).length, 0);
102+
103+
callback();
104+
}).catch(callback);
105+
}
106+
107+
async.forEachOf(levelPermissions, testAuthLevel, test.done);
108+
},
109+
110+
'should merge authLevels if they are arrays': function(test) {
111+
User.findOne({}, null, {authLevel: ['admin', 'owner']})
112+
.exec()
113+
.then(function(user) {
114+
test.ok(user);
115+
116+
var fields = levelPermissions.admin.read.concat(
117+
levelPermissions.owner.read
118+
).concat(permissions.defaults.read);
119+
120+
fields.forEach(function(field) {
121+
console.log(field, ' : ', user[field]);
122+
test.deepEqual(user[field], userValues[field]);
123+
});
124+
125+
var returnedKeys = Object.keys(user.toJSON());
126+
test.equal(lodash.difference(returnedKeys, fields).length, 0);
127+
128+
test.done();
129+
}).catch(test.done);
130+
}
131+
};
132+

test/user.schema.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
var mongoose = require('mongoose');
4+
var uuid = require('uuid');
5+
6+
var userSchema = new mongoose.Schema({
7+
user_id: {
8+
type: String,
9+
required: true,
10+
unique: true,
11+
default: uuid.v4()
12+
},
13+
email: {
14+
type: String,
15+
required: true,
16+
unique: true
17+
},
18+
first_name: {
19+
type: String,
20+
required: true
21+
},
22+
last_name: {
23+
type: String,
24+
required: true
25+
},
26+
password: String,
27+
login_attempts: {
28+
type: Number,
29+
default: 0
30+
},
31+
avatar: {
32+
type: String
33+
},
34+
last_login_date: {
35+
type: Date
36+
},
37+
status: {
38+
type: String,
39+
required: true,
40+
default: 'active'
41+
}
42+
});
43+
44+
/*
45+
* Make sure you add this before compiling your model
46+
*/
47+
userSchema.permissions = {
48+
defaults: {
49+
read: ['_id', 'user_id', 'email', 'first_name', 'last_name', 'avatar']
50+
},
51+
admin: {
52+
read: ['status'],
53+
write: ['status'],
54+
save: true
55+
},
56+
owner: {
57+
read: ['last_login_date'],
58+
write: ['email', 'first_name', 'last_name', 'avatar'],
59+
remove: true
60+
}
61+
};
62+
63+
userSchema.plugin(require('../'));
64+
65+
/*
66+
* Compile model
67+
*/
68+
var users = mongoose.model('users', userSchema);
69+
70+
module.exports = users;

0 commit comments

Comments
 (0)