From c0dc8e95d24d2008d96ab4aa74bbf330b6f0b625 Mon Sep 17 00:00:00 2001 From: Sebastian Gierlinger Date: Fri, 14 Mar 2014 18:36:45 +0100 Subject: [PATCH] Add new permissions to fixtures closes #2325 - added new permissions - added relation to user roles - added updateFixtures to migrateUp - removed validation per model to fix tests --- core/server/data/fixtures/index.js | 251 +++++++++++++++++++++++---- core/server/data/import/000.js | 50 +++--- core/server/data/migration/index.js | 4 +- core/server/models/app.js | 4 - core/server/models/appField.js | 11 -- core/server/models/appSetting.js | 9 - core/server/models/permission.js | 1 + core/server/permissions/effective.js | 4 +- core/test/unit/import_spec.js | 60 ++----- core/test/unit/permissions_spec.js | 2 +- 10 files changed, 271 insertions(+), 125 deletions(-) diff --git a/core/server/data/fixtures/index.js b/core/server/data/fixtures/index.js index e7d4c5de2f..c900a88bf0 100644 --- a/core/server/data/fixtures/index.js +++ b/core/server/data/fixtures/index.js @@ -1,9 +1,13 @@ -var sequence = require('when/sequence'), - _ = require('lodash'), - Post = require('../../models/post').Post, - Tag = require('../../models/tag').Tag, - Role = require('../../models/role').Role, - Permission = require('../../models/permission').Permission; +var sequence = require('when/sequence'), + _ = require('lodash'), + Post = require('../../models/post').Post, + Tag = require('../../models/tag').Tag, + Role = require('../../models/role').Role, + Permission = require('../../models/permission').Permission, + Permissions = require('../../models/permission').Permissions, + + populateFixtures, + updateFixtures; var fixtures = { posts: [ @@ -63,42 +67,227 @@ var fixtures = { "action_type": "create", "object_type": "post" } + ], + + permissions003: [ + { + "name": "Get slug", + "action_type": "slug", + "object_type": "post" + }, + { + "name": "Export database", + "action_type": "exportContent", + "object_type": "db" + }, + { + "name": "Import database", + "action_type": "importContent", + "object_type": "db" + }, + { + "name": "Delete all content", + "action_type": "deleteAllContent", + "object_type": "db" + }, + { + "name": "Browse users", + "action_type": "browse", + "object_type": "user" + }, + { + "name": "Read users", + "action_type": "read", + "object_type": "user" + }, + { + "name": "Edit users", + "action_type": "edit", + "object_type": "user" + }, + { + "name": "Add users", + "action_type": "add", + "object_type": "user" + }, + { + "name": "Browse settings", + "action_type": "browse", + "object_type": "setting" + }, + { + "name": "Read settings", + "action_type": "read", + "object_type": "setting" + }, + { + "name": "Edit settings", + "action_type": "edit", + "object_type": "setting" + } ] }; -module.exports = { - populateFixtures: function () { - var ops = []; - _.each(fixtures.posts, function (post) { - ops.push(function () {return Post.add(post); }); - }); +populateFixtures = function () { + var ops = [], + relations = []; - _.each(fixtures.tags, function (tag) { - ops.push(function () {return Tag.add(tag); }); - }); + _.each(fixtures.posts, function (post) { + ops.push(function () {return Post.add(post); }); + }); - _.each(fixtures.roles, function (role) { - ops.push(function () {return Role.add(role); }); - }); - _.each(fixtures.permissions, function (permission) { - ops.push(function () {return Permission.add(permission); }); - }); + _.each(fixtures.tags, function (tag) { + ops.push(function () {return Tag.add(tag); }); + }); - // add the tag to the post - ops.push(function () { - Post.forge({id: 1}).fetch({withRelated: ['tags']}).then(function (post) { - post.tags().attach([1]); + _.each(fixtures.roles, function (role) { + ops.push(function () {return Role.add(role); }); + }); + + _.each(fixtures.permissions, function (permission) { + ops.push(function () {return Permission.add(permission); }); + }); + + _.each(fixtures.permissions003, function (permission) { + ops.push(function () {return Permission.add(permission); }); + }); + + // add the tag to the post + relations.push(function () { + Post.forge({id: 1}).fetch({withRelated: ['tags']}).then(function (post) { + post.tags().attach([1]); + }); + }); + + //grant permissions to roles + relations.push(function () { + // admins gets all permissions + Role.forge({name: 'Administrator'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var admin_perm = _.map(perms.toJSON(), function (perm) { + return perm.id; + }); + return role.permissions().attach(_.compact(admin_perm)); }); }); - // finally, grant admins all permissions - ops.push(function () { - Role.forge({id: 1}).fetch({withRelated: ['permissions']}).then(function (role) { - role.permissions().attach([1, 2, 3]); + // editor gets access to posts, users and settings.browse, settings.read + Role.forge({name: 'Editor'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var editor_perm = _.map(perms.toJSON(), function (perm) { + if (perm.object_type === 'post' || perm.object_type === 'user') { + return perm.id; + } + if (perm.object_type === 'setting' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + return null; + }); + return role.permissions().attach(_.compact(editor_perm)); }); }); - return sequence(ops); - } + // author gets access to post.add, post.slug, settings.browse, settings.read, users.browse and users.read + Role.forge({name: 'Author'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var author_perm = _.map(perms.toJSON(), function (perm) { + if (perm.object_type === 'post' && + (perm.action_type === 'add' || perm.action_type === 'slug')) { + return perm.id; + } + if (perm.object_type === 'setting' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + if (perm.object_type === 'user' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + return null; + }); + return role.permissions().attach(_.compact(author_perm)); + }); + }); + }); + + return sequence(ops).then(function () { + sequence(relations); + }); }; + +updateFixtures = function () { + var ops = [], + relations = []; + + _.each(fixtures.permissions003, function (permission) { + ops.push(function () {return Permission.add(permission); }); + }); + + relations.push(function () { + // admin gets all new permissions + Role.forge({name: 'Administrator'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var admin_perm = _.map(perms.toJSON(), function (perm) { + var result = fixtures.permissions003.filter(function (object) { + return object.object_type === perm.object_type && object.action_type === perm.action_type; + }); + if (!_.isEmpty(result)) { + return perm.id; + } + return null; + }); + return role.permissions().attach(_.compact(admin_perm)); + }); + }); + + // editor gets access to posts, users and settings.browse, settings.read + Role.forge({name: 'Editor'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var editor_perm = _.map(perms.toJSON(), function (perm) { + if (perm.object_type === 'post' || perm.object_type === 'user') { + return perm.id; + } + if (perm.object_type === 'setting' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + return null; + }); + return role.permissions().attach(_.compact(editor_perm)); + }); + }); + + // author gets access to post.add, post.slug, settings.browse, settings.read, users.browse and users.read + Role.forge({name: 'Author'}).fetch({withRelated: ['permissions']}).then(function (role) { + Permissions.forge().fetch().then(function (perms) { + var author_perm = _.map(perms.toJSON(), function (perm) { + if (perm.object_type === 'post' && + (perm.action_type === 'add' || perm.action_type === 'slug')) { + return perm.id; + } + if (perm.object_type === 'setting' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + if (perm.object_type === 'user' && + (perm.action_type === 'browse' || perm.action_type === 'read')) { + return perm.id; + } + return null; + }); + return role.permissions().attach(_.compact(author_perm)); + }); + }); + }); + + return sequence(ops).then(function () { + sequence(relations); + }); +}; + +module.exports = { + populateFixtures: populateFixtures, + updateFixtures: updateFixtures +}; \ No newline at end of file diff --git a/core/server/data/import/000.js b/core/server/data/import/000.js index 2ceb00f04f..1ccd569ead 100644 --- a/core/server/data/import/000.js +++ b/core/server/data/import/000.js @@ -141,33 +141,33 @@ function importApps(ops, tableData, transaction) { })); }); } -/* -function importAppSettings(ops, tableData, transaction) { - var appsData = tableData.apps, - appSettingsData = tableData.app_settings, - appName; - appSettingsData = stripProperties(['id'], appSettingsData); +// function importAppSettings(ops, tableData, transaction) { +// var appsData = tableData.apps, +// appSettingsData = tableData.app_settings, +// appName; +// +// appSettingsData = stripProperties(['id'], appSettingsData); +// +// _.each(appSettingsData, function (appSetting) { +// // Find app to attach settings to +// appName = _.find(appsData, function (app) { +// return app.id === appSetting.app_id; +// }).name; +// ops.push(models.App.findOne({name: appName}, {transacting: transaction}).then(function (_app) { +// if (_app) { +// // Fix app_id +// appSetting.app_id = _app.id; +// return models.AppSetting.add(appSetting, {transacting: transaction}) +// // add pass-through error handling so that bluebird doesn't think we've dropped it +// .otherwise(function (error) { return when.reject(error); }); +// } +// // Gracefully ignore missing apps +// return when.resolve(_app); +// })); +// }); +// } - _.each(appSettingsData, function (appSetting) { - // Find app to attach settings to - appName = _.find(appsData, function (app) { - return app.id === appSetting.app_id; - }).name; - ops.push(models.App.findOne({name: appName}, {transacting: transaction}).then(function (_app) { - if (_app) { - // Fix app_id - appSetting.app_id = _app.id; - return models.AppSetting.add(appSetting, {transacting: transaction}) - // add pass-through error handling so that bluebird doesn't think we've dropped it - .otherwise(function (error) { return when.reject(error); }); - } - // Gracefully ignore missing apps - return when.resolve(_app); - })); - }); -} -*/ // No data needs modifying, we just import whatever tables are available Importer000.prototype.basicImport = function (data) { var ops = [], diff --git a/core/server/data/migration/index.js b/core/server/data/migration/index.js index 078567f2a0..95eae4494c 100644 --- a/core/server/data/migration/index.js +++ b/core/server/data/migration/index.js @@ -252,7 +252,7 @@ function checkMySQLPostTable() { // Migrate from a specific version to the latest migrateUp = function () { return getTables().then(function (oldTables) { - // if tables exist and lient is mysqls check if posts table is okay + // if tables exist and client is mysqls check if posts table is okay if (!_.isEmpty(oldTables) && client === 'mysql') { return checkMySQLPostTable().then(function () { return oldTables; @@ -274,6 +274,8 @@ migrateUp = function () { return sequence(commands); } return; + }).then(function () { + return fixtures.updateFixtures(); }); }; diff --git a/core/server/models/app.js b/core/server/models/app.js index 58f5a23e0b..612ce95d8b 100644 --- a/core/server/models/app.js +++ b/core/server/models/app.js @@ -6,10 +6,6 @@ var ghostBookshelf = require('./base'), App = ghostBookshelf.Model.extend({ tableName: 'apps', - validate: function () { - ghostBookshelf.validator.check(this.get('name'), "App name cannot be blank").notEmpty(); - }, - permissions: function () { // Have to use the require here because of circular dependencies return this.belongsToMany(require('./permission').Permission, 'permissions_apps'); diff --git a/core/server/models/appField.js b/core/server/models/appField.js index 98e0f2c61c..5d89eaab09 100644 --- a/core/server/models/appField.js +++ b/core/server/models/appField.js @@ -6,17 +6,6 @@ var ghostBookshelf = require('./base'), AppField = ghostBookshelf.Model.extend({ tableName: 'app_fields', - validate: function () { - ghostBookshelf.validator.check(this.get('key'), 'Key cannot be blank').notEmpty(); - ghostBookshelf.validator.check(this.get('key'), 'Key maximum length is 150 characters.').len(0, 150); - ghostBookshelf.validator.check(this.get('app_id'), 'App cannot be blank').notEmpty(); - ghostBookshelf.validator.check(this.get('type'), 'Type maximum length is 150 characters.').len(0, 150); - ghostBookshelf.validator.check(this.get('relatable_id'), 'Relatable id cannot be blank').notEmpty(); - ghostBookshelf.validator.check(this.get('relatable_type'), 'Relatable type cannot be blank').notEmpty(); - - return true; - }, - post: function () { return this.morphOne(Post, 'relatable'); } diff --git a/core/server/models/appSetting.js b/core/server/models/appSetting.js index 2b0be8d570..c9e5a160f6 100644 --- a/core/server/models/appSetting.js +++ b/core/server/models/appSetting.js @@ -6,15 +6,6 @@ var ghostBookshelf = require('./base'), AppSetting = ghostBookshelf.Model.extend({ tableName: 'app_settings', - validate: function () { - ghostBookshelf.validator.check(this.get('key'), 'Key cannot be blank').notEmpty(); - ghostBookshelf.validator.check(this.get('key'), 'Key maximum length is 150 characters.').len(0, 150); - ghostBookshelf.validator.check(this.get('app_id'), 'App cannot be blank').notEmpty(); - ghostBookshelf.validator.check(this.get('type'), 'Type maximum length is 150 characters.').len(0, 150); - - return true; - }, - app: function () { return this.belongsTo(App); } diff --git a/core/server/models/permission.js b/core/server/models/permission.js index 110ca5bd3d..6e13469ee1 100644 --- a/core/server/models/permission.js +++ b/core/server/models/permission.js @@ -2,6 +2,7 @@ var ghostBookshelf = require('./base'), User = require('./user').User, Role = require('./role').Role, App = require('./app').App, + Permission, Permissions; diff --git a/core/server/permissions/effective.js b/core/server/permissions/effective.js index 4ec5a50b3f..9d4f30a280 100644 --- a/core/server/permissions/effective.js +++ b/core/server/permissions/effective.js @@ -1,8 +1,8 @@ var _ = require('lodash'), Models = require('../models'), errors = require('../errorHandling'), - User = Models.User, - App = Models.App; + User = Models.User, + App = Models.App; var effective = { user: function (id) { diff --git a/core/test/unit/import_spec.js b/core/test/unit/import_spec.js index b8aeb110c4..693d08e57d 100644 --- a/core/test/unit/import_spec.js +++ b/core/test/unit/import_spec.js @@ -1,23 +1,23 @@ /*globals describe, beforeEach, it*/ var testUtils = require('../utils'), - should = require('should'), - sinon = require('sinon'), - when = require('when'), - assert = require('assert'), - _ = require("lodash"), - errors = require('../../server/errorHandling'), + should = require('should'), + sinon = require('sinon'), + when = require('when'), + assert = require('assert'), + _ = require("lodash"), + errors = require('../../server/errorHandling'), // Stuff we are testing - knex = require("../../server/models/base").knex, - migration = require('../../server/data/migration'), - exporter = require('../../server/data/export'), - importer = require('../../server/data/import'), + knex = require("../../server/models/base").knex, + migration = require('../../server/data/migration'), + exporter = require('../../server/data/export'), + importer = require('../../server/data/import'), Importer000 = require('../../server/data/import/000'), Importer001 = require('../../server/data/import/001'), Importer002 = require('../../server/data/import/002'), Importer003 = require('../../server/data/import/003'), - fixtures = require('../../server/data/fixtures'), - Settings = require('../../server/models/settings').Settings; + fixtures = require('../../server/data/fixtures'), + Settings = require('../../server/models/settings').Settings; describe("Import", function () { @@ -103,13 +103,7 @@ describe("Import", function () { beforeEach(function (done) { // migrate to current version - migration.migrateUp().then(function () { - // Load the fixtures - return fixtures.populateFixtures(); - }).then(function () { - // Initialise the default settings - return Settings.populateDefaults(); - }).then(function () { + migration.migrateUpFreshDb().then(function () { return testUtils.insertDefaultUser(); }).then(function () { done(); @@ -169,12 +163,8 @@ describe("Import", function () { beforeEach(function (done) { // migrate to current version - migration.migrateUp().then(function () { + migration.migrateUpFreshDb().then(function () { // Load the fixtures - return fixtures.populateFixtures(); - }).then(function () { - // Initialise the default settings - return Settings.populateDefaults(); }).then(function () { return testUtils.insertDefaultUser(); }).then(function () { @@ -356,13 +346,7 @@ describe("Import", function () { beforeEach(function (done) { // migrate to current version - migration.migrateUp().then(function () { - // Load the fixtures - return fixtures.populateFixtures(); - }).then(function () { - // Initialise the default settings - return Settings.populateDefaults(); - }).then(function () { + migration.migrateUpFreshDb().then(function () { return testUtils.insertDefaultUser(); }).then(function () { done(); @@ -543,17 +527,11 @@ describe("Import", function () { beforeEach(function (done) { // migrate to current version - migration.migrateUp().then(function () { - // Load the fixtures - return fixtures.populateFixtures(); + migration.migrateUpFreshDb().then(function () { + return testUtils.insertDefaultUser(); }).then(function () { - // Initialise the default settings - return Settings.populateDefaults(); - }).then(function () { - return testUtils.insertDefaultUser(); - }).then(function () { - done(); - }).then(null, done); + done(); + }).then(null, done); }); it("safely imports data from 003", function (done) { diff --git a/core/test/unit/permissions_spec.js b/core/test/unit/permissions_spec.js index 952ed42368..7657b4ece6 100644 --- a/core/test/unit/permissions_spec.js +++ b/core/test/unit/permissions_spec.js @@ -104,7 +104,7 @@ describe('Permissions', function () { .then(function (actionsMap) { should.exist(actionsMap); - actionsMap.edit.sort().should.eql(['post', 'tag', 'user', 'page'].sort()); + actionsMap.edit.sort().should.eql(['post', 'tag', 'user', 'page', 'setting'].sort()); actionsMap.should.equal(permissions.actionsMap);