Add more functions and tests for Application model
This commit is contained in:
parent
87e033f4d8
commit
836df227c6
|
@ -36,7 +36,7 @@ Application.create(data, function(err, data) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Application.register('MyApp', 'My first mobile application', 'rfeng', function (err, result) {
|
Application.register('rfeng', 'MyApp', {description: 'My first mobile application'}, function (err, result) {
|
||||||
console.log(result.toObject());
|
console.log(result.toObject());
|
||||||
|
|
||||||
result.resetKeys(function (err, result) {
|
result.resetKeys(function (err, result) {
|
||||||
|
|
|
@ -20,19 +20,32 @@ Factors to be authorized against:
|
||||||
Class level permissions, for example, Album
|
Class level permissions, for example, Album
|
||||||
* model name: Album
|
* model name: Album
|
||||||
* methods
|
* methods
|
||||||
// blog posts
|
|
||||||
allow: ['owner', 'admin'] to: '*' // allow owner's of posts and admins to do anything
|
|
||||||
allow: '*' to: ['find', 'read'] // allow everyone to read and find
|
|
||||||
// comments
|
|
||||||
allow '*' to: ['find', 'read'] // read aka findById
|
|
||||||
allow 'user' to: ['create']
|
|
||||||
allow ['owner', 'admin'] to: '*'
|
|
||||||
|
|
||||||
// users only section
|
URL/Route level permissions
|
||||||
allow: '*' to: ['find', 'read', 'create']
|
* url pattern
|
||||||
allow: 'owner' to: ['*.destroy', '*.save']
|
* application id
|
||||||
|
* ip addresses
|
||||||
|
* http headers
|
||||||
|
|
||||||
// scopes
|
Map to oAuth 2.0 scopes
|
||||||
|
|
||||||
// URL level permissions
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var ACLSchema = {
|
||||||
|
model: String, // The model name
|
||||||
|
properties: [String], // A list of property names
|
||||||
|
methods: [String], // A list of methods
|
||||||
|
roles: [String], // A list of roles
|
||||||
|
permission: {type: String, enum: ['Allow', 'Deny']}, // Allow/Deny
|
||||||
|
status: String, // Enabled/disabled
|
||||||
|
created: Date,
|
||||||
|
modified: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
// readAccess, writeAccess --> public, userId, role
|
||||||
|
|
||||||
|
module.exports = function(dataSource) {
|
||||||
|
dataSource = dataSource || new require('loopback-data').ModelBuilder();
|
||||||
|
var ACL = dataSource.define('ACL', ACLSchema);
|
||||||
|
return ACL;
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
// Authentication schemes
|
// Authentication schemes
|
||||||
var AuthenticationSchemeSchema = {
|
var AuthenticationSchemeSchema = {
|
||||||
scheme: String, // local, facebook, google, twitter, linkedin, github
|
scheme: String, // local, facebook, google, twitter, linkedin, github
|
||||||
|
@ -33,7 +35,7 @@ var PushNotificationSettingSchema = {
|
||||||
var ApplicationSchema = {
|
var ApplicationSchema = {
|
||||||
|
|
||||||
// Basic information
|
// Basic information
|
||||||
id: {type: String, required: true}, // The id
|
id: {type: String, required: true, generated: true, id: true}, // The id
|
||||||
name: {type: String, required: true}, // The name
|
name: {type: String, required: true}, // The name
|
||||||
description: String, // The description
|
description: String, // The description
|
||||||
icon: String, // The icon image url
|
icon: String, // The icon image url
|
||||||
|
@ -79,9 +81,10 @@ var ApplicationSchema = {
|
||||||
|
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
|
||||||
function generateKey(hmacKey, algorithm) {
|
function generateKey(hmacKey, algorithm, encoding) {
|
||||||
hmacKey = hmacKey || 'loopback';
|
hmacKey = hmacKey || 'loopback';
|
||||||
algorithm = algorithm || 'sha256';
|
algorithm = algorithm || 'sha256';
|
||||||
|
encoding = encoding || 'base64';
|
||||||
var hmac = crypto.createHmac(algorithm, hmacKey);
|
var hmac = crypto.createHmac(algorithm, hmacKey);
|
||||||
var buf = crypto.randomBytes(64);
|
var buf = crypto.randomBytes(64);
|
||||||
hmac.update(buf);
|
hmac.update(buf);
|
||||||
|
@ -114,20 +117,59 @@ module.exports = function (dataSource) {
|
||||||
app.masterKey = generateKey('master');
|
app.masterKey = generateKey('master');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register a new application
|
/**
|
||||||
Application.register = function (name, description, owner, cb) {
|
* Register a new application
|
||||||
Application.create({name: name, description: description, owner: owner}, cb);
|
* @param owner Owner's user id
|
||||||
|
* @param name Name of the application
|
||||||
|
* @param options Other options
|
||||||
|
* @param cb Callback function
|
||||||
|
*/
|
||||||
|
Application.register = function (owner, name, options, cb) {
|
||||||
|
assert(owner, 'owner is required');
|
||||||
|
assert(name, 'name is required');
|
||||||
|
|
||||||
|
if(typeof options === 'function' && !cb) {
|
||||||
|
cb = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
var props = {owner: owner, name: name};
|
||||||
|
for(var p in options) {
|
||||||
|
if(!(p in props)) {
|
||||||
|
props[p] = options[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Application.create(props, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset keys for the application instance
|
||||||
|
* @param cb
|
||||||
|
*/
|
||||||
Application.prototype.resetKeys = function(cb) {
|
Application.prototype.resetKeys = function(cb) {
|
||||||
this.clientKey = generateKey('client');
|
this.clientKey = generateKey('client');
|
||||||
this.javaScriptKey = generateKey('javaScript');
|
this.javaScriptKey = generateKey('javaScript');
|
||||||
this.restApiKey = generateKey('restApi');
|
this.restApiKey = generateKey('restApi');
|
||||||
this.windowsKey = generateKey('windows');
|
this.windowsKey = generateKey('windows');
|
||||||
this.masterKey = generateKey('master');
|
this.masterKey = generateKey('master');
|
||||||
|
this.modified = new Date();
|
||||||
this.save(cb);
|
this.save(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset keys for a given application by the appId
|
||||||
|
* @param appId
|
||||||
|
* @param cb
|
||||||
|
*/
|
||||||
|
Application.resetKeys = function(appId, cb) {
|
||||||
|
Application.findById(appId, function(err, app) {
|
||||||
|
if(err) {
|
||||||
|
cb && cb(err, app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
app.resetKeys(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return Application;
|
return Application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
exports.Model = require('./model');
|
||||||
|
exports.Email = require('./email');
|
||||||
|
exports.User = require('./user');
|
||||||
|
exports.Session = require('./session');
|
||||||
|
|
||||||
exports.Application = require('./application');
|
exports.Application = require('./application');
|
||||||
exports.ACL = require('./acl');
|
exports.ACL = require('./acl');
|
||||||
exports.Role = require('./role');
|
exports.Role = require('./role');
|
||||||
exports.Installation = require('./installation');
|
exports.Installation = require('./installation');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
var models = require('../lib/models');
|
||||||
|
var loopback = require(('../'));
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var dataSource = loopback.createDataSource('db', {connector: loopback.Memory});
|
||||||
|
|
||||||
|
var Application = models.Application(dataSource);
|
||||||
|
|
||||||
|
describe('Application', function () {
|
||||||
|
var registeredApp = null;
|
||||||
|
|
||||||
|
it('Create a new application', function (done) {
|
||||||
|
|
||||||
|
Application.create({owner: 'rfeng', name: 'MyApp1', description: 'My first mobile application'}, function (err, result) {
|
||||||
|
var app = result;
|
||||||
|
assert.equal(app.owner, 'rfeng');
|
||||||
|
assert.equal(app.name, 'MyApp1');
|
||||||
|
assert.equal(app.description, 'My first mobile application');
|
||||||
|
assert(app.clientKey);
|
||||||
|
assert(app.javaScriptKey);
|
||||||
|
assert(app.restApiKey);
|
||||||
|
assert(app.windowsKey);
|
||||||
|
assert(app.masterKey);
|
||||||
|
assert(app.created);
|
||||||
|
assert(app.modified);
|
||||||
|
done(err, result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Register a new application', function (done) {
|
||||||
|
|
||||||
|
Application.register('rfeng', 'MyApp2', {description: 'My second mobile application'}, function (err, result) {
|
||||||
|
var app = result;
|
||||||
|
assert.equal(app.owner, 'rfeng');
|
||||||
|
assert.equal(app.name, 'MyApp2');
|
||||||
|
assert.equal(app.description, 'My second mobile application');
|
||||||
|
assert(app.clientKey);
|
||||||
|
assert(app.javaScriptKey);
|
||||||
|
assert(app.restApiKey);
|
||||||
|
assert(app.windowsKey);
|
||||||
|
assert(app.masterKey);
|
||||||
|
assert(app.created);
|
||||||
|
assert(app.modified);
|
||||||
|
registeredApp = app;
|
||||||
|
done(err, result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Reset keys', function (done) {
|
||||||
|
|
||||||
|
Application.resetKeys(registeredApp.id, function (err, result) {
|
||||||
|
var app = result;
|
||||||
|
assert.equal(app.owner, 'rfeng');
|
||||||
|
assert.equal(app.name, 'MyApp2');
|
||||||
|
assert.equal(app.description, 'My second mobile application');
|
||||||
|
assert(app.clientKey);
|
||||||
|
assert(app.javaScriptKey);
|
||||||
|
assert(app.restApiKey);
|
||||||
|
assert(app.windowsKey);
|
||||||
|
assert(app.masterKey);
|
||||||
|
|
||||||
|
assert(app.clientKey !== registeredApp.clientKey);
|
||||||
|
assert(app.javaScriptKey !== registeredApp.javaScriptKey);
|
||||||
|
assert(app.restApiKey !== registeredApp.restApiKey);
|
||||||
|
assert(app.windowsKey !== registeredApp.windowsKey);
|
||||||
|
assert(app.masterKey !== registeredApp.masterKey);
|
||||||
|
|
||||||
|
assert(app.created);
|
||||||
|
assert(app.modified);
|
||||||
|
done(err, result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue