Merge pull request #1323 from strongloop/feature/autoconfigure-auth-models

Auto-configure models required by `app.enableAuth`
This commit is contained in:
Miroslav Bajtoš 2015-06-02 17:27:39 +02:00
commit 70ca7c51b4
4 changed files with 77 additions and 1 deletions

View File

@ -291,10 +291,37 @@ app.dataSources = app.datasources = {};
* Enable app wide authentication.
*/
app.enableAuth = function() {
app.enableAuth = function(options) {
var AUTH_MODELS = ['User', 'AccessToken', 'ACL', 'Role', 'RoleMapping'];
var remotes = this.remotes();
var app = this;
if (options && options.dataSource) {
var appModels = app.registry.modelBuilder.models;
AUTH_MODELS.forEach(function(m) {
var Model = app.registry.findModel(m);
if (!Model) {
throw new Error(
'Authentication requires model ' + m + ' to be defined.');
}
if (m.dataSource || m.app) return;
for (var name in appModels) {
var candidate = appModels[name];
var isSubclass = candidate.prototype instanceof Model;
var isAttached = !!candidate.dataSource || !!candidate.app;
if (isSubclass && isAttached) return;
}
app.model(Model, {
dataSource: options.dataSource,
public: m === 'User'
});
});
}
remotes.authorization = function(ctx, next) {
var method = ctx.method;
var req = ctx.req;

View File

@ -99,6 +99,9 @@ function createApplication(options) {
if (loopback.localRegistry || options && options.localRegistry === true) {
// setup the app registry
var registry = app.registry = new Registry();
if (options && options.loadBuiltinModels === true) {
require('./builtin-models')(registry);
}
} else {
app.registry = loopback.registry;
}

View File

@ -796,6 +796,34 @@ describe('app', function() {
app.enableAuth();
expect(app.isAuthEnabled).to.equal(true);
});
it('auto-configures required models to provided dataSource', function() {
var AUTH_MODELS = ['User', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
require('../lib/builtin-models')(app.registry);
var db = app.dataSource('db', { connector: 'memory' });
app.enableAuth({ dataSource: 'db' });
expect(Object.keys(app.models)).to.include.members(AUTH_MODELS);
AUTH_MODELS.forEach(function(m) {
var Model = app.models[m];
expect(Model.dataSource, m + '.dataSource').to.equal(db);
expect(Model.shared, m + '.shared').to.equal(m === 'User');
});
});
it('detects already configured subclass of a required model', function() {
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
var db = app.dataSource('db', { connector: 'memory' });
var Customer = app.registry.createModel('Customer', {}, { base: 'User' });
app.model(Customer, { dataSource: 'db' });
app.enableAuth({ dataSource: 'db' });
expect(Object.keys(app.models)).to.not.include('User');
});
});
describe.onServer('app.get(\'/\', loopback.status())', function() {

View File

@ -115,6 +115,24 @@ describe('loopback', function() {
});
});
describe('loopback(options)', function() {
it('supports localRegistry:true', function() {
var app = loopback({ localRegistry: true });
expect(app.registry).to.not.equal(loopback.registry);
});
it('does not load builtin models into the local registry', function() {
var app = loopback({ localRegistry: true });
expect(app.registry.findModel('User')).to.equal(undefined);
});
it('supports loadBuiltinModels:true', function() {
var app = loopback({ localRegistry: true, loadBuiltinModels: true });
expect(app.registry.findModel('User'))
.to.have.property('modelName', 'User');
});
});
describe('loopback.createDataSource(options)', function() {
it('Create a data source with a connector.', function() {
var dataSource = loopback.createDataSource({