Skip to content

Commit

Permalink
WIP - access control step1
Browse files Browse the repository at this point in the history
  • Loading branch information
Miroslav Bajtoš committed Apr 3, 2015
1 parent 5a51c7f commit 6f0cd70
Show file tree
Hide file tree
Showing 4 changed files with 504 additions and 69 deletions.
129 changes: 61 additions & 68 deletions lib/persisted-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,73 +644,64 @@ module.exports = function(registry) {
http: {verb: 'put', path: '/'}
});

if (options.trackChanges) {
setRemoting(PersistedModel, 'diff', {
description: 'Get a set of deltas and conflicts since the given checkpoint',
accessType: 'READ',
accepts: [
{arg: 'since', type: 'number', description: 'Find deltas since this checkpoint'},
{arg: 'remoteChanges', type: 'array', description: 'an array of change objects',
http: {source: 'body'}}
],
returns: {arg: 'result', type: 'object', root: true},
http: {verb: 'post', path: '/diff'}
});

setRemoting(PersistedModel, 'changes', {
description: 'Get the changes to a model since a given checkpoint.' +
'Provide a filter object to reduce the number of results returned.',
accessType: 'READ',
accepts: [
{arg: 'since', type: 'number', description: 'Only return changes since this checkpoint'},
{arg: 'filter', type: 'object', description: 'Only include changes that match this filter'}
],
returns: {arg: 'changes', type: 'array', root: true},
http: {verb: 'get', path: '/changes'}
});

setRemoting(PersistedModel, 'checkpoint', {
description: 'Create a checkpoint.',
accessType: 'WRITE',
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'post', path: '/checkpoint'}
});
setRemoting(PersistedModel, 'diff', {
description: 'Get a set of deltas and conflicts since the given checkpoint',
accessType: 'READ',
accepts: [
{arg: 'since', type: 'number', description: 'Find deltas since this checkpoint'},
{arg: 'remoteChanges', type: 'array', description: 'an array of change objects',
http: {source: 'body'}}
],
returns: {arg: 'result', type: 'object', root: true},
http: {verb: 'post', path: '/diff'}
});

setRemoting(PersistedModel, 'currentCheckpoint', {
description: 'Get the current checkpoint.',
accessType: 'READ',
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'get', path: '/checkpoint'}
});
setRemoting(PersistedModel, 'changes', {
description: 'Get the changes to a model since a given checkpoint.' +
'Provide a filter object to reduce the number of results returned.',
accessType: 'READ',
accepts: [
{arg: 'since', type: 'number', description: 'Only return changes since this checkpoint'},
{arg: 'filter', type: 'object', description: 'Only include changes that match this filter'}
],
returns: {arg: 'changes', type: 'array', root: true},
http: {verb: 'get', path: '/changes'}
});

setRemoting(PersistedModel, 'createUpdates', {
description: 'Create an update list from a delta list',
accessType: 'WRITE',
accepts: {arg: 'deltas', type: 'array', http: {source: 'body'}},
returns: {arg: 'updates', type: 'array', root: true},
http: {verb: 'post', path: '/create-updates'}
});
setRemoting(PersistedModel, 'checkpoint', {
description: 'Create a checkpoint.',
// The replication algorithm needs to create a source checkpoint,
// even though it is otherwise not making any source changes.
// We need to allow this method for users that have only READ permissions.
accessType: 'READ',
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'post', path: '/checkpoint'}
});

setRemoting(PersistedModel, 'bulkUpdate', {
description: 'Run multiple updates at once. Note: this is not atomic.',
accessType: 'WRITE',
accepts: {arg: 'updates', type: 'array'},
http: {verb: 'post', path: '/bulk-update'}
});
setRemoting(PersistedModel, 'currentCheckpoint', {
description: 'Get the current checkpoint.',
accessType: 'READ',
returns: {arg: 'checkpoint', type: 'object', root: true},
http: {verb: 'get', path: '/checkpoint'}
});

setRemoting(PersistedModel, 'rectifyAllChanges', {
description: 'Rectify all Model changes.',
accessType: 'WRITE',
http: {verb: 'post', path: '/rectify-all'}
});
setRemoting(PersistedModel, 'createUpdates', {
description: 'Create an update list from a delta list',
// This operation is read-only, it does not change any local data.
// It is called by the replication algorithm to compile a list
// of changes to apply on the target.
accessType: 'READ',
accepts: {arg: 'deltas', type: 'array', http: {source: 'body'}},
returns: {arg: 'updates', type: 'array', root: true},
http: {verb: 'post', path: '/create-updates'}
});

setRemoting(PersistedModel, 'rectifyChange', {
description: 'Tell loopback that a change to the model with the given id has occurred.',
accessType: 'WRITE',
accepts: {arg: 'id', type: 'any', http: {source: 'path'}},
http: {verb: 'post', path: '/:id/rectify-change'}
});
}
setRemoting(PersistedModel, 'bulkUpdate', {
description: 'Run multiple updates at once. Note: this is not atomic.',
accessType: 'WRITE',
accepts: {arg: 'updates', type: 'array'},
http: {verb: 'post', path: '/bulk-update'}
});
};

/**
Expand Down Expand Up @@ -893,13 +884,15 @@ module.exports = function(registry) {
};

function tryReplicate(sourceModel, targetModel, since, options, callback) {
var Change = sourceModel.getChangeModel();
var TargetChange = targetModel.getChangeModel();
var changeTrackingEnabled = Change && TargetChange;
// TODO(bajtos) Move Change.Conflict to a standalone model
// that can be used without the Change model. That will allow
// us to replicate changes between two remote models, with no
// client Change model needed.
var Change = sourceModel.Change || targetModel.Change;

assert(
changeTrackingEnabled,
'You must enable change tracking before replicating'
!!Change,
'You must enable change tracking in at least one model before replicating'
);

var diff;
Expand Down Expand Up @@ -1281,7 +1274,7 @@ module.exports = function(registry) {
var changeModel = this.Change;
var isSetup = changeModel && changeModel.dataSource;

assert(isSetup, 'Cannot get a setup Change model');
assert(isSetup, 'Cannot get a setup Change model for ' + this.modelName);

return changeModel;
};
Expand Down
2 changes: 1 addition & 1 deletion test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ describe.onServer('Remote Methods', function() {
methodNames = methodNames.concat(method.sharedMethod.aliases || []);
});

expect(methodNames).to.have.members([
expect(methodNames).to.include.members([
// NOTE(bajtos) These three methods are disabled by default
// Because all tests share the same global registry model
// and one of the tests was enabling remoting of "destroyAll",
Expand Down
Loading

0 comments on commit 6f0cd70

Please sign in to comment.