Merge pull request #2753 from jgable/fixPermissable

Add apps permissable checks in posts and users
This commit is contained in:
Hannah Wolfe 2014-05-14 22:10:44 +01:00
commit f1a3f1a7a5
4 changed files with 42 additions and 23 deletions

View File

@ -82,7 +82,7 @@ posts = {
var self = this,
include;
return canThis(self.user).edit.post(postData.id).then(function () {
return canThis(this).edit.post(postData.id).then(function () {
return checkPostData(postData).then(function (checkedPostData) {
if (postData.include) {
@ -115,7 +115,7 @@ posts = {
include;
// **returns:** a promise for the resulting post in a json object
return canThis(this.user).create.post().then(function () {
return canThis(this).create.post().then(function () {
return checkPostData(postData).then(function (checkedPostData) {
if (postData.include) {
include = prepareInclude(postData.include);
@ -141,7 +141,7 @@ posts = {
destroy: function destroy(args) {
var self = this;
// **returns:** a promise for a json response with the id of the deleted post
return canThis(this.user).remove.post(args.id).then(function () {
return canThis(this).remove.post(args.id).then(function () {
// TODO: Would it be good to get rid of .call()?
return posts.read.call({user: self.user}, {id : args.id, status: 'all'}).then(function (result) {
return dataProvider.Post.destroy(args.id).then(function () {
@ -165,7 +165,7 @@ posts = {
// **takes:** a string to generate the slug from
generateSlug: function generateSlug(args) {
return canThis(this.user).slug.post().then(function () {
return canThis(this).slug.post().then(function () {
return dataProvider.Base.Model.generateSlug(dataProvider.Post, args.title, {status: 'all'}).then(function (slug) {
if (slug) {
return slug;

View File

@ -473,21 +473,31 @@ Post = ghostBookshelf.Model.extend({
});
},
permissable: function (postModelOrId, context) {
permissable: function (postModelOrId, context, loadedPermissions, hasUserPermission, hasAppPermission) {
var self = this,
userId = context.user,
postModel = postModelOrId;
postModel = postModelOrId,
origArgs;
// If we passed in an id instead of a model, get the model
// then check the permissions
if (_.isNumber(postModelOrId) || _.isString(postModelOrId)) {
// Grab the original args without the first one
origArgs = _.toArray(arguments).slice(1);
// Get the actual post model
return this.findOne({id: postModelOrId, status: 'all'}).then(function (foundPostModel) {
return self.permissable(foundPostModel, context);
// Build up the original args but substitute with actual model
var newArgs = [foundPostModel].concat(origArgs);
return self.permissable.apply(self, newArgs);
}, errors.logAndThrowError);
}
// If this is the author of the post, allow it.
if (postModel && userId === postModel.get('author_id')) {
if (postModel) {
// If this is the author of the post, allow it.
hasUserPermission = hasUserPermission || context.user === postModel.get('author_id');
}
if (hasUserPermission && hasAppPermission) {
return when.resolve();
}

View File

@ -172,23 +172,34 @@ User = ghostBookshelf.Model.extend({
},
permissable: function (userModelOrId, context) {
permissable: function (userModelOrId, context, loadedPermissions, hasUserPermission, hasAppPermission) {
var self = this,
userId = context.user,
userModel = userModelOrId;
userModel = userModelOrId,
origArgs;
// If we passed in an id instead of a model, get the model
// then check the permissions
if (_.isNumber(userModelOrId) || _.isString(userModelOrId)) {
// Grab the original args without the first one
origArgs = _.toArray(arguments).slice(1);
// Get the actual post model
return this.findOne({id: userModelOrId}).then(function (foundUserModel) {
return self.permissable(foundUserModel, context);
// Build up the original args but substitute with actual model
var newArgs = [foundUserModel].concat(origArgs);
return self.permissable.apply(self, newArgs);
}, errors.logAndThrowError);
}
// If this is the same user that requests the operation allow it.
if (userModel && userId === userModel.get('id')) {
if (userModel) {
// If this is the same user that requests the operation allow it.
hasUserPermission = hasUserPermission || context.user === userModel.get('id');
}
if (hasUserPermission && hasAppPermission) {
return when.resolve();
}
return when.reject();
},

View File

@ -120,16 +120,14 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (obj_types, act_type,
hasAppPermission = _.any(appPermissions, checkPermission);
}
// Offer a chance for the TargetModel to override the results
if (TargetModel && _.isFunction(TargetModel.permissable)) {
return TargetModel.permissable(modelId, context, loadedPermissions, hasUserPermission, hasAppPermission);
}
if (hasUserPermission && hasAppPermission) {
return when.resolve();
}
return when.reject();
}).otherwise(function () {
// Check for special permissions on the model directly
if (TargetModel && _.isFunction(TargetModel.permissable)) {
return TargetModel.permissable(modelId, context);
}
return when.reject();
});
};