Merge branch 'release/1.5.2' into production
This commit is contained in:
commit
b1787e0b94
|
@ -2,6 +2,8 @@
|
|||
"title": "LoopBack Documentation",
|
||||
"content": [
|
||||
"lib/application.js",
|
||||
{"title": "LoopBack", "depth": 3},
|
||||
"lib/loopback.js",
|
||||
{"title": "Middleware", "depth": 3},
|
||||
"lib/middleware/token.js",
|
||||
"lib/models/access-token.js",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
|
@ -15,7 +15,15 @@ var express = require('express')
|
|||
, i8n = require('inflection');
|
||||
|
||||
/**
|
||||
* Expose `createApplication()`.
|
||||
* `loopback` is the main entry for LoopBack core module. It provides static
|
||||
* methods to create models and data sources. The module itself is a function
|
||||
* that creates loopback `app`. For example,
|
||||
*
|
||||
*
|
||||
* ```js
|
||||
* var loopback = require('loopback');
|
||||
* var app = loopback();
|
||||
* ```
|
||||
*/
|
||||
|
||||
var loopback = exports = module.exports = createApplication;
|
||||
|
@ -47,7 +55,7 @@ function createApplication() {
|
|||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Expose express.middleware as loopback.*
|
||||
* for example `loopback.errorHandler` etc.
|
||||
*/
|
||||
|
@ -59,7 +67,7 @@ for (var key in express) {
|
|||
, Object.getOwnPropertyDescriptor(express, key));
|
||||
}
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Expose additional loopback middleware
|
||||
* for example `loopback.configure` etc.
|
||||
*/
|
||||
|
@ -73,7 +81,7 @@ fs
|
|||
loopback[m.replace(/\.js$/, '')] = require('./middleware/' + m);
|
||||
});
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Error handler title
|
||||
*/
|
||||
|
||||
|
@ -187,8 +195,9 @@ loopback.memory = function (name) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loop up a model class by name
|
||||
* Look up a model class by name from all models created by loopback.createModel()
|
||||
* @param {String} modelName The model name
|
||||
* @return {Model} The model class
|
||||
*/
|
||||
loopback.getModel = function(modelName) {
|
||||
return loopback.Model.modelBuilder.models[modelName];
|
||||
|
@ -196,6 +205,9 @@ loopback.getModel = function(modelName) {
|
|||
|
||||
/**
|
||||
* Set the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @param {Object|DataSource} dataSource The data source settings or instance
|
||||
* @return {DataSource} The data source instance
|
||||
*/
|
||||
|
||||
loopback.setDefaultDataSourceForType = function(type, dataSource) {
|
||||
|
@ -211,6 +223,8 @@ loopback.setDefaultDataSourceForType = function(type, dataSource) {
|
|||
|
||||
/**
|
||||
* Get the default `dataSource` for a given `type`.
|
||||
* @param {String} type The datasource type
|
||||
* @return {DataSource} The data source instance
|
||||
*/
|
||||
|
||||
loopback.getDefaultDataSourceForType = function(type) {
|
||||
|
@ -261,7 +275,7 @@ loopback.RoleMapping = require('./models/role').RoleMapping;
|
|||
loopback.ACL = require('./models/acl').ACL;
|
||||
loopback.Scope = require('./models/acl').Scope;
|
||||
|
||||
/**
|
||||
/*!
|
||||
* Automatically attach these models to dataSources
|
||||
*/
|
||||
|
||||
|
|
|
@ -294,9 +294,9 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
|||
|
||||
var req = new AccessRequest(model, property, accessType);
|
||||
|
||||
var acls = ACL.getStaticACLs(model, property);
|
||||
var acls = this.getStaticACLs(model, property);
|
||||
|
||||
var resolved = ACL.resolvePermission(acls, req);
|
||||
var resolved = this.resolvePermission(acls, req);
|
||||
|
||||
if(resolved && resolved.permission === ACL.DENY) {
|
||||
debug('Permission denied by statically resolved permission');
|
||||
|
@ -307,7 +307,8 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
|||
return;
|
||||
}
|
||||
|
||||
ACL.find({where: {principalType: principalType, principalId: principalId,
|
||||
var self = this;
|
||||
this.find({where: {principalType: principalType, principalId: principalId,
|
||||
model: model, property: propertyQuery, accessType: accessTypeQuery}},
|
||||
function (err, dynACLs) {
|
||||
if (err) {
|
||||
|
@ -315,7 +316,7 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
|||
return;
|
||||
}
|
||||
acls = acls.concat(dynACLs);
|
||||
resolved = ACL.resolvePermission(acls, req);
|
||||
resolved = self.resolvePermission(acls, req);
|
||||
if(resolved && resolved.permission === ACL.DEFAULT) {
|
||||
var modelClass = loopback.getModel(model);
|
||||
resolved.permission = (modelClass && modelClass.settings.defaultPermission) || ACL.ALLOW;
|
||||
|
@ -326,7 +327,7 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
|||
|
||||
ACL.prototype.debug = function() {
|
||||
if(debug.enabled) {
|
||||
debug('---ACL---')
|
||||
debug('---ACL---');
|
||||
debug('model %s', this.model);
|
||||
debug('property %s', this.property);
|
||||
debug('principalType %s', this.principalType);
|
||||
|
@ -361,9 +362,10 @@ ACL.checkAccess = function (context, callback) {
|
|||
var req = new AccessRequest(model.modelName, property, accessType);
|
||||
|
||||
var effectiveACLs = [];
|
||||
var staticACLs = ACL.getStaticACLs(model.modelName, property);
|
||||
var staticACLs = this.getStaticACLs(model.modelName, property);
|
||||
|
||||
ACL.find({where: {model: model.modelName, property: propertyQuery,
|
||||
var self = this;
|
||||
this.find({where: {model: model.modelName, property: propertyQuery,
|
||||
accessType: accessTypeQuery}}, function (err, acls) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
|
@ -403,7 +405,10 @@ ACL.checkAccess = function (context, callback) {
|
|||
callback && callback(err, null);
|
||||
return;
|
||||
}
|
||||
var resolved = ACL.resolvePermission(effectiveACLs, req);
|
||||
var resolved = self.resolvePermission(effectiveACLs, req);
|
||||
if(resolved && resolved.permission === ACL.DEFAULT) {
|
||||
resolved.permission = (model && model.settings.defaultPermission) || ACL.ALLOW;
|
||||
}
|
||||
debug('checkAccess() returns: %j', resolved);
|
||||
callback && callback(null, resolved);
|
||||
});
|
||||
|
@ -437,7 +442,7 @@ ACL.checkAccessForToken = function (token, model, modelId, method, callback) {
|
|||
|
||||
context.debug();
|
||||
|
||||
ACL.checkAccess(context, function (err, access) {
|
||||
this.checkAccess(context, function (err, access) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
return;
|
||||
|
|
|
@ -6,7 +6,6 @@ exports.AccessToken = require('./access-token');
|
|||
exports.Application = require('./application');
|
||||
exports.ACL = require('./acl');
|
||||
exports.Role = require('./role');
|
||||
exports.Installation = require('./installation');
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ RoleMapping.ROLE = 'ROLE';
|
|||
*/
|
||||
RoleMapping.prototype.application = function (callback) {
|
||||
if (this.principalType === RoleMapping.APPLICATION) {
|
||||
loopback.Application.findById(this.principalId, callback);
|
||||
var applicationModel = this.constructor.Application || loopback.Application;
|
||||
applicationModel.findById(this.principalId, callback);
|
||||
} else {
|
||||
process.nextTick(function () {
|
||||
callback && callback(null, null);
|
||||
|
@ -69,6 +70,7 @@ RoleMapping.prototype.application = function (callback) {
|
|||
*/
|
||||
RoleMapping.prototype.user = function (callback) {
|
||||
if (this.principalType === RoleMapping.USER) {
|
||||
var userModel = this.constructor.User || loopback.User;
|
||||
loopback.User.findById(this.principalId, callback);
|
||||
} else {
|
||||
process.nextTick(function () {
|
||||
|
@ -85,7 +87,8 @@ RoleMapping.prototype.user = function (callback) {
|
|||
*/
|
||||
RoleMapping.prototype.childRole = function (callback) {
|
||||
if (this.principalType === RoleMapping.ROLE) {
|
||||
loopback.User.findById(this.principalId, callback);
|
||||
var roleModel = this.constructor.Role || Role;
|
||||
roleModel.findById(this.principalId, callback);
|
||||
} else {
|
||||
process.nextTick(function () {
|
||||
callback && callback(null, null);
|
||||
|
@ -107,10 +110,13 @@ var Role = loopback.createModel('Role', RoleSchema, {
|
|||
}
|
||||
});
|
||||
|
||||
Role.RoleMapping = RoleMapping;
|
||||
|
||||
// Set up the connection to users/applications/roles once the model
|
||||
Role.once('dataSourceAttached', function () {
|
||||
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||
Role.prototype.users = function (callback) {
|
||||
RoleMapping.find({where: {roleId: this.id,
|
||||
roleMappingModel.find({where: {roleId: this.id,
|
||||
principalType: RoleMapping.USER}}, function (err, mappings) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
|
@ -123,7 +129,7 @@ Role.once('dataSourceAttached', function () {
|
|||
};
|
||||
|
||||
Role.prototype.applications = function (callback) {
|
||||
RoleMapping.find({where: {roleId: this.id,
|
||||
roleMappingModel.find({where: {roleId: this.id,
|
||||
principalType: RoleMapping.APPLICATION}}, function (err, mappings) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
|
@ -136,7 +142,7 @@ Role.once('dataSourceAttached', function () {
|
|||
};
|
||||
|
||||
Role.prototype.roles = function (callback) {
|
||||
RoleMapping.find({where: {roleId: this.id,
|
||||
roleMappingModel.find({where: {roleId: this.id,
|
||||
principalType: RoleMapping.ROLE}}, function (err, mappings) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
|
@ -330,7 +336,8 @@ Role.isInRole = function (role, context, callback) {
|
|||
return;
|
||||
}
|
||||
|
||||
Role.findOne({where: {name: role}}, function (err, result) {
|
||||
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||
this.findOne({where: {name: role}}, function (err, result) {
|
||||
if (err) {
|
||||
callback && callback(err);
|
||||
return;
|
||||
|
@ -346,7 +353,7 @@ Role.isInRole = function (role, context, callback) {
|
|||
var principalType = p.type || undefined;
|
||||
var principalId = p.id || undefined;
|
||||
if (principalType && principalId) {
|
||||
RoleMapping.findOne({where: {roleId: result.id,
|
||||
roleMappingModel.findOne({where: {roleId: result.id,
|
||||
principalType: principalType, principalId: principalId}},
|
||||
function (err, result) {
|
||||
debug('Role mapping found: %j', result);
|
||||
|
@ -388,11 +395,12 @@ Role.getRoles = function (context, callback) {
|
|||
}
|
||||
};
|
||||
|
||||
var self = this;
|
||||
// Check against the smart roles
|
||||
var inRoleTasks = [];
|
||||
Object.keys(Role.resolvers).forEach(function (role) {
|
||||
inRoleTasks.push(function (done) {
|
||||
Role.isInRole(role, context, function (err, inRole) {
|
||||
self.isInRole(role, context, function (err, inRole) {
|
||||
if (!err && inRole) {
|
||||
addRole(role);
|
||||
done();
|
||||
|
@ -403,6 +411,7 @@ Role.getRoles = function (context, callback) {
|
|||
});
|
||||
});
|
||||
|
||||
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||
context.principals.forEach(function (p) {
|
||||
// Check against the role mappings
|
||||
var principalType = p.type || undefined;
|
||||
|
@ -416,7 +425,7 @@ Role.getRoles = function (context, callback) {
|
|||
if (principalType && principalId) {
|
||||
// Please find() treat undefined matches all values
|
||||
inRoleTasks.push(function (done) {
|
||||
RoleMapping.find({where: {principalType: principalType,
|
||||
roleMappingModel.find({where: {principalType: principalType,
|
||||
principalId: principalId}}, function (err, mappings) {
|
||||
debug('Role mappings found: %s %j', err, mappings);
|
||||
if (err) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"Platform",
|
||||
"mBaaS"
|
||||
],
|
||||
"version": "1.5.1",
|
||||
"version": "1.5.2",
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
|
|
|
@ -213,7 +213,8 @@ describe('security ACLs', function () {
|
|||
}, {
|
||||
acls: [
|
||||
{principalType: ACL.USER, principalId: userId, accessType: ACL.ALL, permission: ACL.ALLOW}
|
||||
]
|
||||
],
|
||||
defaultPermission: 'DENY'
|
||||
});
|
||||
|
||||
ACL.create({principalType: ACL.USER, principalId: userId, model: 'Customer', property: ACL.ALL,
|
||||
|
@ -243,6 +244,18 @@ describe('security ACLs', function () {
|
|||
}, function(err, access) {
|
||||
assert(!err && access.permission === ACL.ALLOW);
|
||||
});
|
||||
|
||||
ACL.checkAccess({
|
||||
principals: [
|
||||
{type: ACL.ROLE, id: Role.EVERYONE}
|
||||
],
|
||||
model: 'Customer',
|
||||
property: 'name',
|
||||
accessType: ACL.READ
|
||||
}, function(err, access) {
|
||||
assert(!err && access.permission === ACL.DENY);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue