mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
issue #58 - removing the iiwf
Function wrapper and use strict pragma removed from all node files
This commit is contained in:
parent
2c7245e0e5
commit
ba810fb0bb
559
Gruntfile.js
559
Gruntfile.js
@ -1,307 +1,302 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var path = require('path'),
|
||||
buildDirectory = path.resolve(process.cwd(), '../build'),
|
||||
distDirectory = path.resolve(process.cwd(), '../dist'),
|
||||
configureGrunt = function (grunt) {
|
||||
|
||||
var path = require('path'),
|
||||
buildDirectory = path.resolve(process.cwd(), '../build'),
|
||||
distDirectory = path.resolve(process.cwd(), '../dist'),
|
||||
configureGrunt = function (grunt) {
|
||||
var cfg = {
|
||||
// Common paths to be used by tasks
|
||||
paths: {
|
||||
adminAssets: './core/admin/assets',
|
||||
build: buildDirectory,
|
||||
nightlyBuild: path.join(buildDirectory, 'nightly'),
|
||||
buildBuild: path.join(buildDirectory, 'build'),
|
||||
dist: distDirectory,
|
||||
nightlyDist: path.join(distDirectory, 'nightly'),
|
||||
buildDist: path.join(distDirectory, 'build')
|
||||
},
|
||||
|
||||
var cfg = {
|
||||
// Common paths to be used by tasks
|
||||
paths: {
|
||||
adminAssets: './core/admin/assets',
|
||||
build: buildDirectory,
|
||||
nightlyBuild: path.join(buildDirectory, 'nightly'),
|
||||
buildBuild: path.join(buildDirectory, 'build'),
|
||||
dist: distDirectory,
|
||||
nightlyDist: path.join(distDirectory, 'nightly'),
|
||||
buildDist: path.join(distDirectory, 'build')
|
||||
},
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
// JSLint all the things!
|
||||
jslintm: {
|
||||
node: {
|
||||
directives: {
|
||||
// node environment
|
||||
node: true,
|
||||
// browser environment
|
||||
browser: false,
|
||||
// allow dangling underscores in var names
|
||||
nomen: true,
|
||||
// allow to do statements
|
||||
todo: true,
|
||||
// allow unused parameters
|
||||
unparam: true,
|
||||
// don't require use strict pragma
|
||||
sloppy: true
|
||||
},
|
||||
files: {
|
||||
src: [
|
||||
"*.js",
|
||||
"core/**/*.js"
|
||||
]
|
||||
},
|
||||
// Lint core files, but not libs, frontend or hbs files
|
||||
exclude: [
|
||||
"**/assets/lib/**/*.js",
|
||||
"**/assets/js/**/*.js",
|
||||
"**/assets/tpl/*.js"
|
||||
// JSLint all the things!
|
||||
jslintm: {
|
||||
node: {
|
||||
directives: {
|
||||
// node environment
|
||||
node: true,
|
||||
// browser environment
|
||||
browser: false,
|
||||
// allow dangling underscores in var names
|
||||
nomen: true,
|
||||
// allow to do statements
|
||||
todo: true,
|
||||
// allow unused parameters
|
||||
unparam: true,
|
||||
// don't require use strict pragma
|
||||
sloppy: true
|
||||
},
|
||||
files: {
|
||||
src: [
|
||||
"*.js",
|
||||
"core/**/*.js"
|
||||
]
|
||||
},
|
||||
frontend: {
|
||||
directives: {
|
||||
// node environment
|
||||
node: false,
|
||||
// browser environment
|
||||
browser: true,
|
||||
// allow dangling underscores in var names
|
||||
nomen: true,
|
||||
// allow to do statements
|
||||
todo: true,
|
||||
// allow unused parameters
|
||||
unparam: true
|
||||
},
|
||||
files: {
|
||||
src: "**/assets/js/**/*.js"
|
||||
}
|
||||
}
|
||||
// Lint core files, but not libs, frontend or hbs files
|
||||
exclude: [
|
||||
"**/assets/lib/**/*.js",
|
||||
"**/assets/js/**/*.js",
|
||||
"**/assets/tpl/*.js"
|
||||
]
|
||||
},
|
||||
|
||||
mochaTest: {
|
||||
options: {
|
||||
ui: "bdd",
|
||||
reporter: "spec"
|
||||
frontend: {
|
||||
directives: {
|
||||
// node environment
|
||||
node: false,
|
||||
// browser environment
|
||||
browser: true,
|
||||
// allow dangling underscores in var names
|
||||
nomen: true,
|
||||
// allow to do statements
|
||||
todo: true,
|
||||
// allow unused parameters
|
||||
unparam: true
|
||||
},
|
||||
|
||||
all: {
|
||||
src: ['core/test/**/*_spec.js']
|
||||
},
|
||||
|
||||
api: {
|
||||
src: ['core/test/**/api*_spec.js']
|
||||
},
|
||||
|
||||
perm: {
|
||||
src: ['core/test/**/permissions_spec.js']
|
||||
}
|
||||
},
|
||||
|
||||
// Compile all the SASS!
|
||||
sass: {
|
||||
admin: {
|
||||
files: {
|
||||
'<%= paths.adminAssets %>/css/screen.css': '<%= paths.adminAssets %>/sass/screen.scss'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
shell: {
|
||||
bourbon: {
|
||||
command: 'bourbon install --path <%= paths.adminAssets %>/sass/modules/'
|
||||
},
|
||||
|
||||
commitNightly: {
|
||||
command: 'git commit package.json -m "Nightly build <%= pkg.version %>"'
|
||||
},
|
||||
|
||||
tagNightly: {
|
||||
command: 'git tag <%= pkg.version %> -a -m "Nightly build <%= pkg.version %>"'
|
||||
},
|
||||
|
||||
pushMaster: {
|
||||
command: 'git push origin master'
|
||||
},
|
||||
|
||||
pushMasterTags: {
|
||||
command: 'git push origin master --tags'
|
||||
}
|
||||
},
|
||||
|
||||
handlebars: {
|
||||
core: {
|
||||
options: {
|
||||
namespace: "JST",
|
||||
processName: function (filename) {
|
||||
filename = filename.replace('./core/admin/assets/tpl/', '');
|
||||
return filename.replace('.hbs', '');
|
||||
}
|
||||
},
|
||||
files: {
|
||||
"<%= paths.adminAssets %>/tpl/hbs-tpl.js": "<%= paths.adminAssets %>/tpl/**/*.hbs"
|
||||
}
|
||||
}
|
||||
},
|
||||
groc: {
|
||||
application: [
|
||||
"README.md",
|
||||
"config.js",
|
||||
"app.js",
|
||||
"core/ghost.js",
|
||||
"core/admin/assets/js/*.js",
|
||||
"core/admin/assets/js/models/*.js",
|
||||
"core/admin/assets/js/views/*.js",
|
||||
"core/admin/controllers/*.js",
|
||||
"core/frontend/controllers/*.js",
|
||||
"core/frontend/filters/*.js",
|
||||
"core/frontend/helpers/*.js",
|
||||
"core/lang/i18n.js",
|
||||
"core/shared/models/*.js",
|
||||
"core/shared/permissions/*.js",
|
||||
"core/shared/*.js",
|
||||
"core/test/ghost/*.js",
|
||||
"core/test/ghost.js"
|
||||
],
|
||||
options: {
|
||||
"out": "./docs/"
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
handlebars: {
|
||||
files: '<%= paths.adminAssets %>/tpl/**/*.hbs',
|
||||
tasks: ['handlebars']
|
||||
},
|
||||
sass: {
|
||||
files: '<%= paths.adminAssets %>/sass/**/*',
|
||||
tasks: ['sass:admin']
|
||||
}
|
||||
},
|
||||
|
||||
copy: {
|
||||
nightly: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: [
|
||||
'**',
|
||||
'!node_modules/**',
|
||||
'!core/shared/data/*.db',
|
||||
'!.sass*',
|
||||
'!.af*',
|
||||
'!.git*',
|
||||
'!.groc*',
|
||||
'!.travis.yml'
|
||||
],
|
||||
dest: "<%= paths.nightlyBuild %>/<%= pkg.version %>/"
|
||||
}]
|
||||
},
|
||||
build: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: [
|
||||
'**',
|
||||
'!node_modules/**',
|
||||
'!core/shared/data/*.db',
|
||||
'!.sass*',
|
||||
'!.af*',
|
||||
'!.git*',
|
||||
'!.groc*',
|
||||
'!.travis.yml'
|
||||
],
|
||||
dest: "<%= paths.buildBuild %>/"
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
compress: {
|
||||
nightly: {
|
||||
options: {
|
||||
archive: "<%= paths.nightlyDist %>/Ghost-Nightly-<%= pkg.version %>.zip"
|
||||
},
|
||||
expand: true,
|
||||
cwd: "<%= paths.nightlyBuild %>/<%= pkg.version %>/",
|
||||
src: ["**"]
|
||||
},
|
||||
build: {
|
||||
options: {
|
||||
archive: "<%= paths.buildDist %>/Ghost-Build.zip"
|
||||
},
|
||||
expand: true,
|
||||
cwd: "<%= paths.buildBuild %>/",
|
||||
src: ["**"]
|
||||
files: {
|
||||
src: "**/assets/js/**/*.js"
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
grunt.initConfig(cfg);
|
||||
mochaTest: {
|
||||
options: {
|
||||
ui: "bdd",
|
||||
reporter: "spec"
|
||||
},
|
||||
|
||||
grunt.loadNpmTasks("grunt-jslint");
|
||||
grunt.loadNpmTasks("grunt-mocha-test");
|
||||
grunt.loadNpmTasks("grunt-shell");
|
||||
grunt.loadNpmTasks("grunt-bump");
|
||||
all: {
|
||||
src: ['core/test/**/*_spec.js']
|
||||
},
|
||||
|
||||
grunt.loadNpmTasks("grunt-contrib-compress");
|
||||
grunt.loadNpmTasks("grunt-contrib-copy");
|
||||
grunt.loadNpmTasks("grunt-contrib-watch");
|
||||
grunt.loadNpmTasks("grunt-contrib-sass");
|
||||
grunt.loadNpmTasks("grunt-contrib-handlebars");
|
||||
grunt.loadNpmTasks('grunt-groc');
|
||||
api: {
|
||||
src: ['core/test/**/api*_spec.js']
|
||||
},
|
||||
|
||||
// Update the package information after changes
|
||||
grunt.registerTask('updateCurrentPackageInfo', function () {
|
||||
cfg.pkg = grunt.file.readJSON('package.json');
|
||||
});
|
||||
perm: {
|
||||
src: ['core/test/**/permissions_spec.js']
|
||||
}
|
||||
},
|
||||
|
||||
// jslintm aliased to jslint
|
||||
grunt.registerTask("jslint", ["jslintm"]);
|
||||
// Compile all the SASS!
|
||||
sass: {
|
||||
admin: {
|
||||
files: {
|
||||
'<%= paths.adminAssets %>/css/screen.css': '<%= paths.adminAssets %>/sass/screen.scss'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Prepare the project for development
|
||||
// TODO: Git submodule init/update (https://github.com/jaubourg/grunt-update-submodules)?
|
||||
grunt.registerTask("init", ["shell:bourbon", "sass:admin", 'handlebars']);
|
||||
shell: {
|
||||
bourbon: {
|
||||
command: 'bourbon install --path <%= paths.adminAssets %>/sass/modules/'
|
||||
},
|
||||
|
||||
// Run API tests only
|
||||
grunt.registerTask("test-api", ["mochaTest:api"]);
|
||||
commitNightly: {
|
||||
command: 'git commit package.json -m "Nightly build <%= pkg.version %>"'
|
||||
},
|
||||
|
||||
// Run permisisons tests only
|
||||
grunt.registerTask("test-p", ["mochaTest:perm"]);
|
||||
tagNightly: {
|
||||
command: 'git tag <%= pkg.version %> -a -m "Nightly build <%= pkg.version %>"'
|
||||
},
|
||||
|
||||
// Run tests and lint code
|
||||
grunt.registerTask("validate", ["jslint", "mochaTest:all"]);
|
||||
pushMaster: {
|
||||
command: 'git push origin master'
|
||||
},
|
||||
|
||||
// Generate Docs
|
||||
grunt.registerTask("docs", ["groc"]);
|
||||
pushMasterTags: {
|
||||
command: 'git push origin master --tags'
|
||||
}
|
||||
},
|
||||
|
||||
/* Nightly builds
|
||||
* - Bump patch version in package.json,
|
||||
* - Copy files to build-folder/nightly/#{version} directory
|
||||
* - Clean out unnecessary files (travis, .git*, .af*, .groc*)
|
||||
* - Zip files in build folder to dist-folder/#{version} directory
|
||||
* - git commit package.json -m "Nightly build #{version}"
|
||||
* - git tag -a -m "Nightly build #{version}"
|
||||
* - git push origin master
|
||||
* - git push origin master --tags
|
||||
* - TODO: POST to pubsubhubub to notify of new build?
|
||||
*/
|
||||
grunt.registerTask("nightly", [
|
||||
"shell:bourbon",
|
||||
"sass:admin",
|
||||
"handlebars",
|
||||
"validate",
|
||||
"bump",
|
||||
"updateCurrentPackageInfo",
|
||||
"copy:nightly",
|
||||
"compress:nightly"
|
||||
/* Caution: shit gets real below here */
|
||||
//"shell:commitNightly",
|
||||
//"shell:tagNightly",
|
||||
//"shell:pushMaster",
|
||||
//"shell:pushMasterTags"
|
||||
]);
|
||||
handlebars: {
|
||||
core: {
|
||||
options: {
|
||||
namespace: "JST",
|
||||
processName: function (filename) {
|
||||
filename = filename.replace('./core/admin/assets/tpl/', '');
|
||||
return filename.replace('.hbs', '');
|
||||
}
|
||||
},
|
||||
files: {
|
||||
"<%= paths.adminAssets %>/tpl/hbs-tpl.js": "<%= paths.adminAssets %>/tpl/**/*.hbs"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
grunt.registerTask("build", [
|
||||
"shell:bourbon",
|
||||
"sass:admin",
|
||||
"handlebars",
|
||||
"copy:build",
|
||||
"compress:build"
|
||||
]);
|
||||
groc: {
|
||||
application: [
|
||||
"README.md",
|
||||
"config.js",
|
||||
"app.js",
|
||||
"core/ghost.js",
|
||||
"core/admin/assets/js/*.js",
|
||||
"core/admin/assets/js/models/*.js",
|
||||
"core/admin/assets/js/views/*.js",
|
||||
"core/admin/controllers/*.js",
|
||||
"core/frontend/controllers/*.js",
|
||||
"core/frontend/filters/*.js",
|
||||
"core/frontend/helpers/*.js",
|
||||
"core/lang/i18n.js",
|
||||
"core/shared/models/*.js",
|
||||
"core/shared/permissions/*.js",
|
||||
"core/shared/*.js",
|
||||
"core/test/ghost/*.js",
|
||||
"core/test/ghost.js"
|
||||
],
|
||||
options: {
|
||||
"out": "./docs/"
|
||||
}
|
||||
},
|
||||
|
||||
// When you just say "grunt"
|
||||
grunt.registerTask("default", ['sass:admin', 'handlebars']);
|
||||
watch: {
|
||||
handlebars: {
|
||||
files: '<%= paths.adminAssets %>/tpl/**/*.hbs',
|
||||
tasks: ['handlebars']
|
||||
},
|
||||
sass: {
|
||||
files: '<%= paths.adminAssets %>/sass/**/*',
|
||||
tasks: ['sass:admin']
|
||||
}
|
||||
},
|
||||
|
||||
copy: {
|
||||
nightly: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: [
|
||||
'**',
|
||||
'!node_modules/**',
|
||||
'!core/shared/data/*.db',
|
||||
'!.sass*',
|
||||
'!.af*',
|
||||
'!.git*',
|
||||
'!.groc*',
|
||||
'!.travis.yml'
|
||||
],
|
||||
dest: "<%= paths.nightlyBuild %>/<%= pkg.version %>/"
|
||||
}]
|
||||
},
|
||||
build: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: [
|
||||
'**',
|
||||
'!node_modules/**',
|
||||
'!core/shared/data/*.db',
|
||||
'!.sass*',
|
||||
'!.af*',
|
||||
'!.git*',
|
||||
'!.groc*',
|
||||
'!.travis.yml'
|
||||
],
|
||||
dest: "<%= paths.buildBuild %>/"
|
||||
}]
|
||||
}
|
||||
},
|
||||
|
||||
compress: {
|
||||
nightly: {
|
||||
options: {
|
||||
archive: "<%= paths.nightlyDist %>/Ghost-Nightly-<%= pkg.version %>.zip"
|
||||
},
|
||||
expand: true,
|
||||
cwd: "<%= paths.nightlyBuild %>/<%= pkg.version %>/",
|
||||
src: ["**"]
|
||||
},
|
||||
build: {
|
||||
options: {
|
||||
archive: "<%= paths.buildDist %>/Ghost-Build.zip"
|
||||
},
|
||||
expand: true,
|
||||
cwd: "<%= paths.buildBuild %>/",
|
||||
src: ["**"]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = configureGrunt;
|
||||
grunt.initConfig(cfg);
|
||||
|
||||
}());
|
||||
grunt.loadNpmTasks("grunt-jslint");
|
||||
grunt.loadNpmTasks("grunt-mocha-test");
|
||||
grunt.loadNpmTasks("grunt-shell");
|
||||
grunt.loadNpmTasks("grunt-bump");
|
||||
|
||||
grunt.loadNpmTasks("grunt-contrib-compress");
|
||||
grunt.loadNpmTasks("grunt-contrib-copy");
|
||||
grunt.loadNpmTasks("grunt-contrib-watch");
|
||||
grunt.loadNpmTasks("grunt-contrib-sass");
|
||||
grunt.loadNpmTasks("grunt-contrib-handlebars");
|
||||
grunt.loadNpmTasks('grunt-groc');
|
||||
|
||||
// Update the package information after changes
|
||||
grunt.registerTask('updateCurrentPackageInfo', function () {
|
||||
cfg.pkg = grunt.file.readJSON('package.json');
|
||||
});
|
||||
|
||||
// jslintm aliased to jslint
|
||||
grunt.registerTask("jslint", ["jslintm"]);
|
||||
|
||||
// Prepare the project for development
|
||||
// TODO: Git submodule init/update (https://github.com/jaubourg/grunt-update-submodules)?
|
||||
grunt.registerTask("init", ["shell:bourbon", "sass:admin", 'handlebars']);
|
||||
|
||||
// Run API tests only
|
||||
grunt.registerTask("test-api", ["mochaTest:api"]);
|
||||
|
||||
// Run permisisons tests only
|
||||
grunt.registerTask("test-p", ["mochaTest:perm"]);
|
||||
|
||||
// Run tests and lint code
|
||||
grunt.registerTask("validate", ["jslint", "mochaTest:all"]);
|
||||
|
||||
// Generate Docs
|
||||
grunt.registerTask("docs", ["groc"]);
|
||||
|
||||
/* Nightly builds
|
||||
* - Bump patch version in package.json,
|
||||
* - Copy files to build-folder/nightly/#{version} directory
|
||||
* - Clean out unnecessary files (travis, .git*, .af*, .groc*)
|
||||
* - Zip files in build folder to dist-folder/#{version} directory
|
||||
* - git commit package.json -m "Nightly build #{version}"
|
||||
* - git tag -a -m "Nightly build #{version}"
|
||||
* - git push origin master
|
||||
* - git push origin master --tags
|
||||
* - TODO: POST to pubsubhubub to notify of new build?
|
||||
*/
|
||||
grunt.registerTask("nightly", [
|
||||
"shell:bourbon",
|
||||
"sass:admin",
|
||||
"handlebars",
|
||||
"validate",
|
||||
"bump",
|
||||
"updateCurrentPackageInfo",
|
||||
"copy:nightly",
|
||||
"compress:nightly"
|
||||
/* Caution: shit gets real below here */
|
||||
//"shell:commitNightly",
|
||||
//"shell:tagNightly",
|
||||
//"shell:pushMaster",
|
||||
//"shell:pushMasterTags"
|
||||
]);
|
||||
|
||||
grunt.registerTask("build", [
|
||||
"shell:bourbon",
|
||||
"sass:admin",
|
||||
"handlebars",
|
||||
"copy:build",
|
||||
"compress:build"
|
||||
]);
|
||||
|
||||
// When you just say "grunt"
|
||||
grunt.registerTask("default", ['sass:admin', 'handlebars']);
|
||||
};
|
||||
|
||||
module.exports = configureGrunt;
|
297
app.js
297
app.js
@ -1,172 +1,167 @@
|
||||
// # Ghost main app file
|
||||
|
||||
/*global require, __dirname */
|
||||
(function () {
|
||||
"use strict";
|
||||
// Module dependencies.
|
||||
var express = require('express'),
|
||||
when = require('when'),
|
||||
_ = require('underscore'),
|
||||
errors = require('./core/shared/errorHandling'),
|
||||
admin = require('./core/admin/controllers'),
|
||||
frontend = require('./core/frontend/controllers'),
|
||||
api = require('./core/shared/api'),
|
||||
flash = require('connect-flash'),
|
||||
Ghost = require('./core/ghost'),
|
||||
I18n = require('./core/lang/i18n'),
|
||||
filters = require('./core/frontend/filters'),
|
||||
helpers = require('./core/frontend/helpers'),
|
||||
|
||||
// Module dependencies.
|
||||
var express = require('express'),
|
||||
when = require('when'),
|
||||
_ = require('underscore'),
|
||||
errors = require('./core/shared/errorHandling'),
|
||||
admin = require('./core/admin/controllers'),
|
||||
frontend = require('./core/frontend/controllers'),
|
||||
api = require('./core/shared/api'),
|
||||
flash = require('connect-flash'),
|
||||
Ghost = require('./core/ghost'),
|
||||
I18n = require('./core/lang/i18n'),
|
||||
filters = require('./core/frontend/filters'),
|
||||
helpers = require('./core/frontend/helpers'),
|
||||
// ## Custom Middleware
|
||||
auth,
|
||||
authAPI,
|
||||
ghostLocals,
|
||||
disableCachedResult,
|
||||
|
||||
// ## Custom Middleware
|
||||
auth,
|
||||
authAPI,
|
||||
ghostLocals,
|
||||
disableCachedResult,
|
||||
// ## Variables
|
||||
loading = when.defer(),
|
||||
|
||||
// ## Variables
|
||||
loading = when.defer(),
|
||||
|
||||
/**
|
||||
* Create new Ghost object
|
||||
* @type {Ghost}
|
||||
*/
|
||||
ghost = new Ghost();
|
||||
/**
|
||||
* Create new Ghost object
|
||||
* @type {Ghost}
|
||||
*/
|
||||
ghost = new Ghost();
|
||||
|
||||
|
||||
ghost.app().configure('development', function () {
|
||||
ghost.app().use(express.favicon(__dirname + '/content/images/favicon.ico'));
|
||||
ghost.app().use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||
ghost.app().use(express.logger('dev'));
|
||||
ghost.app().use(I18n.load(ghost));
|
||||
ghost.app().use(express.bodyParser({}));
|
||||
ghost.app().use(express.cookieParser('try-ghost'));
|
||||
ghost.app().use(express.cookieSession({ cookie: { maxAge: 60000000 }}));
|
||||
ghost.app().use(ghost.initTheme(ghost.app()));
|
||||
ghost.app().use(flash());
|
||||
ghost.app().configure('development', function () {
|
||||
ghost.app().use(express.favicon(__dirname + '/content/images/favicon.ico'));
|
||||
ghost.app().use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||
ghost.app().use(express.logger('dev'));
|
||||
ghost.app().use(I18n.load(ghost));
|
||||
ghost.app().use(express.bodyParser({}));
|
||||
ghost.app().use(express.cookieParser('try-ghost'));
|
||||
ghost.app().use(express.cookieSession({ cookie: { maxAge: 60000000 }}));
|
||||
ghost.app().use(ghost.initTheme(ghost.app()));
|
||||
ghost.app().use(flash());
|
||||
});
|
||||
|
||||
/**
|
||||
* Authenticate a request by redirecting to login if not logged in
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
auth = function (req, res, next) {
|
||||
if (!req.session.user) {
|
||||
if (req.url && /^\/ghost\/?$/gi.test(req.url)) {
|
||||
// TODO: Welcome message? Intro if no logins yet?
|
||||
req.shutUpJsLint = true;
|
||||
} else {
|
||||
req.flash('warn', "Please login");
|
||||
}
|
||||
|
||||
return res.redirect('/ghost/login/?redirect=' + encodeURIComponent(req.path));
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticate a request by responding with a 401 and json error details
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
authAPI = function (req, res, next) {
|
||||
if (!req.session.user) {
|
||||
// TODO: standardize error format/codes/messages
|
||||
var err = { code: 42, message: 'Please login' };
|
||||
res.json(401, { error: err });
|
||||
return;
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the standard locals that every external page should have available;
|
||||
* path, navItems and settingsCache
|
||||
*/
|
||||
ghostLocals = function (req, res, next) {
|
||||
ghost.doFilter('ghostNavItems', {path: req.path, navItems: []}, function (navData) {
|
||||
// Make sure we have a locals value.
|
||||
res.locals = res.locals || {};
|
||||
|
||||
// Extend it with nav data and settings
|
||||
_.extend(res.locals, navData, {
|
||||
messages: req.flash(),
|
||||
settings: ghost.settings(),
|
||||
availableThemes: ghost.paths().availableThemes,
|
||||
availablePlugins: ghost.paths().availablePlugins
|
||||
});
|
||||
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
disableCachedResult = function (req, res, next) {
|
||||
res.set({
|
||||
"Cache-Control": "no-cache, must-revalidate",
|
||||
"Expires": "Sat, 26 Jul 1997 05:00:00 GMT"
|
||||
});
|
||||
|
||||
/**
|
||||
* Authenticate a request by redirecting to login if not logged in
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
auth = function (req, res, next) {
|
||||
if (!req.session.user) {
|
||||
if (req.url && /^\/ghost\/?$/gi.test(req.url)) {
|
||||
// TODO: Welcome message? Intro if no logins yet?
|
||||
req.shutUpJsLint = true;
|
||||
} else {
|
||||
req.flash('warn', "Please login");
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
return res.redirect('/ghost/login/?redirect=' + encodeURIComponent(req.path));
|
||||
}
|
||||
// Expose the promise we will resolve after our pre-loading
|
||||
ghost.loaded = loading.promise;
|
||||
|
||||
next();
|
||||
};
|
||||
when.all([ghost.init(), filters.loadCoreFilters(ghost), helpers.loadCoreHelpers(ghost)]).then(function () {
|
||||
|
||||
// post init config
|
||||
ghost.app().use(ghostLocals);
|
||||
|
||||
/**
|
||||
* Authenticate a request by responding with a 401 and json error details
|
||||
*
|
||||
* @type {*}
|
||||
* API routes..
|
||||
* @todo auth should be public auth not user auth
|
||||
*/
|
||||
authAPI = function (req, res, next) {
|
||||
if (!req.session.user) {
|
||||
// TODO: standardize error format/codes/messages
|
||||
var err = { code: 42, message: 'Please login' };
|
||||
res.json(401, { error: err });
|
||||
return;
|
||||
}
|
||||
next();
|
||||
};
|
||||
ghost.app().get('/api/v0.1/posts', authAPI, disableCachedResult, api.requestHandler(api.posts.browse));
|
||||
ghost.app().post('/api/v0.1/posts', authAPI, disableCachedResult, api.requestHandler(api.posts.add));
|
||||
ghost.app().get('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.read));
|
||||
ghost.app().put('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.edit));
|
||||
ghost.app().del('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.destroy));
|
||||
ghost.app().get('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.browse));
|
||||
ghost.app().get('/api/v0.1/settings/:key', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.read));
|
||||
ghost.app().put('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.edit));
|
||||
|
||||
/**
|
||||
* Expose the standard locals that every external page should have available;
|
||||
* path, navItems and settingsCache
|
||||
* Admin routes..
|
||||
* @todo put these somewhere in admin
|
||||
*/
|
||||
ghostLocals = function (req, res, next) {
|
||||
ghost.doFilter('ghostNavItems', {path: req.path, navItems: []}, function (navData) {
|
||||
// Make sure we have a locals value.
|
||||
res.locals = res.locals || {};
|
||||
ghost.app().get(/^\/logout\/?$/, admin.logout);
|
||||
ghost.app().get('/ghost/login/', admin.login);
|
||||
ghost.app().get('/ghost/signup/', admin.signup);
|
||||
ghost.app().post('/ghost/login/', admin.auth);
|
||||
ghost.app().post('/ghost/signup/', admin.doRegister);
|
||||
ghost.app().get('/ghost/editor/:id', auth, admin.editor);
|
||||
ghost.app().get('/ghost/editor', auth, admin.editor);
|
||||
ghost.app().get('/ghost/content', auth, admin.content);
|
||||
ghost.app().get('/ghost/settings*', auth, admin.settings);
|
||||
ghost.app().get('/ghost/debug', auth, admin.debug.index);
|
||||
ghost.app().get('/ghost/debug/db/export/', auth, admin.debug['export']);
|
||||
ghost.app().post('/ghost/debug/db/import/', auth, admin.debug.import);
|
||||
ghost.app().get('/ghost/debug/db/reset/', auth, admin.debug.reset);
|
||||
ghost.app().get(/^\/(ghost$|(ghost-admin|admin|wp-admin|dashboard|login)\/?)/, auth, function (req, res) {
|
||||
res.redirect('/ghost/');
|
||||
});
|
||||
ghost.app().get('/ghost/', auth, admin.index);
|
||||
|
||||
// Extend it with nav data and settings
|
||||
_.extend(res.locals, navData, {
|
||||
messages: req.flash(),
|
||||
settings: ghost.settings(),
|
||||
availableThemes: ghost.paths().availableThemes,
|
||||
availablePlugins: ghost.paths().availablePlugins
|
||||
});
|
||||
/**
|
||||
* Frontend routes..
|
||||
* @todo dynamic routing, homepage generator, filters ETC ETC
|
||||
*/
|
||||
ghost.app().get('/:slug', frontend.single);
|
||||
ghost.app().get('/', frontend.homepage);
|
||||
|
||||
next();
|
||||
});
|
||||
};
|
||||
ghost.app().listen(3333, function () {
|
||||
console.log("Express server listening on port " + 3333);
|
||||
|
||||
disableCachedResult = function (req, res, next) {
|
||||
res.set({
|
||||
"Cache-Control": "no-cache, must-revalidate",
|
||||
"Expires": "Sat, 26 Jul 1997 05:00:00 GMT"
|
||||
});
|
||||
// Let everyone know we have finished loading
|
||||
loading.resolve();
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
// Expose the promise we will resolve after our pre-loading
|
||||
ghost.loaded = loading.promise;
|
||||
|
||||
when.all([ghost.init(), filters.loadCoreFilters(ghost), helpers.loadCoreHelpers(ghost)]).then(function () {
|
||||
|
||||
// post init config
|
||||
ghost.app().use(ghostLocals);
|
||||
|
||||
/**
|
||||
* API routes..
|
||||
* @todo auth should be public auth not user auth
|
||||
*/
|
||||
ghost.app().get('/api/v0.1/posts', authAPI, disableCachedResult, api.requestHandler(api.posts.browse));
|
||||
ghost.app().post('/api/v0.1/posts', authAPI, disableCachedResult, api.requestHandler(api.posts.add));
|
||||
ghost.app().get('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.read));
|
||||
ghost.app().put('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.edit));
|
||||
ghost.app().del('/api/v0.1/posts/:id', authAPI, disableCachedResult, api.requestHandler(api.posts.destroy));
|
||||
ghost.app().get('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.browse));
|
||||
ghost.app().get('/api/v0.1/settings/:key', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.read));
|
||||
ghost.app().put('/api/v0.1/settings', authAPI, disableCachedResult, api.cachedSettingsRequestHandler(api.settings.edit));
|
||||
|
||||
/**
|
||||
* Admin routes..
|
||||
* @todo put these somewhere in admin
|
||||
*/
|
||||
ghost.app().get(/^\/logout\/?$/, admin.logout);
|
||||
ghost.app().get('/ghost/login/', admin.login);
|
||||
ghost.app().get('/ghost/signup/', admin.signup);
|
||||
ghost.app().post('/ghost/login/', admin.auth);
|
||||
ghost.app().post('/ghost/signup/', admin.doRegister);
|
||||
ghost.app().get('/ghost/editor/:id', auth, admin.editor);
|
||||
ghost.app().get('/ghost/editor', auth, admin.editor);
|
||||
ghost.app().get('/ghost/content', auth, admin.content);
|
||||
ghost.app().get('/ghost/settings*', auth, admin.settings);
|
||||
ghost.app().get('/ghost/debug', auth, admin.debug.index);
|
||||
ghost.app().get('/ghost/debug/db/export/', auth, admin.debug['export']);
|
||||
ghost.app().post('/ghost/debug/db/import/', auth, admin.debug.import);
|
||||
ghost.app().get('/ghost/debug/db/reset/', auth, admin.debug.reset);
|
||||
ghost.app().get(/^\/(ghost$|(ghost-admin|admin|wp-admin|dashboard|login)\/?)/, auth, function (req, res) {
|
||||
res.redirect('/ghost/');
|
||||
});
|
||||
ghost.app().get('/ghost/', auth, admin.index);
|
||||
|
||||
/**
|
||||
* Frontend routes..
|
||||
* @todo dynamic routing, homepage generator, filters ETC ETC
|
||||
*/
|
||||
ghost.app().get('/:slug', frontend.single);
|
||||
ghost.app().get('/', frontend.homepage);
|
||||
|
||||
ghost.app().listen(3333, function () {
|
||||
console.log("Express server listening on port " + 3333);
|
||||
|
||||
// Let everyone know we have finished loading
|
||||
loading.resolve();
|
||||
});
|
||||
|
||||
}, errors.logAndThrowError);
|
||||
}());
|
||||
}, errors.logAndThrowError);
|
162
config.js
162
config.js
@ -3,104 +3,100 @@
|
||||
/**
|
||||
* global module
|
||||
**/
|
||||
(function () {
|
||||
"use strict";
|
||||
var path = require('path'),
|
||||
config;
|
||||
|
||||
var path = require('path'),
|
||||
config;
|
||||
/**
|
||||
* @module config
|
||||
* @type {Object}
|
||||
*/
|
||||
config = {};
|
||||
|
||||
/**
|
||||
* @module config
|
||||
* @type {Object}
|
||||
*/
|
||||
config = {};
|
||||
// ## Admin settings
|
||||
|
||||
// ## Admin settings
|
||||
/**
|
||||
* @property {string} defaultLang
|
||||
*/
|
||||
config.defaultLang = 'en';
|
||||
|
||||
/**
|
||||
* @property {string} defaultLang
|
||||
*/
|
||||
config.defaultLang = 'en';
|
||||
/**
|
||||
* @property {boolean} forceI18n
|
||||
*/
|
||||
config.forceI18n = true;
|
||||
|
||||
/**
|
||||
* @property {boolean} forceI18n
|
||||
*/
|
||||
config.forceI18n = true;
|
||||
// ## Themes
|
||||
|
||||
// ## Themes
|
||||
/**
|
||||
* @property {string} themeDir
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {string} themeDir
|
||||
*/
|
||||
// Themes
|
||||
config.themeDir = 'themes';
|
||||
|
||||
// Themes
|
||||
config.themeDir = 'themes';
|
||||
/**
|
||||
* @property {string} activeTheme
|
||||
*/
|
||||
config.activeTheme = 'casper';
|
||||
|
||||
/**
|
||||
* @property {string} activeTheme
|
||||
*/
|
||||
config.activeTheme = 'casper';
|
||||
// ## Homepage settings
|
||||
/**
|
||||
* @module homepage
|
||||
* @type {Object}
|
||||
*/
|
||||
config.homepage = {};
|
||||
|
||||
// ## Homepage settings
|
||||
/**
|
||||
* @module homepage
|
||||
* @type {Object}
|
||||
*/
|
||||
config.homepage = {};
|
||||
/**
|
||||
* @property {number} features
|
||||
*/
|
||||
config.homepage.features = 1;
|
||||
|
||||
/**
|
||||
* @property {number} features
|
||||
*/
|
||||
config.homepage.features = 1;
|
||||
/**
|
||||
* @property {number} posts
|
||||
*/
|
||||
config.homepage.posts = 4;
|
||||
|
||||
/**
|
||||
* @property {number} posts
|
||||
*/
|
||||
config.homepage.posts = 4;
|
||||
config.database = {
|
||||
testing: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/tests.db')
|
||||
}
|
||||
},
|
||||
|
||||
config.database = {
|
||||
testing: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/tests.db')
|
||||
}
|
||||
travis: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/tests.db')
|
||||
}
|
||||
// debug: true
|
||||
},
|
||||
|
||||
development: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/testdb.db')
|
||||
},
|
||||
debug: false
|
||||
// debug: true
|
||||
},
|
||||
|
||||
travis: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/tests.db')
|
||||
}
|
||||
// debug: true
|
||||
},
|
||||
staging: {},
|
||||
|
||||
development: {
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: path.join(__dirname, '/core/shared/data/testdb.db')
|
||||
},
|
||||
debug: false
|
||||
// debug: true
|
||||
},
|
||||
production: {}
|
||||
};
|
||||
|
||||
staging: {},
|
||||
/**
|
||||
* @property {Array} nav
|
||||
*/
|
||||
config.nav = [{
|
||||
title: 'Home',
|
||||
url: '/'
|
||||
}, {
|
||||
title: 'Admin',
|
||||
url: '/ghost'
|
||||
}];
|
||||
|
||||
production: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @property {Array} nav
|
||||
*/
|
||||
config.nav = [{
|
||||
title: 'Home',
|
||||
url: '/'
|
||||
}, {
|
||||
title: 'Admin',
|
||||
url: '/ghost'
|
||||
}];
|
||||
|
||||
/**
|
||||
* @property {Object} exports
|
||||
*/
|
||||
module.exports = config;
|
||||
}());
|
||||
/**
|
||||
* @property {Object} exports
|
||||
*/
|
||||
module.exports = config;
|
@ -1,273 +1,268 @@
|
||||
/*global require, module */
|
||||
(function () {
|
||||
"use strict";
|
||||
var Ghost = require('../../ghost'),
|
||||
dataExport = require('../../shared/data/export'),
|
||||
dataImport = require('../../shared/data/import'),
|
||||
_ = require('underscore'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
when = require('when'),
|
||||
nodefn = require('when/node/function'),
|
||||
api = require('../../shared/api'),
|
||||
|
||||
var Ghost = require('../../ghost'),
|
||||
dataExport = require('../../shared/data/export'),
|
||||
dataImport = require('../../shared/data/import'),
|
||||
_ = require('underscore'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
when = require('when'),
|
||||
nodefn = require('when/node/function'),
|
||||
api = require('../../shared/api'),
|
||||
ghost = new Ghost(),
|
||||
dataProvider = ghost.dataProvider,
|
||||
adminNavbar,
|
||||
adminControllers;
|
||||
|
||||
ghost = new Ghost(),
|
||||
dataProvider = ghost.dataProvider,
|
||||
adminNavbar,
|
||||
adminControllers;
|
||||
|
||||
// TODO: combine path/navClass to single "slug(?)" variable with no prefix
|
||||
adminNavbar = {
|
||||
dashboard: {
|
||||
name: 'Dashboard',
|
||||
navClass: 'dashboard',
|
||||
key: 'admin.navbar.dashboard',
|
||||
// defaultString: 'dashboard',
|
||||
path: '/'
|
||||
},
|
||||
content: {
|
||||
name: 'Content',
|
||||
navClass: 'content',
|
||||
key: 'admin.navbar.content',
|
||||
// defaultString: 'content',
|
||||
path: '/content/'
|
||||
},
|
||||
add: {
|
||||
name: 'New Post',
|
||||
navClass: 'editor',
|
||||
key: 'admin.navbar.editor',
|
||||
// defaultString: 'editor',
|
||||
path: '/editor/'
|
||||
},
|
||||
settings: {
|
||||
name: 'Settings',
|
||||
navClass: 'settings',
|
||||
key: 'admin.navbar.settings',
|
||||
// defaultString: 'settings',
|
||||
path: '/settings/'
|
||||
}
|
||||
};
|
||||
|
||||
ghost.doFilter('messWithAdmin', adminNavbar, function () {
|
||||
console.log('the dofilter hook called in /core/admin/controllers/index.js');
|
||||
});
|
||||
|
||||
// TODO - make this a util or helper
|
||||
function setSelected(list, name) {
|
||||
_.each(list, function (item, key) {
|
||||
item.selected = key === name;
|
||||
});
|
||||
return list;
|
||||
// TODO: combine path/navClass to single "slug(?)" variable with no prefix
|
||||
adminNavbar = {
|
||||
dashboard: {
|
||||
name: 'Dashboard',
|
||||
navClass: 'dashboard',
|
||||
key: 'admin.navbar.dashboard',
|
||||
// defaultString: 'dashboard',
|
||||
path: '/'
|
||||
},
|
||||
content: {
|
||||
name: 'Content',
|
||||
navClass: 'content',
|
||||
key: 'admin.navbar.content',
|
||||
// defaultString: 'content',
|
||||
path: '/content/'
|
||||
},
|
||||
add: {
|
||||
name: 'New Post',
|
||||
navClass: 'editor',
|
||||
key: 'admin.navbar.editor',
|
||||
// defaultString: 'editor',
|
||||
path: '/editor/'
|
||||
},
|
||||
settings: {
|
||||
name: 'Settings',
|
||||
navClass: 'settings',
|
||||
key: 'admin.navbar.settings',
|
||||
// defaultString: 'settings',
|
||||
path: '/settings/'
|
||||
}
|
||||
};
|
||||
|
||||
adminControllers = {
|
||||
'login': function (req, res) {
|
||||
res.render('login', {
|
||||
bodyClass: 'ghost-login',
|
||||
hideNavbar: true,
|
||||
adminNav: setSelected(adminNavbar, 'login')
|
||||
});
|
||||
},
|
||||
'auth': function (req, res) {
|
||||
api.users.check({email: req.body.email, pw: req.body.password}).then(function (user) {
|
||||
console.log('user found: ', user);
|
||||
req.session.user = "ghostadmin";
|
||||
res.redirect(req.query.redirect || '/ghost/');
|
||||
}, function (error) {
|
||||
// Do something here to signal the reason for an error
|
||||
req.flash('error', error.message);
|
||||
res.redirect('/ghost/login/');
|
||||
});
|
||||
},
|
||||
'signup': function (req, res) {
|
||||
res.render('signup', {
|
||||
bodyClass: 'ghost-login',
|
||||
hideNavbar: true,
|
||||
adminNav: setSelected(adminNavbar, 'login')
|
||||
});
|
||||
},
|
||||
'doRegister': function (req, res) {
|
||||
var email = req.body.email_address,
|
||||
password = req.body.password;
|
||||
ghost.doFilter('messWithAdmin', adminNavbar, function () {
|
||||
console.log('the dofilter hook called in /core/admin/controllers/index.js');
|
||||
});
|
||||
|
||||
if (email !== '' && password.length > 5) {
|
||||
api.users.add({
|
||||
email_address: email,
|
||||
password: password
|
||||
}).then(function (user) {
|
||||
console.log('user added', user);
|
||||
res.redirect('/ghost/login/');
|
||||
}, function (error) {
|
||||
req.flash('error', error.message);
|
||||
res.redirect('/ghost/signup/');
|
||||
});
|
||||
} else {
|
||||
req.flash('error', "The password is too short. Have at least 6 characters in there");
|
||||
res.redirect('back');
|
||||
}
|
||||
},
|
||||
'logout': function (req, res) {
|
||||
delete req.session.user;
|
||||
req.flash('success', "You were successfully logged out");
|
||||
// TODO - make this a util or helper
|
||||
function setSelected(list, name) {
|
||||
_.each(list, function (item, key) {
|
||||
item.selected = key === name;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
adminControllers = {
|
||||
'login': function (req, res) {
|
||||
res.render('login', {
|
||||
bodyClass: 'ghost-login',
|
||||
hideNavbar: true,
|
||||
adminNav: setSelected(adminNavbar, 'login')
|
||||
});
|
||||
},
|
||||
'auth': function (req, res) {
|
||||
api.users.check({email: req.body.email, pw: req.body.password}).then(function (user) {
|
||||
console.log('user found: ', user);
|
||||
req.session.user = "ghostadmin";
|
||||
res.redirect(req.query.redirect || '/ghost/');
|
||||
}, function (error) {
|
||||
// Do something here to signal the reason for an error
|
||||
req.flash('error', error.message);
|
||||
res.redirect('/ghost/login/');
|
||||
},
|
||||
'index': function (req, res) {
|
||||
res.render('dashboard', {
|
||||
bodyClass: 'dashboard',
|
||||
adminNav: setSelected(adminNavbar, 'dashboard')
|
||||
});
|
||||
},
|
||||
'signup': function (req, res) {
|
||||
res.render('signup', {
|
||||
bodyClass: 'ghost-login',
|
||||
hideNavbar: true,
|
||||
adminNav: setSelected(adminNavbar, 'login')
|
||||
});
|
||||
},
|
||||
'doRegister': function (req, res) {
|
||||
var email = req.body.email_address,
|
||||
password = req.body.password;
|
||||
|
||||
if (email !== '' && password.length > 5) {
|
||||
api.users.add({
|
||||
email_address: email,
|
||||
password: password
|
||||
}).then(function (user) {
|
||||
console.log('user added', user);
|
||||
res.redirect('/ghost/login/');
|
||||
}, function (error) {
|
||||
req.flash('error', error.message);
|
||||
res.redirect('/ghost/signup/');
|
||||
});
|
||||
} else {
|
||||
req.flash('error', "The password is too short. Have at least 6 characters in there");
|
||||
res.redirect('back');
|
||||
}
|
||||
},
|
||||
'logout': function (req, res) {
|
||||
delete req.session.user;
|
||||
req.flash('success', "You were successfully logged out");
|
||||
res.redirect('/ghost/login/');
|
||||
},
|
||||
'index': function (req, res) {
|
||||
res.render('dashboard', {
|
||||
bodyClass: 'dashboard',
|
||||
adminNav: setSelected(adminNavbar, 'dashboard')
|
||||
});
|
||||
},
|
||||
'editor': function (req, res) {
|
||||
if (req.params.id !== undefined) {
|
||||
api.posts.read({id: parseInt(req.params.id, 10)})
|
||||
.then(function (post) {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'content'),
|
||||
title: post.get('title'),
|
||||
content: post.get('content')
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'add')
|
||||
});
|
||||
}
|
||||
},
|
||||
'content': function (req, res) {
|
||||
api.posts.browse({status: req.params.status || 'all'})
|
||||
.then(function (page) {
|
||||
res.render('content', {
|
||||
bodyClass: 'manage',
|
||||
adminNav: setSelected(adminNavbar, 'content'),
|
||||
posts: page.posts
|
||||
});
|
||||
});
|
||||
},
|
||||
'settings': function (req, res) {
|
||||
api.settings.browse()
|
||||
.then(function (settings) {
|
||||
res.render('settings', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings'),
|
||||
settings: settings
|
||||
});
|
||||
});
|
||||
},
|
||||
'debug': { /* ugly temporary stuff for managing the app before it's properly finished */
|
||||
index: function (req, res) {
|
||||
res.render('debug', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings')
|
||||
});
|
||||
},
|
||||
'editor': function (req, res) {
|
||||
if (req.params.id !== undefined) {
|
||||
api.posts.read({id: parseInt(req.params.id, 10)})
|
||||
.then(function (post) {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'content'),
|
||||
title: post.get('title'),
|
||||
content: post.get('content')
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'add')
|
||||
});
|
||||
}
|
||||
},
|
||||
'content': function (req, res) {
|
||||
api.posts.browse({status: req.params.status || 'all'})
|
||||
.then(function (page) {
|
||||
res.render('content', {
|
||||
bodyClass: 'manage',
|
||||
adminNav: setSelected(adminNavbar, 'content'),
|
||||
posts: page.posts
|
||||
});
|
||||
});
|
||||
},
|
||||
'settings': function (req, res) {
|
||||
api.settings.browse()
|
||||
.then(function (settings) {
|
||||
res.render('settings', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings'),
|
||||
settings: settings
|
||||
});
|
||||
});
|
||||
},
|
||||
'debug': { /* ugly temporary stuff for managing the app before it's properly finished */
|
||||
index: function (req, res) {
|
||||
res.render('debug', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings')
|
||||
});
|
||||
},
|
||||
'export': function (req, res) {
|
||||
// Get current version from settings
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
// Export the current versions data
|
||||
return dataExport(setting.value);
|
||||
}, function () {
|
||||
// If no setting, assume 001
|
||||
return dataExport("001");
|
||||
})
|
||||
.then(function (exportedData) {
|
||||
// Save the exported data to the file system for download
|
||||
var fileName = path.resolve(__dirname + '/../../shared/data/export/exported-' + (new Date().getTime()) + '.json');
|
||||
'export': function (req, res) {
|
||||
// Get current version from settings
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
// Export the current versions data
|
||||
return dataExport(setting.value);
|
||||
}, function () {
|
||||
// If no setting, assume 001
|
||||
return dataExport("001");
|
||||
})
|
||||
.then(function (exportedData) {
|
||||
// Save the exported data to the file system for download
|
||||
var fileName = path.resolve(__dirname + '/../../shared/data/export/exported-' + (new Date().getTime()) + '.json');
|
||||
|
||||
return nodefn.call(fs.writeFile, fileName, JSON.stringify(exportedData)).then(function () {
|
||||
return when(fileName);
|
||||
});
|
||||
})
|
||||
.then(function (exportedFilePath) {
|
||||
// Send the exported data file
|
||||
res.download(exportedFilePath, 'GhostData.json');
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
// Notify of an error if it occurs
|
||||
req.flash("error", error.message || error);
|
||||
res.redirect("/ghost/debug");
|
||||
return nodefn.call(fs.writeFile, fileName, JSON.stringify(exportedData)).then(function () {
|
||||
return when(fileName);
|
||||
});
|
||||
},
|
||||
'import': function (req, res) {
|
||||
if (!req.files.importfile) {
|
||||
})
|
||||
.then(function (exportedFilePath) {
|
||||
// Send the exported data file
|
||||
res.download(exportedFilePath, 'GhostData.json');
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
// Notify of an error if it occurs
|
||||
req.flash("error", "Must select a file to import");
|
||||
return res.redirect("/ghost/debug");
|
||||
}
|
||||
|
||||
// Get the current version for importing
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
return when(setting.value);
|
||||
}, function () {
|
||||
return when("001");
|
||||
})
|
||||
.then(function (currentVersion) {
|
||||
// Read the file contents
|
||||
return nodefn.call(fs.readFile, req.files.importfile.path)
|
||||
.then(function (fileContents) {
|
||||
var importData;
|
||||
|
||||
// Parse the json data
|
||||
try {
|
||||
importData = JSON.parse(fileContents);
|
||||
} catch (e) {
|
||||
return when.reject(new Error("Failed to parse the import file"));
|
||||
}
|
||||
|
||||
if (!importData.meta || !importData.meta.version) {
|
||||
return when.reject(new Error("Import data does not specify version"));
|
||||
}
|
||||
|
||||
// Import for the current version
|
||||
return dataImport(currentVersion, importData);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
req.flash("success", "Data imported");
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
// Notify of an error if it occurs
|
||||
req.flash("error", error.message || error);
|
||||
})
|
||||
.then(function () {
|
||||
res.redirect("/ghost/debug");
|
||||
});
|
||||
},
|
||||
'reset': function (req, res) {
|
||||
// Grab the current version so we can get the migration
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
var migration = require("../../shared/data/migration/" + setting.value);
|
||||
|
||||
// Run the downward migration
|
||||
return migration.down();
|
||||
}, function () {
|
||||
// If no version in the DB, assume 001
|
||||
var migration = require("../../shared/data/migration/001");
|
||||
|
||||
// Run the downward migration
|
||||
return migration.down();
|
||||
})
|
||||
.then(function () {
|
||||
// Re-initalize the providers (should run the migration up again)
|
||||
return dataProvider.init();
|
||||
})
|
||||
.then(function () {
|
||||
req.flash("success", "Database reset");
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
req.flash("error", error.message || error);
|
||||
})
|
||||
.then(function () {
|
||||
res.redirect('/ghost/debug');
|
||||
});
|
||||
req.flash("error", error.message || error);
|
||||
res.redirect("/ghost/debug");
|
||||
});
|
||||
},
|
||||
'import': function (req, res) {
|
||||
if (!req.files.importfile) {
|
||||
// Notify of an error if it occurs
|
||||
req.flash("error", "Must select a file to import");
|
||||
return res.redirect("/ghost/debug");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = adminControllers;
|
||||
}());
|
||||
// Get the current version for importing
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
return when(setting.value);
|
||||
}, function () {
|
||||
return when("001");
|
||||
})
|
||||
.then(function (currentVersion) {
|
||||
// Read the file contents
|
||||
return nodefn.call(fs.readFile, req.files.importfile.path)
|
||||
.then(function (fileContents) {
|
||||
var importData;
|
||||
|
||||
// Parse the json data
|
||||
try {
|
||||
importData = JSON.parse(fileContents);
|
||||
} catch (e) {
|
||||
return when.reject(new Error("Failed to parse the import file"));
|
||||
}
|
||||
|
||||
if (!importData.meta || !importData.meta.version) {
|
||||
return when.reject(new Error("Import data does not specify version"));
|
||||
}
|
||||
|
||||
// Import for the current version
|
||||
return dataImport(currentVersion, importData);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
req.flash("success", "Data imported");
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
// Notify of an error if it occurs
|
||||
req.flash("error", error.message || error);
|
||||
})
|
||||
.then(function () {
|
||||
res.redirect("/ghost/debug");
|
||||
});
|
||||
},
|
||||
'reset': function (req, res) {
|
||||
// Grab the current version so we can get the migration
|
||||
api.settings.read({ key: "currentVersion" })
|
||||
.then(function (setting) {
|
||||
var migration = require("../../shared/data/migration/" + setting.value);
|
||||
|
||||
// Run the downward migration
|
||||
return migration.down();
|
||||
}, function () {
|
||||
// If no version in the DB, assume 001
|
||||
var migration = require("../../shared/data/migration/001");
|
||||
|
||||
// Run the downward migration
|
||||
return migration.down();
|
||||
})
|
||||
.then(function () {
|
||||
// Re-initalize the providers (should run the migration up again)
|
||||
return dataProvider.init();
|
||||
})
|
||||
.then(function () {
|
||||
req.flash("success", "Database reset");
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
req.flash("error", error.message || error);
|
||||
})
|
||||
.then(function () {
|
||||
res.redirect('/ghost/debug');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = adminControllers;
|
@ -3,31 +3,28 @@
|
||||
*/
|
||||
|
||||
/*global require, module */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Ghost = require('../../ghost'),
|
||||
api = require('../../shared/api'),
|
||||
var Ghost = require('../../ghost'),
|
||||
api = require('../../shared/api'),
|
||||
|
||||
ghost = new Ghost(),
|
||||
frontendControllers;
|
||||
ghost = new Ghost(),
|
||||
frontendControllers;
|
||||
|
||||
frontendControllers = {
|
||||
'homepage': function (req, res) {
|
||||
api.posts.browse().then(function (page) {
|
||||
ghost.doFilter('prePostsRender', page.posts, function (posts) {
|
||||
res.render('index', {posts: posts});
|
||||
});
|
||||
frontendControllers = {
|
||||
'homepage': function (req, res) {
|
||||
api.posts.browse().then(function (page) {
|
||||
ghost.doFilter('prePostsRender', page.posts, function (posts) {
|
||||
res.render('index', {posts: posts});
|
||||
});
|
||||
},
|
||||
'single': function (req, res) {
|
||||
api.posts.read({'slug': req.params.slug}).then(function (post) {
|
||||
ghost.doFilter('prePostsRender', post.toJSON(), function (post) {
|
||||
res.render('single', {post: post});
|
||||
});
|
||||
});
|
||||
},
|
||||
'single': function (req, res) {
|
||||
api.posts.read({'slug': req.params.slug}).then(function (post) {
|
||||
ghost.doFilter('prePostsRender', post.toJSON(), function (post) {
|
||||
res.render('single', {post: post});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = frontendControllers;
|
||||
}());
|
||||
module.exports = frontendControllers;
|
@ -1,31 +1,26 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var _ = require('underscore'),
|
||||
defaultCoreFilterPriority = 4,
|
||||
coreFilters;
|
||||
|
||||
var _ = require('underscore'),
|
||||
defaultCoreFilterPriority = 4,
|
||||
coreFilters;
|
||||
coreFilters = function (ghost) {
|
||||
ghost.registerFilter('ghostNavItems', defaultCoreFilterPriority, function (args) {
|
||||
var selectedItem;
|
||||
|
||||
coreFilters = function (ghost) {
|
||||
ghost.registerFilter('ghostNavItems', defaultCoreFilterPriority, function (args) {
|
||||
var selectedItem;
|
||||
// Set the nav items based on the config
|
||||
args.navItems = ghost.config().nav;
|
||||
|
||||
// Set the nav items based on the config
|
||||
args.navItems = ghost.config().nav;
|
||||
|
||||
// Mark the current selected Item
|
||||
selectedItem = _.find(args.navItems, function (item) {
|
||||
// TODO: Better selection determination?
|
||||
return item.url === args.path;
|
||||
});
|
||||
|
||||
if (selectedItem) {
|
||||
selectedItem.active = true;
|
||||
}
|
||||
|
||||
return args;
|
||||
// Mark the current selected Item
|
||||
selectedItem = _.find(args.navItems, function (item) {
|
||||
// TODO: Better selection determination?
|
||||
return item.url === args.path;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.loadCoreFilters = coreFilters;
|
||||
if (selectedItem) {
|
||||
selectedItem.active = true;
|
||||
}
|
||||
|
||||
}());
|
||||
return args;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.loadCoreFilters = coreFilters;
|
@ -1,53 +1,49 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
_ = require('underscore'),
|
||||
handlebars = require('express-hbs').handlebars,
|
||||
nodefn = require('when/node/function'),
|
||||
GhostNavHelper;
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
_ = require('underscore'),
|
||||
handlebars = require('express-hbs').handlebars,
|
||||
nodefn = require('when/node/function'),
|
||||
GhostNavHelper;
|
||||
GhostNavHelper = function (navTemplate) {
|
||||
// Bind the context for our methods.
|
||||
_.bindAll(this, 'compileTemplate', 'renderNavItems');
|
||||
|
||||
GhostNavHelper = function (navTemplate) {
|
||||
// Bind the context for our methods.
|
||||
_.bindAll(this, 'compileTemplate', 'renderNavItems');
|
||||
if (_.isFunction(navTemplate)) {
|
||||
this.navTemplateFunc = navTemplate;
|
||||
} else {
|
||||
this.navTemplatePath = navTemplate;
|
||||
}
|
||||
};
|
||||
|
||||
if (_.isFunction(navTemplate)) {
|
||||
this.navTemplateFunc = navTemplate;
|
||||
} else {
|
||||
this.navTemplatePath = navTemplate;
|
||||
}
|
||||
};
|
||||
GhostNavHelper.prototype.compileTemplate = function (templatePath) {
|
||||
var self = this;
|
||||
|
||||
GhostNavHelper.prototype.compileTemplate = function (templatePath) {
|
||||
var self = this;
|
||||
// Allow people to overwrite the navTemplatePath
|
||||
templatePath = templatePath || this.navTemplatePath;
|
||||
|
||||
// Allow people to overwrite the navTemplatePath
|
||||
templatePath = templatePath || this.navTemplatePath;
|
||||
return nodefn.call(fs.readFile, templatePath).then(function (navTemplateContents) {
|
||||
// TODO: Can handlebars compile async?
|
||||
self.navTemplateFunc = handlebars.compile(navTemplateContents.toString());
|
||||
});
|
||||
};
|
||||
|
||||
return nodefn.call(fs.readFile, templatePath).then(function (navTemplateContents) {
|
||||
// TODO: Can handlebars compile async?
|
||||
self.navTemplateFunc = handlebars.compile(navTemplateContents.toString());
|
||||
});
|
||||
};
|
||||
GhostNavHelper.prototype.renderNavItems = function (navItems) {
|
||||
var output;
|
||||
|
||||
GhostNavHelper.prototype.renderNavItems = function (navItems) {
|
||||
var output;
|
||||
output = this.navTemplateFunc({links: navItems});
|
||||
|
||||
output = this.navTemplateFunc({links: navItems});
|
||||
return output;
|
||||
};
|
||||
|
||||
return output;
|
||||
};
|
||||
// A static helper method for registering with ghost
|
||||
GhostNavHelper.registerWithGhost = function (ghost) {
|
||||
var templatePath = path.join(ghost.paths().frontendViews, 'nav.hbs'),
|
||||
ghostNavHelper = new GhostNavHelper(templatePath);
|
||||
|
||||
// A static helper method for registering with ghost
|
||||
GhostNavHelper.registerWithGhost = function (ghost) {
|
||||
var templatePath = path.join(ghost.paths().frontendViews, 'nav.hbs'),
|
||||
ghostNavHelper = new GhostNavHelper(templatePath);
|
||||
return ghostNavHelper.compileTemplate().then(function () {
|
||||
ghost.registerThemeHelper("ghostNav", ghostNavHelper.renderNavItems);
|
||||
});
|
||||
};
|
||||
|
||||
return ghostNavHelper.compileTemplate().then(function () {
|
||||
ghost.registerThemeHelper("ghostNav", ghostNavHelper.renderNavItems);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = GhostNavHelper;
|
||||
}());
|
||||
module.exports = GhostNavHelper;
|
@ -1,127 +1,121 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var _ = require('underscore'),
|
||||
moment = require('moment'),
|
||||
when = require('when'),
|
||||
navHelper = require('./ghostNav'),
|
||||
hbs = require('express-hbs'),
|
||||
coreHelpers;
|
||||
|
||||
var _ = require('underscore'),
|
||||
moment = require('moment'),
|
||||
when = require('when'),
|
||||
navHelper = require('./ghostNav'),
|
||||
hbs = require('express-hbs'),
|
||||
coreHelpers;
|
||||
coreHelpers = function (ghost) {
|
||||
/**
|
||||
* [ description]
|
||||
* @todo ghost core helpers + a way for themes to register them
|
||||
* @param {Object} context date object
|
||||
* @param {*} block
|
||||
* @return {Object} A Moment time / date object
|
||||
*/
|
||||
ghost.registerThemeHelper('dateFormat', function (context, block) {
|
||||
var f = block.hash.format || "MMM Do, YYYY";
|
||||
return moment(context).format(f);
|
||||
});
|
||||
|
||||
coreHelpers = function (ghost) {
|
||||
/**
|
||||
* [ description]
|
||||
* @todo ghost core helpers + a way for themes to register them
|
||||
* @param {Object} context date object
|
||||
* @param {*} block
|
||||
* @return {Object} A Moment time / date object
|
||||
*/
|
||||
ghost.registerThemeHelper('dateFormat', function (context, block) {
|
||||
var f = block.hash.format || "MMM Do, YYYY";
|
||||
return moment(context).format(f);
|
||||
});
|
||||
/**
|
||||
* [ description]
|
||||
*
|
||||
* @param String key
|
||||
* @param String default translation
|
||||
* @param {Object} options
|
||||
* @return String A correctly internationalised string
|
||||
*/
|
||||
ghost.registerThemeHelper('e', function (key, defaultString, options) {
|
||||
var output;
|
||||
|
||||
/**
|
||||
* [ description]
|
||||
*
|
||||
* @param String key
|
||||
* @param String default translation
|
||||
* @param {Object} options
|
||||
* @return String A correctly internationalised string
|
||||
*/
|
||||
ghost.registerThemeHelper('e', function (key, defaultString, options) {
|
||||
var output;
|
||||
if (ghost.config().defaultLang === 'en' && _.isEmpty(options.hash) && !ghost.config().forceI18n) {
|
||||
output = defaultString;
|
||||
} else {
|
||||
output = ghost.polyglot().t(key, options.hash);
|
||||
}
|
||||
|
||||
if (ghost.config().defaultLang === 'en' && _.isEmpty(options.hash) && !ghost.config().forceI18n) {
|
||||
output = defaultString;
|
||||
return output;
|
||||
});
|
||||
|
||||
ghost.registerThemeHelper('json', function (object, options) {
|
||||
return JSON.stringify(object);
|
||||
});
|
||||
|
||||
ghost.registerThemeHelper('foreach', function (context, options) {
|
||||
var fn = options.fn,
|
||||
inverse = options.inverse,
|
||||
i = 0,
|
||||
j = 0,
|
||||
columns = options.hash.columns,
|
||||
key,
|
||||
ret = "",
|
||||
data;
|
||||
|
||||
if (options.data) {
|
||||
data = hbs.handlebars.createFrame(options.data);
|
||||
}
|
||||
|
||||
function setKeys(_data, _i, _j, _columns) {
|
||||
if (_i === 0) {
|
||||
_data.first = true;
|
||||
}
|
||||
if (_i === _j - 1) {
|
||||
_data.last = true;
|
||||
}
|
||||
// first post is index zero but still needs to be odd
|
||||
if (_i % 2 === 1) {
|
||||
_data.even = true;
|
||||
} else {
|
||||
output = ghost.polyglot().t(key, options.hash);
|
||||
_data.odd = true;
|
||||
}
|
||||
|
||||
return output;
|
||||
});
|
||||
|
||||
ghost.registerThemeHelper('json', function (object, options) {
|
||||
return JSON.stringify(object);
|
||||
});
|
||||
|
||||
ghost.registerThemeHelper('foreach', function (context, options) {
|
||||
var fn = options.fn,
|
||||
inverse = options.inverse,
|
||||
i = 0,
|
||||
j = 0,
|
||||
columns = options.hash.columns,
|
||||
key,
|
||||
ret = "",
|
||||
data;
|
||||
|
||||
if (options.data) {
|
||||
data = hbs.handlebars.createFrame(options.data);
|
||||
if (_i % _columns === 0) {
|
||||
_data.rowStart = true;
|
||||
} else if (_i % _columns === (_columns - 1)) {
|
||||
_data.rowEnd = true;
|
||||
}
|
||||
|
||||
function setKeys(_data, _i, _j, _columns) {
|
||||
if (_i === 0) {
|
||||
_data.first = true;
|
||||
return _data;
|
||||
}
|
||||
if (context && typeof context === 'object') {
|
||||
if (context instanceof Array) {
|
||||
for (j = context.length; i < j; i += 1) {
|
||||
if (data) {
|
||||
data.index = i;
|
||||
data.first = data.rowEnd = data.rowStart = data.last = data.even = data.odd = false;
|
||||
data = setKeys(data, i, j, columns);
|
||||
}
|
||||
ret = ret + fn(context[i], { data: data });
|
||||
}
|
||||
if (_i === _j - 1) {
|
||||
_data.last = true;
|
||||
} else {
|
||||
for (key in context) {
|
||||
if (context.hasOwnProperty(key)) {
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
// first post is index zero but still needs to be odd
|
||||
if (_i % 2 === 1) {
|
||||
_data.even = true;
|
||||
} else {
|
||||
_data.odd = true;
|
||||
}
|
||||
if (_i % _columns === 0) {
|
||||
_data.rowStart = true;
|
||||
} else if (_i % _columns === (_columns - 1)) {
|
||||
_data.rowEnd = true;
|
||||
}
|
||||
return _data;
|
||||
}
|
||||
if (context && typeof context === 'object') {
|
||||
if (context instanceof Array) {
|
||||
for (j = context.length; i < j; i += 1) {
|
||||
for (key in context) {
|
||||
if (context.hasOwnProperty(key)) {
|
||||
if (data) {
|
||||
data.index = i;
|
||||
data.key = key;
|
||||
data.first = data.rowEnd = data.rowStart = data.last = data.even = data.odd = false;
|
||||
data = setKeys(data, i, j, columns);
|
||||
}
|
||||
ret = ret + fn(context[i], { data: data });
|
||||
}
|
||||
} else {
|
||||
for (key in context) {
|
||||
if (context.hasOwnProperty(key)) {
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
for (key in context) {
|
||||
if (context.hasOwnProperty(key)) {
|
||||
if (data) {
|
||||
data.key = key;
|
||||
data.first = data.rowEnd = data.rowStart = data.last = data.even = data.odd = false;
|
||||
data = setKeys(data, i, j, columns);
|
||||
}
|
||||
ret = ret + fn(context[key], {data: data});
|
||||
i += 1;
|
||||
}
|
||||
ret = ret + fn(context[key], {data: data});
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
ret = inverse(this);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
if (i === 0) {
|
||||
ret = inverse(this);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
|
||||
return when.all([
|
||||
// Just one async helper for now, but could be more in the future
|
||||
navHelper.registerWithGhost(ghost)
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
module.exports.loadCoreHelpers = coreHelpers;
|
||||
}());
|
||||
return when.all([
|
||||
// Just one async helper for now, but could be more in the future
|
||||
navHelper.registerWithGhost(ghost)
|
||||
]);
|
||||
};
|
||||
|
||||
module.exports.loadCoreHelpers = coreHelpers;
|
435
core/ghost.js
435
core/ghost.js
@ -1,257 +1,252 @@
|
||||
// # Ghost Module
|
||||
// Defines core methods required to build the frontend
|
||||
|
||||
/*global module, require, __dirname */
|
||||
(function () {
|
||||
"use strict";
|
||||
// ## Setup Prerequisites
|
||||
var config = require('./../config'),
|
||||
when = require('when'),
|
||||
express = require('express'),
|
||||
errors = require('../core/shared/errorHandling'),
|
||||
path = require('path'),
|
||||
hbs = require('express-hbs'),
|
||||
_ = require('underscore'),
|
||||
Polyglot = require('node-polyglot'),
|
||||
|
||||
// ## Setup Prerequisites
|
||||
var config = require('./../config'),
|
||||
when = require('when'),
|
||||
express = require('express'),
|
||||
errors = require('../core/shared/errorHandling'),
|
||||
path = require('path'),
|
||||
hbs = require('express-hbs'),
|
||||
_ = require('underscore'),
|
||||
Polyglot = require('node-polyglot'),
|
||||
models = require('./shared/models'),
|
||||
ExampleFilter = require('../content/plugins/exampleFilters'),
|
||||
|
||||
models = require('./shared/models'),
|
||||
ExampleFilter = require('../content/plugins/exampleFilters'),
|
||||
requireTree = require('./shared/require-tree'),
|
||||
themeDirectories = requireTree(path.resolve(__dirname + '../../content/themes')),
|
||||
pluginDirectories = requireTree(path.resolve(__dirname + '../../content/plugins')),
|
||||
|
||||
requireTree = require('./shared/require-tree'),
|
||||
themeDirectories = requireTree(path.resolve(__dirname + '../../content/themes')),
|
||||
pluginDirectories = requireTree(path.resolve(__dirname + '../../content/plugins')),
|
||||
Ghost,
|
||||
instance,
|
||||
defaults,
|
||||
statuses;
|
||||
|
||||
Ghost,
|
||||
instance,
|
||||
defaults,
|
||||
statuses;
|
||||
// ## Default values
|
||||
/**
|
||||
* A hash of default values to use instead of 'magic' numbers/strings.
|
||||
* @type {Object}
|
||||
*/
|
||||
defaults = {
|
||||
filterPriority: 5,
|
||||
maxPriority: 9
|
||||
};
|
||||
|
||||
// ## Default values
|
||||
/**
|
||||
* A hash of default values to use instead of 'magic' numbers/strings.
|
||||
* @type {Object}
|
||||
*/
|
||||
defaults = {
|
||||
filterPriority: 5,
|
||||
maxPriority: 9
|
||||
};
|
||||
// ## Article Statuses
|
||||
/**
|
||||
* A list of atricle status types
|
||||
* @type {Object}
|
||||
*/
|
||||
statuses = {
|
||||
'draft': 'draft',
|
||||
'complete': 'complete',
|
||||
'approved': 'approved',
|
||||
'scheduled': 'scheduled',
|
||||
'published': 'published'
|
||||
};
|
||||
|
||||
// ## Article Statuses
|
||||
/**
|
||||
* A list of atricle status types
|
||||
* @type {Object}
|
||||
*/
|
||||
statuses = {
|
||||
'draft': 'draft',
|
||||
'complete': 'complete',
|
||||
'approved': 'approved',
|
||||
'scheduled': 'scheduled',
|
||||
'published': 'published'
|
||||
};
|
||||
// ## Module Methods
|
||||
/**
|
||||
* @method Ghost
|
||||
* @returns {*}
|
||||
* @constructor
|
||||
*/
|
||||
Ghost = function () {
|
||||
var app,
|
||||
plugin,
|
||||
polyglot;
|
||||
|
||||
// ## Module Methods
|
||||
/**
|
||||
* @method Ghost
|
||||
* @returns {*}
|
||||
* @constructor
|
||||
*/
|
||||
Ghost = function () {
|
||||
var app,
|
||||
plugin,
|
||||
polyglot;
|
||||
if (!instance) {
|
||||
instance = this;
|
||||
|
||||
if (!instance) {
|
||||
instance = this;
|
||||
// Holds the filters
|
||||
instance.filterCallbacks = [];
|
||||
|
||||
// Holds the filters
|
||||
instance.filterCallbacks = [];
|
||||
// Holds the filter hooks (that are built in to Ghost Core)
|
||||
instance.filters = [];
|
||||
|
||||
// Holds the filter hooks (that are built in to Ghost Core)
|
||||
instance.filters = [];
|
||||
// Holds the theme directories temporarily
|
||||
instance.themeDirectories = {};
|
||||
|
||||
// Holds the theme directories temporarily
|
||||
instance.themeDirectories = {};
|
||||
|
||||
// Holds the plugin directories temporarily
|
||||
instance.pluginDirectories = {};
|
||||
// Holds the plugin directories temporarily
|
||||
instance.pluginDirectories = {};
|
||||
|
||||
|
||||
plugin = new ExampleFilter(instance).init();
|
||||
plugin = new ExampleFilter(instance).init();
|
||||
|
||||
app = express();
|
||||
app = express();
|
||||
|
||||
polyglot = new Polyglot();
|
||||
polyglot = new Polyglot();
|
||||
|
||||
// functionality
|
||||
// load Plugins...
|
||||
// var f = new FancyFirstChar(ghost).init();
|
||||
// functionality
|
||||
// load Plugins...
|
||||
// var f = new FancyFirstChar(ghost).init();
|
||||
|
||||
_.extend(instance, {
|
||||
app: function () { return app; },
|
||||
config: function () { return config; },
|
||||
_.extend(instance, {
|
||||
app: function () { return app; },
|
||||
config: function () { return config; },
|
||||
|
||||
// there's no management here to be sure this has loaded
|
||||
settings: function () { return instance.settingsCache; },
|
||||
dataProvider: models,
|
||||
statuses: function () { return statuses; },
|
||||
polyglot: function () { return polyglot; },
|
||||
plugin: function () { return plugin; },
|
||||
getPaths: function () {
|
||||
return when.all([themeDirectories, pluginDirectories]).then(function (paths) {
|
||||
instance.themeDirectories = paths[0];
|
||||
instance.pluginDirectories = paths[1];
|
||||
return;
|
||||
});
|
||||
},
|
||||
paths: function () {
|
||||
return {
|
||||
'activeTheme': __dirname + '/../content/' + config.themeDir + '/' + config.activeTheme + '/',
|
||||
'adminViews': __dirname + '/admin/views/',
|
||||
'frontendViews': __dirname + '/frontend/views/',
|
||||
'lang': __dirname + '/lang/',
|
||||
'availableThemes': instance.themeDirectories,
|
||||
'availablePlugins': instance.pluginDirectories
|
||||
};
|
||||
// there's no management here to be sure this has loaded
|
||||
settings: function () { return instance.settingsCache; },
|
||||
dataProvider: models,
|
||||
statuses: function () { return statuses; },
|
||||
polyglot: function () { return polyglot; },
|
||||
plugin: function () { return plugin; },
|
||||
getPaths: function () {
|
||||
return when.all([themeDirectories, pluginDirectories]).then(function (paths) {
|
||||
instance.themeDirectories = paths[0];
|
||||
instance.pluginDirectories = paths[1];
|
||||
return;
|
||||
});
|
||||
},
|
||||
paths: function () {
|
||||
return {
|
||||
'activeTheme': __dirname + '/../content/' + config.themeDir + '/' + config.activeTheme + '/',
|
||||
'adminViews': __dirname + '/admin/views/',
|
||||
'frontendViews': __dirname + '/frontend/views/',
|
||||
'lang': __dirname + '/lang/',
|
||||
'availableThemes': instance.themeDirectories,
|
||||
'availablePlugins': instance.pluginDirectories
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
Ghost.prototype.init = function () {
|
||||
var self = this;
|
||||
|
||||
return when.join(instance.dataProvider.init(), instance.getPaths()).then(function () {
|
||||
return self.updateSettingsCache();
|
||||
}, errors.logAndThrowError);
|
||||
};
|
||||
|
||||
|
||||
Ghost.prototype.updateSettingsCache = function (settings) {
|
||||
var self = this;
|
||||
|
||||
settings = settings || {};
|
||||
|
||||
if (!_.isEmpty(settings)) {
|
||||
self.settingsCache = settings;
|
||||
} else {
|
||||
// TODO: this should use api.browse
|
||||
return models.Settings.findAll().then(function (result) {
|
||||
var settings = {};
|
||||
_.map(result.models, function (member) {
|
||||
if (!settings.hasOwnProperty(member.attributes.key)) {
|
||||
settings[member.attributes.key] = member.attributes.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
return instance;
|
||||
};
|
||||
|
||||
Ghost.prototype.init = function () {
|
||||
var self = this;
|
||||
|
||||
return when.join(instance.dataProvider.init(), instance.getPaths()).then(function () {
|
||||
return self.updateSettingsCache();
|
||||
}, errors.logAndThrowError);
|
||||
};
|
||||
|
||||
|
||||
Ghost.prototype.updateSettingsCache = function (settings) {
|
||||
var self = this;
|
||||
|
||||
settings = settings || {};
|
||||
|
||||
if (!_.isEmpty(settings)) {
|
||||
self.settingsCache = settings;
|
||||
} else {
|
||||
// TODO: this should use api.browse
|
||||
return models.Settings.findAll().then(function (result) {
|
||||
var settings = {};
|
||||
_.map(result.models, function (member) {
|
||||
if (!settings.hasOwnProperty(member.attributes.key)) {
|
||||
settings[member.attributes.key] = member.attributes.value;
|
||||
}
|
||||
});
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
|
||||
self.settingsCache = settings;
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {method} hbs.registerHelper
|
||||
*/
|
||||
Ghost.prototype.registerThemeHelper = function (name, fn) {
|
||||
hbs.registerHelper(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {method} hbs.registerHelper
|
||||
*/
|
||||
Ghost.prototype.registerThemeHelper = function (name, fn) {
|
||||
hbs.registerHelper(name, fn);
|
||||
};
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerTheme = function (name, fn) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerTheme = function (name, fn) {
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerPlugin = function (name, fn) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerPlugin = function (name, fn) {
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {integer} priority
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Ghost.prototype.registerFilter = function (name, priority, fn) {
|
||||
// Curry the priority optional parameter to a default of 5
|
||||
if (_.isFunction(priority)) {
|
||||
fn = priority;
|
||||
priority = defaults.filterPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {integer} priority
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Ghost.prototype.registerFilter = function (name, priority, fn) {
|
||||
// Curry the priority optional parameter to a default of 5
|
||||
if (_.isFunction(priority)) {
|
||||
fn = priority;
|
||||
priority = defaults.filterPriority;
|
||||
this.filterCallbacks[name] = this.filterCallbacks[name] || {};
|
||||
this.filterCallbacks[name][priority] = this.filterCallbacks[name][priority] || [];
|
||||
|
||||
this.filterCallbacks[name][priority].push(fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name [description]
|
||||
* @param {*} args
|
||||
* @param {Function} callback
|
||||
* @return {method} callback
|
||||
*/
|
||||
Ghost.prototype.doFilter = function (name, args, callback) {
|
||||
var callbacks = this.filterCallbacks[name];
|
||||
|
||||
// Bug out early if no callbacks by that name
|
||||
if (!callbacks) {
|
||||
return callback(args);
|
||||
}
|
||||
|
||||
_.times(defaults.maxPriority + 1, function (priority) {
|
||||
// Bug out if no handlers on this priority
|
||||
if (!_.isArray(callbacks[priority])) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.filterCallbacks[name] = this.filterCallbacks[name] || {};
|
||||
this.filterCallbacks[name][priority] = this.filterCallbacks[name][priority] || [];
|
||||
|
||||
this.filterCallbacks[name][priority].push(fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name [description]
|
||||
* @param {*} args
|
||||
* @param {Function} callback
|
||||
* @return {method} callback
|
||||
*/
|
||||
Ghost.prototype.doFilter = function (name, args, callback) {
|
||||
var callbacks = this.filterCallbacks[name];
|
||||
|
||||
// Bug out early if no callbacks by that name
|
||||
if (!callbacks) {
|
||||
return callback(args);
|
||||
}
|
||||
|
||||
_.times(defaults.maxPriority + 1, function (priority) {
|
||||
// Bug out if no handlers on this priority
|
||||
if (!_.isArray(callbacks[priority])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call each handler for this priority level
|
||||
_.each(callbacks[priority], function (filterHandler) {
|
||||
args = filterHandler(args);
|
||||
});
|
||||
// Call each handler for this priority level
|
||||
_.each(callbacks[priority], function (filterHandler) {
|
||||
args = filterHandler(args);
|
||||
});
|
||||
});
|
||||
|
||||
callback(args);
|
||||
callback(args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise Theme
|
||||
*
|
||||
* @todo Tod (?) Old comment
|
||||
* @param {Object} app
|
||||
*/
|
||||
Ghost.prototype.initTheme = function (app) {
|
||||
var self = this;
|
||||
return function initTheme(req, res, next) {
|
||||
app.set('view engine', 'hbs');
|
||||
if (/(^\/ghost$|^\/ghost\/)/.test(req.url) === false) {
|
||||
app.engine('hbs', hbs.express3(
|
||||
{partialsDir: self.paths().activeTheme + 'partials'}
|
||||
));
|
||||
app.set('views', self.paths().activeTheme);
|
||||
} else {
|
||||
app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + 'partials'}));
|
||||
app.set('views', self.paths().adminViews);
|
||||
app.use('/core/admin/assets', express['static'](path.join(__dirname, '/admin/assets')));
|
||||
}
|
||||
app.use(express['static'](self.paths().activeTheme));
|
||||
app.use('/content/images', express['static'](path.join(__dirname, '/../content/images')));
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise Theme
|
||||
*
|
||||
* @todo Tod (?) Old comment
|
||||
* @param {Object} app
|
||||
*/
|
||||
Ghost.prototype.initTheme = function (app) {
|
||||
var self = this;
|
||||
return function initTheme(req, res, next) {
|
||||
app.set('view engine', 'hbs');
|
||||
if (/(^\/ghost$|^\/ghost\/)/.test(req.url) === false) {
|
||||
app.engine('hbs', hbs.express3(
|
||||
{partialsDir: self.paths().activeTheme + 'partials'}
|
||||
));
|
||||
app.set('views', self.paths().activeTheme);
|
||||
} else {
|
||||
app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + 'partials'}));
|
||||
app.set('views', self.paths().adminViews);
|
||||
app.use('/core/admin/assets', express['static'](path.join(__dirname, '/admin/assets')));
|
||||
}
|
||||
app.use(express['static'](self.paths().activeTheme));
|
||||
app.use('/content/images', express['static'](path.join(__dirname, '/../content/images')));
|
||||
next();
|
||||
};
|
||||
};
|
||||
// TODO: Expose the defaults for other people to see/manipulate as a static value?
|
||||
// Ghost.defaults = defaults;
|
||||
|
||||
// TODO: Expose the defaults for other people to see/manipulate as a static value?
|
||||
// Ghost.defaults = defaults;
|
||||
|
||||
module.exports = Ghost;
|
||||
}());
|
||||
module.exports = Ghost;
|
@ -1,57 +1,53 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var fs = require('fs'),
|
||||
/**
|
||||
* Create new Polyglot object
|
||||
* @type {Polyglot}
|
||||
*/
|
||||
I18n;
|
||||
|
||||
var fs = require('fs'),
|
||||
/**
|
||||
* Create new Polyglot object
|
||||
* @type {Polyglot}
|
||||
*/
|
||||
I18n;
|
||||
I18n = function (ghost) {
|
||||
|
||||
I18n = function (ghost) {
|
||||
// TODO: validate
|
||||
var lang = ghost.config().defaultLang,
|
||||
path = ghost.paths().lang,
|
||||
langFilePath = path + lang + '.json';
|
||||
|
||||
// TODO: validate
|
||||
var lang = ghost.config().defaultLang,
|
||||
path = ghost.paths().lang,
|
||||
langFilePath = path + lang + '.json';
|
||||
return function (req, res, next) {
|
||||
|
||||
return function (req, res, next) {
|
||||
if (lang === 'en') {
|
||||
// TODO: do stuff here to optimise for en
|
||||
|
||||
if (lang === 'en') {
|
||||
// TODO: do stuff here to optimise for en
|
||||
// Make jslint empty block error go away
|
||||
lang = 'en';
|
||||
}
|
||||
|
||||
// Make jslint empty block error go away
|
||||
/** TODO potentially use req.acceptedLanguages rather than the default
|
||||
* TODO handle loading language file for frontend on frontend request etc
|
||||
* TODO switch this mess to be promise driven */
|
||||
fs.stat(langFilePath, function (error) {
|
||||
if (error) {
|
||||
console.log('No language file found for language ' + lang + '. Defaulting to en');
|
||||
lang = 'en';
|
||||
}
|
||||
|
||||
/** TODO potentially use req.acceptedLanguages rather than the default
|
||||
* TODO handle loading language file for frontend on frontend request etc
|
||||
* TODO switch this mess to be promise driven */
|
||||
fs.stat(langFilePath, function (error) {
|
||||
fs.readFile(langFilePath, function (error, data) {
|
||||
if (error) {
|
||||
console.log('No language file found for language ' + lang + '. Defaulting to en');
|
||||
lang = 'en';
|
||||
throw error;
|
||||
}
|
||||
|
||||
fs.readFile(langFilePath, function (error, data) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
throw e; // TODO - do something better with the error here
|
||||
}
|
||||
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
throw e; // TODO - do something better with the error here
|
||||
}
|
||||
ghost.polyglot().extend(data);
|
||||
|
||||
ghost.polyglot().extend(data);
|
||||
|
||||
next();
|
||||
});
|
||||
next();
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.load = I18n;
|
||||
}());
|
||||
module.exports.load = I18n;
|
@ -4,155 +4,149 @@
|
||||
/**
|
||||
* This is intended to replace the old dataProvider files and should access & manipulate the models directly
|
||||
*/
|
||||
var Ghost = require('../ghost'),
|
||||
_ = require('underscore'),
|
||||
when = require('when'),
|
||||
errors = require('./errorHandling'),
|
||||
|
||||
/*global module, require */
|
||||
(function () {
|
||||
"use strict";
|
||||
ghost = new Ghost(),
|
||||
dataProvider = ghost.dataProvider,
|
||||
posts,
|
||||
users,
|
||||
settings,
|
||||
requestHandler,
|
||||
cachedSettingsRequestHandler,
|
||||
settingsObject,
|
||||
settingsCollection;
|
||||
|
||||
var Ghost = require('../ghost'),
|
||||
_ = require('underscore'),
|
||||
when = require('when'),
|
||||
errors = require('./errorHandling'),
|
||||
// # Posts
|
||||
posts = {
|
||||
// takes filter / pagination parameters
|
||||
// returns a page of posts in a json response
|
||||
browse: function browse(options) {
|
||||
return dataProvider.Post.findPage(options);
|
||||
},
|
||||
// takes an identifier (id or slug?)
|
||||
// returns a single post in a json response
|
||||
read: function read(args) {
|
||||
return dataProvider.Post.findOne(args);
|
||||
},
|
||||
// takes a json object with all the properties which should be updated
|
||||
// returns the resulting post in a json response
|
||||
edit: function edit(postData) {
|
||||
return dataProvider.Post.edit(postData);
|
||||
},
|
||||
// takes a json object representing a post,
|
||||
// returns the resulting post in a json response
|
||||
add: function add(postData) {
|
||||
return dataProvider.Post.add(postData);
|
||||
},
|
||||
// takes an identifier (id or slug?)
|
||||
// returns a json response with the id of the deleted post
|
||||
destroy: function destroy(args) {
|
||||
return dataProvider.Post.destroy(args.id);
|
||||
}
|
||||
};
|
||||
|
||||
ghost = new Ghost(),
|
||||
dataProvider = ghost.dataProvider,
|
||||
posts,
|
||||
users,
|
||||
settings,
|
||||
requestHandler,
|
||||
cachedSettingsRequestHandler,
|
||||
settingsObject,
|
||||
settingsCollection;
|
||||
// # Users
|
||||
users = {
|
||||
add: function add(postData) {
|
||||
return dataProvider.User.add(postData);
|
||||
},
|
||||
check: function check(postData) {
|
||||
return dataProvider.User.check(postData);
|
||||
}
|
||||
};
|
||||
|
||||
// # Posts
|
||||
posts = {
|
||||
// takes filter / pagination parameters
|
||||
// returns a page of posts in a json response
|
||||
browse: function browse(options) {
|
||||
return dataProvider.Post.findPage(options);
|
||||
},
|
||||
// takes an identifier (id or slug?)
|
||||
// returns a single post in a json response
|
||||
read: function read(args) {
|
||||
return dataProvider.Post.findOne(args);
|
||||
},
|
||||
// takes a json object with all the properties which should be updated
|
||||
// returns the resulting post in a json response
|
||||
edit: function edit(postData) {
|
||||
return dataProvider.Post.edit(postData);
|
||||
},
|
||||
// takes a json object representing a post,
|
||||
// returns the resulting post in a json response
|
||||
add: function add(postData) {
|
||||
return dataProvider.Post.add(postData);
|
||||
},
|
||||
// takes an identifier (id or slug?)
|
||||
// returns a json response with the id of the deleted post
|
||||
destroy: function destroy(args) {
|
||||
return dataProvider.Post.destroy(args.id);
|
||||
}
|
||||
};
|
||||
// # Settings
|
||||
|
||||
// # Users
|
||||
users = {
|
||||
add: function add(postData) {
|
||||
return dataProvider.User.add(postData);
|
||||
},
|
||||
check: function check(postData) {
|
||||
return dataProvider.User.check(postData);
|
||||
}
|
||||
};
|
||||
// Turn a settings collection into a single object/hashmap
|
||||
settingsObject = function (settings) {
|
||||
return (settings.toJSON ? settings.toJSON() : settings).reduce(function (res, item) {
|
||||
if (item.toJSON) { item = item.toJSON(); }
|
||||
if (item.key) { res[item.key] = item.value; }
|
||||
return res;
|
||||
}, {});
|
||||
};
|
||||
// Turn an object into a collection
|
||||
settingsCollection = function (settings) {
|
||||
return _.map(settings, function (value, key) {
|
||||
return { key: key, value: value };
|
||||
});
|
||||
};
|
||||
|
||||
// # Settings
|
||||
settings = {
|
||||
browse: function browse(options) {
|
||||
return dataProvider.Settings.browse(options).then(settingsObject, errors.logAndThrowError);
|
||||
},
|
||||
read: function read(options) {
|
||||
return dataProvider.Settings.read(options.key).then(function (setting) {
|
||||
if (!setting) {
|
||||
return when.reject("Unable to find setting: " + options.key);
|
||||
}
|
||||
|
||||
// Turn a settings collection into a single object/hashmap
|
||||
settingsObject = function (settings) {
|
||||
return (settings.toJSON ? settings.toJSON() : settings).reduce(function (res, item) {
|
||||
if (item.toJSON) { item = item.toJSON(); }
|
||||
if (item.key) { res[item.key] = item.value; }
|
||||
return res;
|
||||
}, {});
|
||||
};
|
||||
// Turn an object into a collection
|
||||
settingsCollection = function (settings) {
|
||||
return _.map(settings, function (value, key) {
|
||||
return { key: key, value: value };
|
||||
return _.pick(setting.toJSON(), 'key', 'value');
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
edit: function edit(settings) {
|
||||
settings = settingsCollection(settings);
|
||||
return dataProvider.Settings.edit(settings).then(settingsObject, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
|
||||
// categories: {};
|
||||
// post_categories: {};
|
||||
|
||||
|
||||
// requestHandler
|
||||
// decorator for api functions which are called via an HTTP request
|
||||
// takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response
|
||||
requestHandler = function (apiMethod) {
|
||||
return function (req, res) {
|
||||
var options = _.extend(req.body, req.query, req.params);
|
||||
return apiMethod(options).then(function (result) {
|
||||
res.json(result || {});
|
||||
}, function (error) {
|
||||
res.json(400, {error: error});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
settings = {
|
||||
browse: function browse(options) {
|
||||
return dataProvider.Settings.browse(options).then(settingsObject, errors.logAndThrowError);
|
||||
},
|
||||
read: function read(options) {
|
||||
return dataProvider.Settings.read(options.key).then(function (setting) {
|
||||
if (!setting) {
|
||||
return when.reject("Unable to find setting: " + options.key);
|
||||
}
|
||||
cachedSettingsRequestHandler = function (apiMethod) {
|
||||
if (!ghost.settings()) {
|
||||
return requestHandler(apiMethod);
|
||||
}
|
||||
|
||||
return _.pick(setting.toJSON(), 'key', 'value');
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
edit: function edit(settings) {
|
||||
settings = settingsCollection(settings);
|
||||
return dataProvider.Settings.edit(settings).then(settingsObject, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
return function (req, res) {
|
||||
var options = _.extend(req.body, req.query, req.params),
|
||||
promise;
|
||||
|
||||
// categories: {};
|
||||
// post_categories: {};
|
||||
|
||||
|
||||
// requestHandler
|
||||
// decorator for api functions which are called via an HTTP request
|
||||
// takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response
|
||||
requestHandler = function (apiMethod) {
|
||||
return function (req, res) {
|
||||
var options = _.extend(req.body, req.query, req.params);
|
||||
return apiMethod(options).then(function (result) {
|
||||
res.json(result || {});
|
||||
}, function (error) {
|
||||
res.json(400, {error: error});
|
||||
switch (apiMethod.name) {
|
||||
case 'browse':
|
||||
promise = when(ghost.settings());
|
||||
break;
|
||||
case 'read':
|
||||
promise = when(ghost.settings()[options.key]);
|
||||
break;
|
||||
case 'edit':
|
||||
promise = apiMethod(options).then(function (result) {
|
||||
ghost.updateSettingsCache(result);
|
||||
return result;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
cachedSettingsRequestHandler = function (apiMethod) {
|
||||
if (!ghost.settings()) {
|
||||
return requestHandler(apiMethod);
|
||||
break;
|
||||
default:
|
||||
errors.logAndThrowError(new Error('Unknown method name for settings API: ' + apiMethod.name));
|
||||
}
|
||||
|
||||
return function (req, res) {
|
||||
var options = _.extend(req.body, req.query, req.params),
|
||||
promise;
|
||||
|
||||
switch (apiMethod.name) {
|
||||
case 'browse':
|
||||
promise = when(ghost.settings());
|
||||
break;
|
||||
case 'read':
|
||||
promise = when(ghost.settings()[options.key]);
|
||||
break;
|
||||
case 'edit':
|
||||
promise = apiMethod(options).then(function (result) {
|
||||
ghost.updateSettingsCache(result);
|
||||
return result;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
errors.logAndThrowError(new Error('Unknown method name for settings API: ' + apiMethod.name));
|
||||
}
|
||||
return promise.then(function (result) {
|
||||
res.json(result || {});
|
||||
}, function (error) {
|
||||
res.json(400, {error: error});
|
||||
});
|
||||
};
|
||||
return promise.then(function (result) {
|
||||
res.json(result || {});
|
||||
}, function (error) {
|
||||
res.json(400, {error: error});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
module.exports.posts = posts;
|
||||
module.exports.users = users;
|
||||
module.exports.settings = settings;
|
||||
module.exports.requestHandler = requestHandler;
|
||||
module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;
|
||||
}());
|
||||
module.exports.posts = posts;
|
||||
module.exports.users = users;
|
||||
module.exports.settings = settings;
|
||||
module.exports.requestHandler = requestHandler;
|
||||
module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;
|
@ -1,49 +1,45 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var _ = require("underscore"),
|
||||
when = require("when"),
|
||||
knex = require('../../models/base').Knex,
|
||||
Exporter001;
|
||||
|
||||
var _ = require("underscore"),
|
||||
when = require("when"),
|
||||
knex = require('../../models/base').Knex,
|
||||
Exporter001;
|
||||
Exporter001 = function () {
|
||||
this.version = "001";
|
||||
};
|
||||
|
||||
Exporter001 = function () {
|
||||
this.version = "001";
|
||||
};
|
||||
|
||||
Exporter001.prototype.exportData = function () {
|
||||
var self = this,
|
||||
tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'],
|
||||
selectOps = _.map(tables, function (name) {
|
||||
return knex(name).select();
|
||||
});
|
||||
|
||||
return when.all(selectOps).then(function (tableData) {
|
||||
var exportData = {
|
||||
meta: {
|
||||
exported_on: new Date().getTime(),
|
||||
version: self.version
|
||||
},
|
||||
data: {
|
||||
// Filled below
|
||||
}
|
||||
};
|
||||
|
||||
_.each(tables, function (name, i) {
|
||||
exportData.data[name] = tableData[i];
|
||||
});
|
||||
|
||||
return when.resolve(exportData);
|
||||
}, function (err) {
|
||||
console.log("Error exporting data: " + err);
|
||||
Exporter001.prototype.exportData = function () {
|
||||
var self = this,
|
||||
tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'],
|
||||
selectOps = _.map(tables, function (name) {
|
||||
return knex(name).select();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
// Make available for unit tests
|
||||
Exporter001: Exporter001,
|
||||
return when.all(selectOps).then(function (tableData) {
|
||||
var exportData = {
|
||||
meta: {
|
||||
exported_on: new Date().getTime(),
|
||||
version: self.version
|
||||
},
|
||||
data: {
|
||||
// Filled below
|
||||
}
|
||||
};
|
||||
|
||||
exportData: function () {
|
||||
return new Exporter001().exportData();
|
||||
}
|
||||
};
|
||||
}());
|
||||
_.each(tables, function (name, i) {
|
||||
exportData.data[name] = tableData[i];
|
||||
});
|
||||
|
||||
return when.resolve(exportData);
|
||||
}, function (err) {
|
||||
console.log("Error exporting data: " + err);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
// Make available for unit tests
|
||||
Exporter001: Exporter001,
|
||||
|
||||
exportData: function () {
|
||||
return new Exporter001().exportData();
|
||||
}
|
||||
};
|
@ -1,21 +1,17 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var when = require('when');
|
||||
|
||||
var when = require('when');
|
||||
module.exports = function (version) {
|
||||
var exporter;
|
||||
|
||||
module.exports = function (version) {
|
||||
var exporter;
|
||||
try {
|
||||
exporter = require("./" + version);
|
||||
} catch (ignore) {
|
||||
// Zero effs given
|
||||
}
|
||||
|
||||
try {
|
||||
exporter = require("./" + version);
|
||||
} catch (ignore) {
|
||||
// Zero effs given
|
||||
}
|
||||
if (!exporter) {
|
||||
return when.reject("No exporter found");
|
||||
}
|
||||
|
||||
if (!exporter) {
|
||||
return when.reject("No exporter found");
|
||||
}
|
||||
|
||||
return exporter.exportData();
|
||||
};
|
||||
}());
|
||||
return exporter.exportData();
|
||||
};
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
var uuid = require('node-uuid');
|
||||
|
||||
/*global module */
|
||||
@ -159,5 +158,4 @@ module.exports = {
|
||||
"role_id": 1
|
||||
}
|
||||
]
|
||||
|
||||
};
|
||||
};
|
@ -1,58 +1,54 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var when = require("when"),
|
||||
_ = require("underscore"),
|
||||
knex = require('../../models/base').Knex,
|
||||
Importer001;
|
||||
|
||||
var when = require("when"),
|
||||
_ = require("underscore"),
|
||||
knex = require('../../models/base').Knex,
|
||||
Importer001;
|
||||
Importer001 = function () {
|
||||
_.bindAll(this, "importFrom001");
|
||||
|
||||
Importer001 = function () {
|
||||
_.bindAll(this, "importFrom001");
|
||||
this.version = "001";
|
||||
|
||||
this.version = "001";
|
||||
|
||||
this.importFrom = {
|
||||
"001": this.importFrom001
|
||||
};
|
||||
this.importFrom = {
|
||||
"001": this.importFrom001
|
||||
};
|
||||
};
|
||||
|
||||
Importer001.prototype.importData = function (data) {
|
||||
return this.canImport(data)
|
||||
.then(function (importerFunc) {
|
||||
return importerFunc(data);
|
||||
}, function (reason) {
|
||||
return when.reject(reason);
|
||||
});
|
||||
};
|
||||
|
||||
Importer001.prototype.canImport = function (data) {
|
||||
if (data.meta && data.meta.version && this.importFrom[data.meta.version]) {
|
||||
return when.resolve(this.importFrom[data.meta.version]);
|
||||
}
|
||||
|
||||
return when.reject("Unsupported version of data");
|
||||
};
|
||||
|
||||
Importer001.prototype.importFrom001 = function (data) {
|
||||
var insertOps = [];
|
||||
|
||||
_.each(data.data, function (tableData, name) {
|
||||
if (tableData && tableData.length) {
|
||||
insertOps.push(knex(name).insert(tableData));
|
||||
}
|
||||
Importer001.prototype.importData = function (data) {
|
||||
return this.canImport(data)
|
||||
.then(function (importerFunc) {
|
||||
return importerFunc(data);
|
||||
}, function (reason) {
|
||||
return when.reject(reason);
|
||||
});
|
||||
};
|
||||
|
||||
return when.all(insertOps).then(function (results) {
|
||||
return when.resolve(results);
|
||||
}, function (err) {
|
||||
console.log("Error inserting imported data: ", err.message || err, err.stack);
|
||||
});
|
||||
};
|
||||
Importer001.prototype.canImport = function (data) {
|
||||
if (data.meta && data.meta.version && this.importFrom[data.meta.version]) {
|
||||
return when.resolve(this.importFrom[data.meta.version]);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Importer001: Importer001,
|
||||
importData: function (data) {
|
||||
new Importer001().importData(data);
|
||||
return when.reject("Unsupported version of data");
|
||||
};
|
||||
|
||||
Importer001.prototype.importFrom001 = function (data) {
|
||||
var insertOps = [];
|
||||
|
||||
_.each(data.data, function (tableData, name) {
|
||||
if (tableData && tableData.length) {
|
||||
insertOps.push(knex(name).insert(tableData));
|
||||
}
|
||||
};
|
||||
}());
|
||||
});
|
||||
|
||||
return when.all(insertOps).then(function (results) {
|
||||
return when.resolve(results);
|
||||
}, function (err) {
|
||||
console.log("Error inserting imported data: ", err.message || err, err.stack);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
Importer001: Importer001,
|
||||
importData: function (data) {
|
||||
new Importer001().importData(data);
|
||||
}
|
||||
};
|
@ -1,21 +1,17 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var when = require('when');
|
||||
|
||||
var when = require('when');
|
||||
module.exports = function (version, data) {
|
||||
var importer;
|
||||
|
||||
module.exports = function (version, data) {
|
||||
var importer;
|
||||
try {
|
||||
importer = require("./" + version);
|
||||
} catch (ignore) {
|
||||
// Zero effs given
|
||||
}
|
||||
|
||||
try {
|
||||
importer = require("./" + version);
|
||||
} catch (ignore) {
|
||||
// Zero effs given
|
||||
}
|
||||
if (!importer) {
|
||||
return when.reject("No importer found");
|
||||
}
|
||||
|
||||
if (!importer) {
|
||||
return when.reject("No importer found");
|
||||
}
|
||||
|
||||
return importer.importData(data);
|
||||
};
|
||||
}());
|
||||
return importer.importData(data);
|
||||
};
|
||||
|
@ -1,135 +1,128 @@
|
||||
/*global require, exports */
|
||||
var when = require('when'),
|
||||
knex = require('../../models/base').Knex,
|
||||
fixtures = require('../fixtures/001'),
|
||||
up,
|
||||
down;
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
up = function () {
|
||||
|
||||
return when.all([
|
||||
|
||||
var when = require('when'),
|
||||
knex = require('../../models/base').Knex,
|
||||
fixtures = require('../fixtures/001'),
|
||||
up,
|
||||
down;
|
||||
knex.Schema.createTable('posts', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('title');
|
||||
t.string('slug');
|
||||
t.text('content');
|
||||
t.text('content_html');
|
||||
t.string('meta_title');
|
||||
t.string('meta_description');
|
||||
t.string('meta_keywords');
|
||||
t.bool('featured');
|
||||
t.string('image');
|
||||
t.string('status');
|
||||
t.string('language');
|
||||
t.integer('author_id');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at').nullable();
|
||||
t.integer('updated_by').nullable();
|
||||
t.dateTime('published_at').nullable();
|
||||
t.integer('published_by').nullable();
|
||||
}),
|
||||
|
||||
up = function () {
|
||||
knex.Schema.createTable('users', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('full_name');
|
||||
t.string('password');
|
||||
t.string('email_address');
|
||||
t.string('profile_picture');
|
||||
t.string('cover_picture');
|
||||
t.text('bio');
|
||||
t.string('url');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at');
|
||||
t.integer('updated_by');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('roles', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('name');
|
||||
t.string('description');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('roles_users', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('role_id');
|
||||
t.integer('user_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('name');
|
||||
t.string('object_type');
|
||||
t.string('action_type');
|
||||
t.integer('object_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions_users', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('user_id');
|
||||
t.integer('permission_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions_roles', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('role_id');
|
||||
t.integer('permission_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('settings', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('key').unique();
|
||||
t.text('value');
|
||||
t.string('type');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at');
|
||||
t.integer('updated_by');
|
||||
})
|
||||
|
||||
// Once we create all of the initial tables, bootstrap any of the data
|
||||
]).then(function () {
|
||||
|
||||
return when.all([
|
||||
knex('posts').insert(fixtures.posts),
|
||||
// knex('users').insert(fixtures.users),
|
||||
knex('roles').insert(fixtures.roles),
|
||||
// knex('roles_users').insert(fixtures.roles_users),
|
||||
knex('permissions').insert(fixtures.permissions),
|
||||
knex('permissions_roles').insert(fixtures.permissions_roles),
|
||||
knex('settings').insert(fixtures.settings)
|
||||
]);
|
||||
|
||||
knex.Schema.createTable('posts', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('title');
|
||||
t.string('slug');
|
||||
t.text('content');
|
||||
t.text('content_html');
|
||||
t.string('meta_title');
|
||||
t.string('meta_description');
|
||||
t.string('meta_keywords');
|
||||
t.bool('featured');
|
||||
t.string('image');
|
||||
t.string('status');
|
||||
t.string('language');
|
||||
t.integer('author_id');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at').nullable();
|
||||
t.integer('updated_by').nullable();
|
||||
t.dateTime('published_at').nullable();
|
||||
t.integer('published_by').nullable();
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
knex.Schema.createTable('users', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('full_name');
|
||||
t.string('password');
|
||||
t.string('email_address');
|
||||
t.string('profile_picture');
|
||||
t.string('cover_picture');
|
||||
t.text('bio');
|
||||
t.string('url');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at');
|
||||
t.integer('updated_by');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('roles', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('name');
|
||||
t.string('description');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('roles_users', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('role_id');
|
||||
t.integer('user_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('name');
|
||||
t.string('object_type');
|
||||
t.string('action_type');
|
||||
t.integer('object_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions_users', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('user_id');
|
||||
t.integer('permission_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('permissions_roles', function (t) {
|
||||
t.increments().primary();
|
||||
t.integer('role_id');
|
||||
t.integer('permission_id');
|
||||
}),
|
||||
|
||||
knex.Schema.createTable('settings', function (t) {
|
||||
t.increments().primary();
|
||||
t.string('uuid');
|
||||
t.string('key').unique();
|
||||
t.text('value');
|
||||
t.string('type');
|
||||
t.dateTime('created_at');
|
||||
t.integer('created_by');
|
||||
t.dateTime('updated_at');
|
||||
t.integer('updated_by');
|
||||
})
|
||||
|
||||
// Once we create all of the initial tables, bootstrap any of the data
|
||||
]).then(function () {
|
||||
|
||||
return when.all([
|
||||
knex('posts').insert(fixtures.posts),
|
||||
// knex('users').insert(fixtures.users),
|
||||
knex('roles').insert(fixtures.roles),
|
||||
// knex('roles_users').insert(fixtures.roles_users),
|
||||
knex('permissions').insert(fixtures.permissions),
|
||||
knex('permissions_roles').insert(fixtures.permissions_roles),
|
||||
knex('settings').insert(fixtures.settings)
|
||||
]);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
down = function () {
|
||||
down = function () {
|
||||
return when.all([
|
||||
knex.Schema.dropTableIfExists("posts"),
|
||||
knex.Schema.dropTableIfExists("users"),
|
||||
knex.Schema.dropTableIfExists("roles"),
|
||||
knex.Schema.dropTableIfExists("settings"),
|
||||
knex.Schema.dropTableIfExists("permissions")
|
||||
]).then(function () {
|
||||
// Drop the relation tables after the model tables?
|
||||
return when.all([
|
||||
knex.Schema.dropTableIfExists("posts"),
|
||||
knex.Schema.dropTableIfExists("users"),
|
||||
knex.Schema.dropTableIfExists("roles"),
|
||||
knex.Schema.dropTableIfExists("settings"),
|
||||
knex.Schema.dropTableIfExists("permissions")
|
||||
]).then(function () {
|
||||
// Drop the relation tables after the model tables?
|
||||
return when.all([
|
||||
knex.Schema.dropTableIfExists("roles_users"),
|
||||
knex.Schema.dropTableIfExists("permissions_users"),
|
||||
knex.Schema.dropTableIfExists("permissions_roles")
|
||||
]);
|
||||
});
|
||||
};
|
||||
knex.Schema.dropTableIfExists("roles_users"),
|
||||
knex.Schema.dropTableIfExists("permissions_users"),
|
||||
knex.Schema.dropTableIfExists("permissions_roles")
|
||||
]);
|
||||
});
|
||||
};
|
||||
|
||||
exports.up = up;
|
||||
exports.down = down;
|
||||
}());
|
||||
exports.up = up;
|
||||
exports.down = down;
|
@ -1,60 +1,56 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var _ = require('underscore'),
|
||||
errors;
|
||||
|
||||
var _ = require('underscore'),
|
||||
errors;
|
||||
|
||||
/**
|
||||
* Basic error handling helpers
|
||||
*/
|
||||
errors = {
|
||||
throwError: function (err) {
|
||||
if (!err) {
|
||||
err = new Error("An error occurred");
|
||||
}
|
||||
|
||||
if (_.isString(err)) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
throw err;
|
||||
},
|
||||
|
||||
logError: function (err) {
|
||||
err = err || "Unknown";
|
||||
// TODO: Logging framework hookup
|
||||
console.log("Error occurred: ", err.message || err);
|
||||
},
|
||||
|
||||
logAndThrowError: function (err) {
|
||||
this.logError(err);
|
||||
|
||||
this.throwError(err);
|
||||
},
|
||||
|
||||
logErrorWithMessage: function (msg) {
|
||||
var self = this;
|
||||
|
||||
return function () {
|
||||
self.logError(msg);
|
||||
};
|
||||
},
|
||||
|
||||
logErrorWithRedirect: function (msg, redirectTo, req, res) {
|
||||
var self = this;
|
||||
|
||||
return function () {
|
||||
self.logError(msg);
|
||||
|
||||
if (_.isFunction(res.redirect)) {
|
||||
res.redirect(redirectTo);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Basic error handling helpers
|
||||
*/
|
||||
errors = {
|
||||
throwError: function (err) {
|
||||
if (!err) {
|
||||
err = new Error("An error occurred");
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure our 'this' context in the functions
|
||||
_.bindAll(errors, "throwError", "logError", "logAndThrowError", "logErrorWithMessage", "logErrorWithRedirect");
|
||||
if (_.isString(err)) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
module.exports = errors;
|
||||
}());
|
||||
throw err;
|
||||
},
|
||||
|
||||
logError: function (err) {
|
||||
err = err || "Unknown";
|
||||
// TODO: Logging framework hookup
|
||||
console.log("Error occurred: ", err.message || err);
|
||||
},
|
||||
|
||||
logAndThrowError: function (err) {
|
||||
this.logError(err);
|
||||
|
||||
this.throwError(err);
|
||||
},
|
||||
|
||||
logErrorWithMessage: function (msg) {
|
||||
var self = this;
|
||||
|
||||
return function () {
|
||||
self.logError(msg);
|
||||
};
|
||||
},
|
||||
|
||||
logErrorWithRedirect: function (msg, redirectTo, req, res) {
|
||||
var self = this;
|
||||
|
||||
return function () {
|
||||
self.logError(msg);
|
||||
|
||||
if (_.isFunction(res.redirect)) {
|
||||
res.redirect(redirectTo);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure our 'this' context in the functions
|
||||
_.bindAll(errors, "throwError", "logError", "logAndThrowError", "logErrorWithMessage", "logErrorWithRedirect");
|
||||
|
||||
module.exports = errors;
|
@ -1,96 +1,90 @@
|
||||
(function () {
|
||||
var GhostBookshelf,
|
||||
Bookshelf = require('bookshelf'),
|
||||
config = require('../../../config');
|
||||
|
||||
"use strict";
|
||||
// Initializes Bookshelf as its own instance, so we can modify the Models and not mess up
|
||||
// others' if they're using the library outside of ghost.
|
||||
GhostBookshelf = Bookshelf.Initialize('ghost', config.database[process.env.NODE_ENV || 'development']);
|
||||
|
||||
var GhostBookshelf,
|
||||
Bookshelf = require('bookshelf'),
|
||||
config = require('../../../config');
|
||||
// The Base Model which other Ghost objects will inherit from,
|
||||
// including some convenience functions as static properties on the model.
|
||||
GhostBookshelf.Model = GhostBookshelf.Model.extend({
|
||||
|
||||
// Initializes Bookshelf as its own instance, so we can modify the Models and not mess up
|
||||
// others' if they're using the library outside of ghost.
|
||||
GhostBookshelf = Bookshelf.Initialize('ghost', config.database[process.env.NODE_ENV || 'development']);
|
||||
// Base prototype properties will go here
|
||||
|
||||
// The Base Model which other Ghost objects will inherit from,
|
||||
// including some convenience functions as static properties on the model.
|
||||
GhostBookshelf.Model = GhostBookshelf.Model.extend({
|
||||
}, {
|
||||
|
||||
// Base prototype properties will go here
|
||||
/**
|
||||
* Naive find all
|
||||
* @param options (optional)
|
||||
*/
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
return GhostBookshelf.Collection.forge([], {model: this}).fetch(options);
|
||||
},
|
||||
|
||||
}, {
|
||||
browse: function () {
|
||||
return this.findAll.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Naive find all
|
||||
* @param options (optional)
|
||||
*/
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
return GhostBookshelf.Collection.forge([], {model: this}).fetch(options);
|
||||
},
|
||||
/**
|
||||
* Naive find one where args match
|
||||
* @param args
|
||||
* @param options (optional)
|
||||
*/
|
||||
findOne: function (args, options) {
|
||||
options = options || {};
|
||||
return this.forge(args).fetch(options);
|
||||
},
|
||||
|
||||
browse: function () {
|
||||
return this.findAll.apply(this, arguments);
|
||||
},
|
||||
read: function () {
|
||||
return this.findOne.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Naive find one where args match
|
||||
* @param args
|
||||
* @param options (optional)
|
||||
*/
|
||||
findOne: function (args, options) {
|
||||
options = options || {};
|
||||
return this.forge(args).fetch(options);
|
||||
},
|
||||
/**
|
||||
* Naive edit
|
||||
* @param editedObj
|
||||
* @param options (optional)
|
||||
*/
|
||||
edit: function (editedObj, options) {
|
||||
options = options || {};
|
||||
return this.forge({id: editedObj.id}).fetch(options).then(function (foundObj) {
|
||||
return foundObj.set(editedObj).save();
|
||||
});
|
||||
},
|
||||
|
||||
read: function () {
|
||||
return this.findOne.apply(this, arguments);
|
||||
},
|
||||
update: function () {
|
||||
return this.edit.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Naive edit
|
||||
* @param editedObj
|
||||
* @param options (optional)
|
||||
*/
|
||||
edit: function (editedObj, options) {
|
||||
options = options || {};
|
||||
return this.forge({id: editedObj.id}).fetch(options).then(function (foundObj) {
|
||||
return foundObj.set(editedObj).save();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Naive create
|
||||
* @param editedObj
|
||||
* @param options (optional)
|
||||
*/
|
||||
add: function (newObj, options) {
|
||||
options = options || {};
|
||||
return this.forge(newObj).save(options);
|
||||
},
|
||||
|
||||
update: function () {
|
||||
return this.edit.apply(this, arguments);
|
||||
},
|
||||
create: function () {
|
||||
return this.add.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Naive create
|
||||
* @param editedObj
|
||||
* @param options (optional)
|
||||
*/
|
||||
add: function (newObj, options) {
|
||||
options = options || {};
|
||||
return this.forge(newObj).save(options);
|
||||
},
|
||||
/**
|
||||
* Naive destroy
|
||||
* @param _identifier
|
||||
* @param options (optional)
|
||||
*/
|
||||
destroy: function (_identifier, options) {
|
||||
options = options || {};
|
||||
return this.forge({id: _identifier}).destroy(options);
|
||||
},
|
||||
|
||||
create: function () {
|
||||
return this.add.apply(this, arguments);
|
||||
},
|
||||
'delete': function () {
|
||||
return this.destroy.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive destroy
|
||||
* @param _identifier
|
||||
* @param options (optional)
|
||||
*/
|
||||
destroy: function (_identifier, options) {
|
||||
options = options || {};
|
||||
return this.forge({id: _identifier}).destroy(options);
|
||||
},
|
||||
});
|
||||
|
||||
'delete': function () {
|
||||
return this.destroy.apply(this, arguments);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = GhostBookshelf;
|
||||
|
||||
}());
|
||||
module.exports = GhostBookshelf;
|
@ -1,29 +1,22 @@
|
||||
/*global require, module */
|
||||
var GhostBookshelf = require('./base'),
|
||||
errors = require('../errorHandling'),
|
||||
knex = GhostBookshelf.Knex;
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var GhostBookshelf = require('./base'),
|
||||
errors = require('../errorHandling'),
|
||||
knex = GhostBookshelf.Knex;
|
||||
|
||||
module.exports = {
|
||||
Post: require('./post').Post,
|
||||
User: require('./user').User,
|
||||
Role: require('./role').Role,
|
||||
Permission: require('./permission').Permission,
|
||||
Settings: require('./settings').Settings,
|
||||
init: function () {
|
||||
return knex.Schema.hasTable('posts').then(null, function () {
|
||||
// Simple bootstraping of the data model for now.
|
||||
var migration = require('../data/migration/001');
|
||||
return migration.down().then(function () {
|
||||
return migration.up();
|
||||
}, errors.logAndThrowError);
|
||||
}, errors.logAndThrowError).then(function () {
|
||||
console.log('models loaded');
|
||||
module.exports = {
|
||||
Post: require('./post').Post,
|
||||
User: require('./user').User,
|
||||
Role: require('./role').Role,
|
||||
Permission: require('./permission').Permission,
|
||||
Settings: require('./settings').Settings,
|
||||
init: function () {
|
||||
return knex.Schema.hasTable('posts').then(null, function () {
|
||||
// Simple bootstraping of the data model for now.
|
||||
var migration = require('../data/migration/001');
|
||||
return migration.down().then(function () {
|
||||
return migration.up();
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
}, errors.logAndThrowError).then(function () {
|
||||
console.log('models loaded');
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
|
@ -1,31 +1,26 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var GhostBookshelf = require('./base'),
|
||||
User = require('./user').User,
|
||||
Role = require('./role').Role,
|
||||
Permission,
|
||||
Permissions;
|
||||
|
||||
var GhostBookshelf = require('./base'),
|
||||
User = require('./user').User,
|
||||
Role = require('./role').Role,
|
||||
Permission,
|
||||
Permissions;
|
||||
Permission = GhostBookshelf.Model.extend({
|
||||
tableName: 'permissions',
|
||||
|
||||
Permission = GhostBookshelf.Model.extend({
|
||||
tableName: 'permissions',
|
||||
roles: function () {
|
||||
return this.belongsToMany(Role);
|
||||
},
|
||||
|
||||
roles: function () {
|
||||
return this.belongsToMany(Role);
|
||||
},
|
||||
users: function () {
|
||||
return this.belongsToMany(User);
|
||||
}
|
||||
});
|
||||
|
||||
users: function () {
|
||||
return this.belongsToMany(User);
|
||||
}
|
||||
});
|
||||
Permissions = GhostBookshelf.Collection.extend({
|
||||
model: Permission
|
||||
});
|
||||
|
||||
Permissions = GhostBookshelf.Collection.extend({
|
||||
model: Permission
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
Permission: Permission,
|
||||
Permissions: Permissions
|
||||
};
|
||||
|
||||
}());
|
||||
module.exports = {
|
||||
Permission: Permission,
|
||||
Permissions: Permissions
|
||||
};
|
@ -1,87 +1,83 @@
|
||||
(function () {
|
||||
var Post,
|
||||
Posts,
|
||||
_ = require('underscore'),
|
||||
uuid = require('node-uuid'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
Showdown = require('showdown'),
|
||||
converter = new Showdown.converter(),
|
||||
User = require('./user').User,
|
||||
GhostBookshelf = require('./base');
|
||||
|
||||
"use strict";
|
||||
Post = GhostBookshelf.Model.extend({
|
||||
|
||||
var Post,
|
||||
Posts,
|
||||
_ = require('underscore'),
|
||||
uuid = require('node-uuid'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
Showdown = require('showdown'),
|
||||
converter = new Showdown.converter(),
|
||||
User = require('./user').User,
|
||||
GhostBookshelf = require('./base');
|
||||
tableName: 'posts',
|
||||
|
||||
Post = GhostBookshelf.Model.extend({
|
||||
hasTimestamps: true,
|
||||
|
||||
tableName: 'posts',
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4(),
|
||||
status: 'draft'
|
||||
// TODO: language: ghost.config().defaultLang);
|
||||
};
|
||||
},
|
||||
|
||||
hasTimestamps: true,
|
||||
initialize: function () {
|
||||
this.on('creating', this.creating, this);
|
||||
this.on('saving', this.saving, this);
|
||||
},
|
||||
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4(),
|
||||
status: 'draft'
|
||||
// TODO: language: ghost.config().defaultLang);
|
||||
};
|
||||
},
|
||||
saving: function () {
|
||||
if (!this.get('title')) {
|
||||
throw new Error('Post title cannot be blank');
|
||||
}
|
||||
this.set('content_html', converter.makeHtml(this.get('content')));
|
||||
|
||||
initialize: function () {
|
||||
this.on('creating', this.creating, this);
|
||||
this.on('saving', this.saving, this);
|
||||
},
|
||||
|
||||
saving: function () {
|
||||
if (!this.get('title')) {
|
||||
throw new Error('Post title cannot be blank');
|
||||
}
|
||||
this.set('content_html', converter.makeHtml(this.get('content')));
|
||||
|
||||
if (this.hasChanged('status') && this.get('status') === 'published') {
|
||||
this.set('published_at', new Date());
|
||||
// This will need to go elsewhere in the API layer.
|
||||
this.set('published_by', 1);
|
||||
}
|
||||
|
||||
this.set('updated_by', 1);
|
||||
// refactoring of ghost required in order to make these details available here
|
||||
},
|
||||
|
||||
creating: function () {
|
||||
if (!this.get('slug')) {
|
||||
this.generateSlug();
|
||||
}
|
||||
|
||||
if (!this.get('created_by')) {
|
||||
this.set('created_by', 1);
|
||||
}
|
||||
|
||||
if (!this.get('author_id')) {
|
||||
this.set('author_id', 1);
|
||||
}
|
||||
},
|
||||
|
||||
generateSlug: function () {
|
||||
return this.set('slug', this.get('title').replace(/\:/g, '').replace(/\s/g, '-').toLowerCase());
|
||||
},
|
||||
|
||||
user: function () {
|
||||
return this.belongsTo(User, 'created_by');
|
||||
},
|
||||
|
||||
author: function () {
|
||||
return this.belongsTo(User, 'author_id');
|
||||
if (this.hasChanged('status') && this.get('status') === 'published') {
|
||||
this.set('published_at', new Date());
|
||||
// This will need to go elsewhere in the API layer.
|
||||
this.set('published_by', 1);
|
||||
}
|
||||
|
||||
}, {
|
||||
this.set('updated_by', 1);
|
||||
// refactoring of ghost required in order to make these details available here
|
||||
},
|
||||
|
||||
/**
|
||||
* Find results by page - returns an object containing the
|
||||
* information about the request (page, limit), along with the
|
||||
* info needed for pagination (pages, total).
|
||||
*
|
||||
* {
|
||||
creating: function () {
|
||||
if (!this.get('slug')) {
|
||||
this.generateSlug();
|
||||
}
|
||||
|
||||
if (!this.get('created_by')) {
|
||||
this.set('created_by', 1);
|
||||
}
|
||||
|
||||
if (!this.get('author_id')) {
|
||||
this.set('author_id', 1);
|
||||
}
|
||||
},
|
||||
|
||||
generateSlug: function () {
|
||||
return this.set('slug', this.get('title').replace(/\:/g, '').replace(/\s/g, '-').toLowerCase());
|
||||
},
|
||||
|
||||
user: function () {
|
||||
return this.belongsTo(User, 'created_by');
|
||||
},
|
||||
|
||||
author: function () {
|
||||
return this.belongsTo(User, 'author_id');
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/**
|
||||
* Find results by page - returns an object containing the
|
||||
* information about the request (page, limit), along with the
|
||||
* info needed for pagination (pages, total).
|
||||
*
|
||||
* {
|
||||
* posts: [
|
||||
* {...}, {...}, {...}
|
||||
* ],
|
||||
@ -90,118 +86,116 @@
|
||||
* pages: __,
|
||||
* total: __
|
||||
* }
|
||||
*
|
||||
* @params opts
|
||||
*/
|
||||
findPage: function (opts) {
|
||||
var postCollection;
|
||||
*
|
||||
* @params opts
|
||||
*/
|
||||
findPage: function (opts) {
|
||||
var postCollection;
|
||||
|
||||
// Allow findPage(n)
|
||||
if (_.isString(opts) || _.isNumber(opts)) {
|
||||
opts = {page: opts};
|
||||
}
|
||||
|
||||
opts = _.extend({
|
||||
page: 1,
|
||||
limit: 15,
|
||||
where: {},
|
||||
status: 'published',
|
||||
orderBy: ['published_at', 'DESC']
|
||||
}, opts);
|
||||
|
||||
postCollection = Posts.forge();
|
||||
|
||||
// Unless `all` is passed as an option, filter on
|
||||
// the status provided.
|
||||
if (opts.status !== 'all') {
|
||||
opts.where.status = opts.status;
|
||||
}
|
||||
|
||||
// If there are where conditionals specified, add those
|
||||
// to the query.
|
||||
if (opts.where) {
|
||||
postCollection.query('where', opts.where);
|
||||
}
|
||||
|
||||
// Set the limit & offset for the query, fetching
|
||||
// with the opts (to specify any eager relations, etc.)
|
||||
// Omitting the `page`, `limit`, `where` just to be sure
|
||||
// aren't used for other purposes.
|
||||
return postCollection
|
||||
.query('limit', opts.limit)
|
||||
.query('offset', opts.limit * (opts.page - 1))
|
||||
.query('orderBy', opts.orderBy[0], opts.orderBy[1])
|
||||
.fetch(_.omit(opts, 'page', 'limit', 'where', 'status', 'orderBy'))
|
||||
.then(function (collection) {
|
||||
var qb;
|
||||
|
||||
// After we're done, we need to figure out what
|
||||
// the limits are for the pagination values.
|
||||
qb = GhostBookshelf.Knex(_.result(collection, 'tableName'));
|
||||
|
||||
if (opts.where) {
|
||||
qb.where(opts.where);
|
||||
}
|
||||
|
||||
return qb.count(_.result(collection, 'idAttribute')).then(function (resp) {
|
||||
var totalPosts = resp[0].aggregate;
|
||||
return {
|
||||
posts: collection.toJSON(),
|
||||
page: opts.page,
|
||||
limit: opts.limit,
|
||||
pages: Math.ceil(totalPosts / opts.limit),
|
||||
total: totalPosts
|
||||
};
|
||||
}, errors.logAndThrowError);
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
|
||||
permissable: function (postModelOrId, userId, action_type, userPermissions) {
|
||||
var self = this,
|
||||
hasPermission,
|
||||
postModel = postModelOrId;
|
||||
|
||||
// If we passed in an id instead of a model, get the model
|
||||
// then check the permissions
|
||||
if (_.isNumber(postModelOrId) || _.isString(postModelOrId)) {
|
||||
return this.read({id: postModelOrId}).then(function (foundPostModel) {
|
||||
return self.permissable(foundPostModel, userId, action_type, userPermissions);
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
|
||||
// TODO: This logic is temporary, will probably need to be updated
|
||||
|
||||
hasPermission = _.any(userPermissions, function (perm) {
|
||||
if (perm.get('object_type') !== 'post') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// True, if no object_id specified, or it matches
|
||||
return !perm.get('object_id') || perm.get('object_id') === postModel.id;
|
||||
});
|
||||
|
||||
// If this is the author of the post, allow it.
|
||||
hasPermission = hasPermission || userId === postModel.get('author_id');
|
||||
|
||||
if (hasPermission) {
|
||||
return when.resolve();
|
||||
}
|
||||
|
||||
// Otherwise, you shall not pass.
|
||||
return when.reject();
|
||||
// Allow findPage(n)
|
||||
if (_.isString(opts) || _.isNumber(opts)) {
|
||||
opts = {page: opts};
|
||||
}
|
||||
|
||||
});
|
||||
opts = _.extend({
|
||||
page: 1,
|
||||
limit: 15,
|
||||
where: {},
|
||||
status: 'published',
|
||||
orderBy: ['published_at', 'DESC']
|
||||
}, opts);
|
||||
|
||||
Posts = GhostBookshelf.Collection.extend({
|
||||
postCollection = Posts.forge();
|
||||
|
||||
model: Post
|
||||
// Unless `all` is passed as an option, filter on
|
||||
// the status provided.
|
||||
if (opts.status !== 'all') {
|
||||
opts.where.status = opts.status;
|
||||
}
|
||||
|
||||
});
|
||||
// If there are where conditionals specified, add those
|
||||
// to the query.
|
||||
if (opts.where) {
|
||||
postCollection.query('where', opts.where);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Post: Post,
|
||||
Posts: Posts
|
||||
};
|
||||
// Set the limit & offset for the query, fetching
|
||||
// with the opts (to specify any eager relations, etc.)
|
||||
// Omitting the `page`, `limit`, `where` just to be sure
|
||||
// aren't used for other purposes.
|
||||
return postCollection
|
||||
.query('limit', opts.limit)
|
||||
.query('offset', opts.limit * (opts.page - 1))
|
||||
.query('orderBy', opts.orderBy[0], opts.orderBy[1])
|
||||
.fetch(_.omit(opts, 'page', 'limit', 'where', 'status', 'orderBy'))
|
||||
.then(function (collection) {
|
||||
var qb;
|
||||
|
||||
}());
|
||||
// After we're done, we need to figure out what
|
||||
// the limits are for the pagination values.
|
||||
qb = GhostBookshelf.Knex(_.result(collection, 'tableName'));
|
||||
|
||||
if (opts.where) {
|
||||
qb.where(opts.where);
|
||||
}
|
||||
|
||||
return qb.count(_.result(collection, 'idAttribute')).then(function (resp) {
|
||||
var totalPosts = resp[0].aggregate;
|
||||
return {
|
||||
posts: collection.toJSON(),
|
||||
page: opts.page,
|
||||
limit: opts.limit,
|
||||
pages: Math.ceil(totalPosts / opts.limit),
|
||||
total: totalPosts
|
||||
};
|
||||
}, errors.logAndThrowError);
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
|
||||
permissable: function (postModelOrId, userId, action_type, userPermissions) {
|
||||
var self = this,
|
||||
hasPermission,
|
||||
postModel = postModelOrId;
|
||||
|
||||
// If we passed in an id instead of a model, get the model
|
||||
// then check the permissions
|
||||
if (_.isNumber(postModelOrId) || _.isString(postModelOrId)) {
|
||||
return this.read({id: postModelOrId}).then(function (foundPostModel) {
|
||||
return self.permissable(foundPostModel, userId, action_type, userPermissions);
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
|
||||
// TODO: This logic is temporary, will probably need to be updated
|
||||
|
||||
hasPermission = _.any(userPermissions, function (perm) {
|
||||
if (perm.get('object_type') !== 'post') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// True, if no object_id specified, or it matches
|
||||
return !perm.get('object_id') || perm.get('object_id') === postModel.id;
|
||||
});
|
||||
|
||||
// If this is the author of the post, allow it.
|
||||
hasPermission = hasPermission || userId === postModel.get('author_id');
|
||||
|
||||
if (hasPermission) {
|
||||
return when.resolve();
|
||||
}
|
||||
|
||||
// Otherwise, you shall not pass.
|
||||
return when.reject();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Posts = GhostBookshelf.Collection.extend({
|
||||
|
||||
model: Post
|
||||
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
Post: Post,
|
||||
Posts: Posts
|
||||
};
|
@ -1,32 +1,26 @@
|
||||
(function () {
|
||||
var User = require('./user').User,
|
||||
Permission = require('./permission').Permission,
|
||||
GhostBookshelf = require('./base'),
|
||||
Role,
|
||||
Roles;
|
||||
|
||||
"use strict";
|
||||
Role = GhostBookshelf.Model.extend({
|
||||
tableName: 'roles',
|
||||
|
||||
var User = require('./user').User,
|
||||
Permission = require('./permission').Permission,
|
||||
GhostBookshelf = require('./base'),
|
||||
Role,
|
||||
Roles;
|
||||
users: function () {
|
||||
return this.belongsToMany(User);
|
||||
},
|
||||
|
||||
Role = GhostBookshelf.Model.extend({
|
||||
tableName: 'roles',
|
||||
permissions: function () {
|
||||
return this.belongsToMany(Permission);
|
||||
}
|
||||
});
|
||||
|
||||
users: function () {
|
||||
return this.belongsToMany(User);
|
||||
},
|
||||
Roles = GhostBookshelf.Collection.extend({
|
||||
model: Role
|
||||
});
|
||||
|
||||
permissions: function () {
|
||||
return this.belongsToMany(Permission);
|
||||
}
|
||||
});
|
||||
|
||||
Roles = GhostBookshelf.Collection.extend({
|
||||
model: Role
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
Role: Role,
|
||||
Roles: Roles
|
||||
};
|
||||
|
||||
}());
|
||||
module.exports = {
|
||||
Role: Role,
|
||||
Roles: Roles
|
||||
};
|
||||
|
@ -1,50 +1,45 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
var Settings,
|
||||
GhostBookshelf = require('./base'),
|
||||
uuid = require('node-uuid'),
|
||||
_ = require('underscore'),
|
||||
errors = require('../errorHandling'),
|
||||
when = require('when');
|
||||
|
||||
var Settings,
|
||||
GhostBookshelf = require('./base'),
|
||||
uuid = require('node-uuid'),
|
||||
_ = require('underscore'),
|
||||
errors = require('../errorHandling'),
|
||||
when = require('when');
|
||||
|
||||
// Each setting is saved as a separate row in the database,
|
||||
// but the overlying API treats them as a single key:value mapping
|
||||
Settings = GhostBookshelf.Model.extend({
|
||||
tableName: 'settings',
|
||||
hasTimestamps: true,
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4(),
|
||||
type: 'general'
|
||||
};
|
||||
// Each setting is saved as a separate row in the database,
|
||||
// but the overlying API treats them as a single key:value mapping
|
||||
Settings = GhostBookshelf.Model.extend({
|
||||
tableName: 'settings',
|
||||
hasTimestamps: true,
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4(),
|
||||
type: 'general'
|
||||
};
|
||||
}
|
||||
}, {
|
||||
read: function (_key) {
|
||||
// Allow for just passing the key instead of attributes
|
||||
if (!_.isObject(_key)) {
|
||||
_key = { key: _key };
|
||||
}
|
||||
}, {
|
||||
read: function (_key) {
|
||||
// Allow for just passing the key instead of attributes
|
||||
if (!_.isObject(_key)) {
|
||||
_key = { key: _key };
|
||||
}
|
||||
return GhostBookshelf.Model.read.call(this, _key);
|
||||
},
|
||||
return GhostBookshelf.Model.read.call(this, _key);
|
||||
},
|
||||
|
||||
edit: function (_data) {
|
||||
var settings = this;
|
||||
if (!Array.isArray(_data)) {
|
||||
_data = [_data];
|
||||
}
|
||||
return when.map(_data, function (item) {
|
||||
// Accept an array of models as input
|
||||
if (item.toJSON) { item = item.toJSON(); }
|
||||
return settings.forge({ key: item.key }).fetch().then(function (setting) {
|
||||
return setting.set('value', item.value).save();
|
||||
}, errors.logAndThrowError);
|
||||
});
|
||||
edit: function (_data) {
|
||||
var settings = this;
|
||||
if (!Array.isArray(_data)) {
|
||||
_data = [_data];
|
||||
}
|
||||
});
|
||||
return when.map(_data, function (item) {
|
||||
// Accept an array of models as input
|
||||
if (item.toJSON) { item = item.toJSON(); }
|
||||
return settings.forge({ key: item.key }).fetch().then(function (setting) {
|
||||
return setting.set('value', item.value).save();
|
||||
}, errors.logAndThrowError);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
Settings: Settings
|
||||
};
|
||||
|
||||
}());
|
||||
module.exports = {
|
||||
Settings: Settings
|
||||
};
|
@ -1,101 +1,98 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var User,
|
||||
Users,
|
||||
UserRole,
|
||||
// UserRoles,
|
||||
_ = require('underscore'),
|
||||
uuid = require('node-uuid'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
nodefn = require('when/node/function'),
|
||||
bcrypt = require('bcrypt-nodejs'),
|
||||
Posts = require('./post').Posts,
|
||||
GhostBookshelf = require('./base'),
|
||||
Role = require('./role').Role,
|
||||
Permission = require('./permission').Permission;
|
||||
var User,
|
||||
Users,
|
||||
UserRole,
|
||||
// UserRoles,
|
||||
_ = require('underscore'),
|
||||
uuid = require('node-uuid'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
nodefn = require('when/node/function'),
|
||||
bcrypt = require('bcrypt-nodejs'),
|
||||
Posts = require('./post').Posts,
|
||||
GhostBookshelf = require('./base'),
|
||||
Role = require('./role').Role,
|
||||
Permission = require('./permission').Permission;
|
||||
|
||||
|
||||
|
||||
UserRole = GhostBookshelf.Model.extend({
|
||||
tableName: 'roles_users'
|
||||
});
|
||||
UserRole = GhostBookshelf.Model.extend({
|
||||
tableName: 'roles_users'
|
||||
});
|
||||
|
||||
|
||||
User = GhostBookshelf.Model.extend({
|
||||
User = GhostBookshelf.Model.extend({
|
||||
|
||||
tableName: 'users',
|
||||
tableName: 'users',
|
||||
|
||||
hasTimestamps: true,
|
||||
hasTimestamps: true,
|
||||
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4()
|
||||
defaults: function () {
|
||||
return {
|
||||
uuid: uuid.v4()
|
||||
};
|
||||
},
|
||||
|
||||
posts: function () {
|
||||
return this.hasMany(Posts, 'created_by');
|
||||
},
|
||||
|
||||
roles: function () {
|
||||
return this.belongsToMany(Role);
|
||||
},
|
||||
|
||||
permissions: function () {
|
||||
return this.belongsToMany(Permission);
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/**
|
||||
* Naive user add
|
||||
* @param _user
|
||||
*
|
||||
* Hashes the password provided before saving to the database.
|
||||
*/
|
||||
add: function (_user) {
|
||||
|
||||
var User = this,
|
||||
// Clone the _user so we don't expose the hashed password unnecessarily
|
||||
userData = _.extend({}, _user),
|
||||
fail = false,
|
||||
userRoles = {
|
||||
|
||||
"role_id": 1,
|
||||
"user_id": 1
|
||||
};
|
||||
},
|
||||
|
||||
posts: function () {
|
||||
return this.hasMany(Posts, 'created_by');
|
||||
},
|
||||
|
||||
roles: function () {
|
||||
return this.belongsToMany(Role);
|
||||
},
|
||||
|
||||
permissions: function () {
|
||||
return this.belongsToMany(Permission);
|
||||
}
|
||||
|
||||
}, {
|
||||
|
||||
/**
|
||||
* Naive user add
|
||||
* @param _user
|
||||
*
|
||||
* Hashes the password provided before saving to the database.
|
||||
* This only allows one user to be added to the database, otherwise fails.
|
||||
* @param {object} user
|
||||
* @author javorszky
|
||||
*/
|
||||
add: function (_user) {
|
||||
return this.forge().fetch().then(function (user) {
|
||||
|
||||
var User = this,
|
||||
// Clone the _user so we don't expose the hashed password unnecessarily
|
||||
userData = _.extend({}, _user),
|
||||
fail = false,
|
||||
userRoles = {
|
||||
if (user) {
|
||||
fail = true;
|
||||
}
|
||||
|
||||
"role_id": 1,
|
||||
"user_id": 1
|
||||
};
|
||||
if (fail) {
|
||||
return when.reject(new Error('A user is already registered. Only one user for now!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This only allows one user to be added to the database, otherwise fails.
|
||||
* @param {object} user
|
||||
* @author javorszky
|
||||
*/
|
||||
return this.forge().fetch().then(function (user) {
|
||||
|
||||
if (user) {
|
||||
fail = true;
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
return when.reject(new Error('A user is already registered. Only one user for now!'));
|
||||
}
|
||||
|
||||
return nodefn.call(bcrypt.hash, _user.password, null, null).then(function (hash) {
|
||||
userData.password = hash;
|
||||
GhostBookshelf.Model.add.call(UserRole, userRoles);
|
||||
return GhostBookshelf.Model.add.call(User, userData);
|
||||
}, errors.logAndThrowError);
|
||||
return nodefn.call(bcrypt.hash, _user.password, null, null).then(function (hash) {
|
||||
userData.password = hash;
|
||||
GhostBookshelf.Model.add.call(UserRole, userRoles);
|
||||
return GhostBookshelf.Model.add.call(User, userData);
|
||||
}, errors.logAndThrowError);
|
||||
}, errors.logAndThrowError);
|
||||
|
||||
/**
|
||||
* Temporarily replacing the function below with another one that checks
|
||||
* whether there's anyone registered at all. This is due to #138
|
||||
* @author javorszky
|
||||
*/
|
||||
/**
|
||||
return this.forge({email_address: userData.email_address}).fetch().then(function (user) {
|
||||
/**
|
||||
* Temporarily replacing the function below with another one that checks
|
||||
* whether there's anyone registered at all. This is due to #138
|
||||
* @author javorszky
|
||||
*/
|
||||
/**
|
||||
return this.forge({email_address: userData.email_address}).fetch().then(function (user) {
|
||||
if (!!user.attributes.email_address) {
|
||||
return when.reject(new Error('A user with that email address already exists.'));
|
||||
}
|
||||
@ -105,66 +102,64 @@
|
||||
return GhostBookshelf.Model.add.call(User, userData);
|
||||
});
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
/**
|
||||
* User check
|
||||
* @param _userdata
|
||||
*
|
||||
* Finds the user by email, and check's the password
|
||||
*/
|
||||
check: function (_userdata) {
|
||||
return this.forge({
|
||||
email_address: _userdata.email
|
||||
}).fetch({require: true}).then(function (user) {
|
||||
return nodefn.call(bcrypt.compare, _userdata.pw, user.get('password')).then(function (matched) {
|
||||
if (!matched) {
|
||||
return when.reject(new Error('Passwords do not match'));
|
||||
}
|
||||
return user;
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
|
||||
/**
|
||||
* User check
|
||||
* @param _userdata
|
||||
*
|
||||
* Finds the user by email, and check's the password
|
||||
*/
|
||||
check: function (_userdata) {
|
||||
return this.forge({
|
||||
email_address: _userdata.email
|
||||
}).fetch({require: true}).then(function (user) {
|
||||
return nodefn.call(bcrypt.compare, _userdata.pw, user.get('password')).then(function (matched) {
|
||||
if (!matched) {
|
||||
return when.reject(new Error('Passwords do not match'));
|
||||
}
|
||||
return user;
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
}, errors.logAndThrowError);
|
||||
},
|
||||
|
||||
effectivePermissions: function (id) {
|
||||
return this.read({id: id}, { withRelated: ['permissions', 'roles.permissions'] })
|
||||
.then(function (foundUser) {
|
||||
var seenPerms = {},
|
||||
rolePerms = _.map(foundUser.related('roles').models, function (role) {
|
||||
return role.related('permissions').models;
|
||||
}),
|
||||
allPerms = [];
|
||||
effectivePermissions: function (id) {
|
||||
return this.read({id: id}, { withRelated: ['permissions', 'roles.permissions'] })
|
||||
.then(function (foundUser) {
|
||||
var seenPerms = {},
|
||||
rolePerms = _.map(foundUser.related('roles').models, function (role) {
|
||||
return role.related('permissions').models;
|
||||
}),
|
||||
allPerms = [];
|
||||
|
||||
rolePerms.push(foundUser.related('permissions').models);
|
||||
rolePerms.push(foundUser.related('permissions').models);
|
||||
|
||||
_.each(rolePerms, function (rolePermGroup) {
|
||||
_.each(rolePermGroup, function (perm) {
|
||||
var key = perm.get('action_type') + '-' + perm.get('object_type') + '-' + perm.get('object_id');
|
||||
_.each(rolePerms, function (rolePermGroup) {
|
||||
_.each(rolePermGroup, function (perm) {
|
||||
var key = perm.get('action_type') + '-' + perm.get('object_type') + '-' + perm.get('object_id');
|
||||
|
||||
// Only add perms once
|
||||
if (seenPerms[key]) {
|
||||
return;
|
||||
}
|
||||
// Only add perms once
|
||||
if (seenPerms[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
allPerms.push(perm);
|
||||
seenPerms[key] = true;
|
||||
});
|
||||
allPerms.push(perm);
|
||||
seenPerms[key] = true;
|
||||
});
|
||||
});
|
||||
|
||||
return when.resolve(allPerms);
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
return when.resolve(allPerms);
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Users = GhostBookshelf.Collection.extend({
|
||||
model: User
|
||||
});
|
||||
Users = GhostBookshelf.Collection.extend({
|
||||
model: User
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
User: User,
|
||||
Users: Users
|
||||
};
|
||||
|
||||
}());
|
||||
module.exports = {
|
||||
User: User,
|
||||
Users: Users
|
||||
};
|
@ -1,179 +1,174 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
// canThis(someUser).edit.posts([id]|[[ids]])
|
||||
// canThis(someUser).edit.post(somePost|somePostId)
|
||||
|
||||
// canThis(someUser).edit.posts([id]|[[ids]])
|
||||
// canThis(someUser).edit.post(somePost|somePostId)
|
||||
var _ = require('underscore'),
|
||||
when = require('when'),
|
||||
Models = require('../models'),
|
||||
objectTypeModelMap = require('./objectTypeModelMap'),
|
||||
UserProvider = Models.User,
|
||||
PermissionsProvider = Models.Permission,
|
||||
init,
|
||||
refresh,
|
||||
canThis,
|
||||
CanThisResult,
|
||||
exported;
|
||||
|
||||
var _ = require('underscore'),
|
||||
when = require('when'),
|
||||
Models = require('../models'),
|
||||
objectTypeModelMap = require('./objectTypeModelMap'),
|
||||
UserProvider = Models.User,
|
||||
PermissionsProvider = Models.Permission,
|
||||
init,
|
||||
refresh,
|
||||
canThis,
|
||||
CanThisResult,
|
||||
exported;
|
||||
// Base class for canThis call results
|
||||
CanThisResult = function () {
|
||||
this.userPermissionLoad = false;
|
||||
};
|
||||
|
||||
// Base class for canThis call results
|
||||
CanThisResult = function () {
|
||||
this.userPermissionLoad = false;
|
||||
};
|
||||
CanThisResult.prototype.buildObjectTypeHandlers = function (obj_types, act_type, userId) {
|
||||
var self = this,
|
||||
obj_type_handlers = {};
|
||||
|
||||
CanThisResult.prototype.buildObjectTypeHandlers = function (obj_types, act_type, userId) {
|
||||
var self = this,
|
||||
obj_type_handlers = {};
|
||||
// Iterate through the object types, i.e. ['post', 'tag', 'user']
|
||||
_.each(obj_types, function (obj_type) {
|
||||
var TargetModel = objectTypeModelMap[obj_type];
|
||||
|
||||
// Iterate through the object types, i.e. ['post', 'tag', 'user']
|
||||
_.each(obj_types, function (obj_type) {
|
||||
var TargetModel = objectTypeModelMap[obj_type];
|
||||
// Create the 'handler' for the object type;
|
||||
// the '.post()' in canThis(user).edit.post()
|
||||
obj_type_handlers[obj_type] = function (modelOrId) {
|
||||
var modelId;
|
||||
|
||||
// Create the 'handler' for the object type;
|
||||
// the '.post()' in canThis(user).edit.post()
|
||||
obj_type_handlers[obj_type] = function (modelOrId) {
|
||||
var modelId;
|
||||
|
||||
if (_.isNumber(modelOrId) || _.isString(modelOrId)) {
|
||||
// It's an id already, do nothing
|
||||
modelId = modelOrId;
|
||||
} else if (modelOrId) {
|
||||
// It's a model, get the id
|
||||
modelId = modelOrId.id;
|
||||
}
|
||||
|
||||
// Wait for the user loading to finish
|
||||
return self.userPermissionLoad.then(function (userPermissions) {
|
||||
// Iterate through the user permissions looking for an affirmation
|
||||
var hasPermission;
|
||||
|
||||
// Allow for a target model to implement a "Permissable" interface
|
||||
if (TargetModel && _.isFunction(TargetModel.permissable)) {
|
||||
return TargetModel.permissable(modelId, userId, act_type, userPermissions);
|
||||
}
|
||||
|
||||
// Otherwise, check all the permissions for matching object id
|
||||
hasPermission = _.any(userPermissions, function (userPermission) {
|
||||
var permObjId;
|
||||
|
||||
// Look for a matching action type and object type first
|
||||
if (userPermission.get('action_type') !== act_type || userPermission.get('object_type') !== obj_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grab the object id (if specified, could be null)
|
||||
permObjId = userPermission.get('object_id');
|
||||
|
||||
// If we didn't specify a model (any thing)
|
||||
// or the permission didn't have an id scope set
|
||||
// then the user has permission
|
||||
if (!modelId || !permObjId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, check if the id's match
|
||||
// TODO: String vs Int comparison possibility here?
|
||||
return modelId === permObjId;
|
||||
});
|
||||
|
||||
if (hasPermission) {
|
||||
return when.resolve();
|
||||
}
|
||||
|
||||
return when.reject();
|
||||
}).otherwise(function () {
|
||||
// No permissions loaded, or error loading permissions
|
||||
|
||||
// Still check for permissable without permissions
|
||||
if (TargetModel && _.isFunction(TargetModel.permissable)) {
|
||||
return TargetModel.permissable(modelId, userId, act_type, []);
|
||||
}
|
||||
|
||||
return when.reject();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
return obj_type_handlers;
|
||||
};
|
||||
|
||||
CanThisResult.prototype.beginCheck = function (user) {
|
||||
var self = this,
|
||||
userId = user.id || user;
|
||||
|
||||
// TODO: Switch logic based on object type; user, role, post.
|
||||
|
||||
// Kick off the fetching of the user data
|
||||
this.userPermissionLoad = UserProvider.effectivePermissions(userId);
|
||||
|
||||
// Iterate through the actions and their related object types
|
||||
// We should have loaded these through a permissions.init() call previously
|
||||
// TODO: Throw error if not init() yet?
|
||||
_.each(exported.actionsMap, function (obj_types, act_type) {
|
||||
// Build up the object type handlers;
|
||||
// the '.post()' parts in canThis(user).edit.post()
|
||||
var obj_type_handlers = self.buildObjectTypeHandlers(obj_types, act_type, userId);
|
||||
|
||||
// Define a property for the action on the result;
|
||||
// the '.edit' in canThis(user).edit.post()
|
||||
Object.defineProperty(self, act_type, {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
value: obj_type_handlers
|
||||
});
|
||||
});
|
||||
|
||||
// Return this for chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
canThis = function (user) {
|
||||
var result = new CanThisResult();
|
||||
|
||||
return result.beginCheck(user);
|
||||
};
|
||||
|
||||
init = refresh = function () {
|
||||
// Load all the permissions
|
||||
return PermissionsProvider.browse().then(function (perms) {
|
||||
var seenActions = {};
|
||||
|
||||
exported.actionsMap = {};
|
||||
|
||||
// Build a hash map of the actions on objects, i.e
|
||||
/*
|
||||
{
|
||||
'edit': ['post', 'tag', 'user', 'page'],
|
||||
'delete': ['post', 'user'],
|
||||
'create': ['post', 'user', 'page']
|
||||
if (_.isNumber(modelOrId) || _.isString(modelOrId)) {
|
||||
// It's an id already, do nothing
|
||||
modelId = modelOrId;
|
||||
} else if (modelOrId) {
|
||||
// It's a model, get the id
|
||||
modelId = modelOrId.id;
|
||||
}
|
||||
*/
|
||||
_.each(perms.models, function (perm) {
|
||||
var action_type = perm.get('action_type'),
|
||||
object_type = perm.get('object_type');
|
||||
|
||||
exported.actionsMap[action_type] = exported.actionsMap[action_type] || [];
|
||||
seenActions[action_type] = seenActions[action_type] || {};
|
||||
// Wait for the user loading to finish
|
||||
return self.userPermissionLoad.then(function (userPermissions) {
|
||||
// Iterate through the user permissions looking for an affirmation
|
||||
var hasPermission;
|
||||
|
||||
// Check if we've already seen this action -> object combo
|
||||
if (seenActions[action_type][object_type]) {
|
||||
return;
|
||||
// Allow for a target model to implement a "Permissable" interface
|
||||
if (TargetModel && _.isFunction(TargetModel.permissable)) {
|
||||
return TargetModel.permissable(modelId, userId, act_type, userPermissions);
|
||||
}
|
||||
|
||||
exported.actionsMap[action_type].push(object_type);
|
||||
seenActions[action_type][object_type] = true;
|
||||
// Otherwise, check all the permissions for matching object id
|
||||
hasPermission = _.any(userPermissions, function (userPermission) {
|
||||
var permObjId;
|
||||
|
||||
// Look for a matching action type and object type first
|
||||
if (userPermission.get('action_type') !== act_type || userPermission.get('object_type') !== obj_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grab the object id (if specified, could be null)
|
||||
permObjId = userPermission.get('object_id');
|
||||
|
||||
// If we didn't specify a model (any thing)
|
||||
// or the permission didn't have an id scope set
|
||||
// then the user has permission
|
||||
if (!modelId || !permObjId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, check if the id's match
|
||||
// TODO: String vs Int comparison possibility here?
|
||||
return modelId === permObjId;
|
||||
});
|
||||
|
||||
if (hasPermission) {
|
||||
return when.resolve();
|
||||
}
|
||||
|
||||
return when.reject();
|
||||
}).otherwise(function () {
|
||||
// No permissions loaded, or error loading permissions
|
||||
|
||||
// Still check for permissable without permissions
|
||||
if (TargetModel && _.isFunction(TargetModel.permissable)) {
|
||||
return TargetModel.permissable(modelId, userId, act_type, []);
|
||||
}
|
||||
|
||||
return when.reject();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
return when(exported.actionsMap);
|
||||
return obj_type_handlers;
|
||||
};
|
||||
|
||||
CanThisResult.prototype.beginCheck = function (user) {
|
||||
var self = this,
|
||||
userId = user.id || user;
|
||||
|
||||
// TODO: Switch logic based on object type; user, role, post.
|
||||
|
||||
// Kick off the fetching of the user data
|
||||
this.userPermissionLoad = UserProvider.effectivePermissions(userId);
|
||||
|
||||
// Iterate through the actions and their related object types
|
||||
// We should have loaded these through a permissions.init() call previously
|
||||
// TODO: Throw error if not init() yet?
|
||||
_.each(exported.actionsMap, function (obj_types, act_type) {
|
||||
// Build up the object type handlers;
|
||||
// the '.post()' parts in canThis(user).edit.post()
|
||||
var obj_type_handlers = self.buildObjectTypeHandlers(obj_types, act_type, userId);
|
||||
|
||||
// Define a property for the action on the result;
|
||||
// the '.edit' in canThis(user).edit.post()
|
||||
Object.defineProperty(self, act_type, {
|
||||
writable: false,
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
value: obj_type_handlers
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = exported = {
|
||||
init: init,
|
||||
refresh: refresh,
|
||||
canThis: canThis,
|
||||
actionsMap: {}
|
||||
};
|
||||
// Return this for chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
}());
|
||||
canThis = function (user) {
|
||||
var result = new CanThisResult();
|
||||
|
||||
return result.beginCheck(user);
|
||||
};
|
||||
|
||||
init = refresh = function () {
|
||||
// Load all the permissions
|
||||
return PermissionsProvider.browse().then(function (perms) {
|
||||
var seenActions = {};
|
||||
|
||||
exported.actionsMap = {};
|
||||
|
||||
// Build a hash map of the actions on objects, i.e
|
||||
/*
|
||||
{
|
||||
'edit': ['post', 'tag', 'user', 'page'],
|
||||
'delete': ['post', 'user'],
|
||||
'create': ['post', 'user', 'page']
|
||||
}
|
||||
*/
|
||||
_.each(perms.models, function (perm) {
|
||||
var action_type = perm.get('action_type'),
|
||||
object_type = perm.get('object_type');
|
||||
|
||||
exported.actionsMap[action_type] = exported.actionsMap[action_type] || [];
|
||||
seenActions[action_type] = seenActions[action_type] || {};
|
||||
|
||||
// Check if we've already seen this action -> object combo
|
||||
if (seenActions[action_type][object_type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
exported.actionsMap[action_type].push(object_type);
|
||||
seenActions[action_type][object_type] = true;
|
||||
});
|
||||
|
||||
return when(exported.actionsMap);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = exported = {
|
||||
init: init,
|
||||
refresh: refresh,
|
||||
canThis: canThis,
|
||||
actionsMap: {}
|
||||
};
|
@ -1,11 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
'post': require('../models/post').Post,
|
||||
'role': require('../models/role').Role,
|
||||
'user': require('../models/user').User,
|
||||
'permission': require('../models/permission').Permission,
|
||||
'setting': require('../models/settings').Settings
|
||||
};
|
||||
}());
|
||||
module.exports = {
|
||||
'post': require('../models/post').Post,
|
||||
'role': require('../models/role').Role,
|
||||
'user': require('../models/user').User,
|
||||
'permission': require('../models/permission').Permission,
|
||||
'setting': require('../models/settings').Settings
|
||||
};
|
||||
|
@ -1,70 +1,67 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
var when = require('when'),
|
||||
keys = require('when/keys'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
extend = function (obj, source) {
|
||||
var key;
|
||||
for (key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
obj[key] = source[key];
|
||||
}
|
||||
var when = require('when'),
|
||||
keys = require('when/keys'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
extend = function (obj, source) {
|
||||
var key;
|
||||
for (key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
obj[key] = source[key];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
readDir = function (dir, options, depth) {
|
||||
depth = depth || 0;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
readDir = function (dir, options, depth) {
|
||||
depth = depth || 0;
|
||||
|
||||
options = extend({
|
||||
index: true
|
||||
}, options);
|
||||
options = extend({
|
||||
index: true
|
||||
}, options);
|
||||
|
||||
if (depth > 1) {
|
||||
return null;
|
||||
if (depth > 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var subtree = {},
|
||||
treeDeferred = when.defer(),
|
||||
treePromise = treeDeferred.promise;
|
||||
|
||||
fs.readdir(dir, function (error, files) {
|
||||
if (error) {
|
||||
return treeDeferred.reject(error);
|
||||
}
|
||||
|
||||
var subtree = {},
|
||||
treeDeferred = when.defer(),
|
||||
treePromise = treeDeferred.promise;
|
||||
files = files || [];
|
||||
|
||||
fs.readdir(dir, function (error, files) {
|
||||
if (error) {
|
||||
return treeDeferred.reject(error);
|
||||
}
|
||||
|
||||
files = files || [];
|
||||
|
||||
files.forEach(function (file) {
|
||||
var fileDeferred = when.defer(),
|
||||
filePromise = fileDeferred.promise,
|
||||
ext = path.extname(file),
|
||||
name = path.basename(file, ext),
|
||||
fpath = path.join(dir, file);
|
||||
subtree[name] = filePromise;
|
||||
fs.lstat(fpath, function (error, result) {
|
||||
if (result.isDirectory()) {
|
||||
fileDeferred.resolve(readDir(fpath, options, depth + 1));
|
||||
} else {
|
||||
fileDeferred.resolve(fpath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return keys.all(subtree).then(function(theFiles) {
|
||||
return treeDeferred.resolve(theFiles);
|
||||
files.forEach(function (file) {
|
||||
var fileDeferred = when.defer(),
|
||||
filePromise = fileDeferred.promise,
|
||||
ext = path.extname(file),
|
||||
name = path.basename(file, ext),
|
||||
fpath = path.join(dir, file);
|
||||
subtree[name] = filePromise;
|
||||
fs.lstat(fpath, function (error, result) {
|
||||
if (result.isDirectory()) {
|
||||
fileDeferred.resolve(readDir(fpath, options, depth + 1));
|
||||
} else {
|
||||
fileDeferred.resolve(fpath);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return when(treePromise).then(function (prom) {
|
||||
return prom;
|
||||
return keys.all(subtree).then(function(theFiles) {
|
||||
return treeDeferred.resolve(theFiles);
|
||||
});
|
||||
},
|
||||
readAll = function (dir, options, depth) {
|
||||
return when(readDir(dir, options, depth)).then(function (paths) {
|
||||
return paths;
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = readAll;
|
||||
}());
|
||||
return when(treePromise).then(function (prom) {
|
||||
return prom;
|
||||
});
|
||||
},
|
||||
readAll = function (dir, options, depth) {
|
||||
return when(readDir(dir, options, depth)).then(function (paths) {
|
||||
return paths;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = readAll;
|
@ -1,171 +1,165 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
/*globals describe, it, beforeEach */
|
||||
var should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
Models = require('../../shared/models');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe("Role Model", function () {
|
||||
|
||||
var should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
Models = require('../../shared/models');
|
||||
var RoleModel = Models.Role;
|
||||
|
||||
describe("Role Model", function () {
|
||||
should.exist(RoleModel);
|
||||
|
||||
var RoleModel = Models.Role;
|
||||
|
||||
should.exist(RoleModel);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can browse roles", function (done) {
|
||||
RoleModel.browse().then(function (foundRoles) {
|
||||
should.exist(foundRoles);
|
||||
|
||||
foundRoles.models.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can read roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can edit roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return foundRole.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return RoleModel.read({id: 1});
|
||||
}).then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedRole.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can add roles", function (done) {
|
||||
var newRole = {
|
||||
name: "test1",
|
||||
description: "test1 description"
|
||||
};
|
||||
|
||||
RoleModel.add(newRole).then(function (createdRole) {
|
||||
should.exist(createdRole);
|
||||
|
||||
createdRole.attributes.name.should.equal(newRole.name);
|
||||
createdRole.attributes.description.should.equal(newRole.description);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can delete roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return RoleModel['delete'](1);
|
||||
}).then(function () {
|
||||
return RoleModel.browse();
|
||||
}).then(function (foundRoles) {
|
||||
var hasRemovedId = foundRoles.any(function (role) {
|
||||
return role.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
describe("Permission Model", function () {
|
||||
it("can browse roles", function (done) {
|
||||
RoleModel.browse().then(function (foundRoles) {
|
||||
should.exist(foundRoles);
|
||||
|
||||
var PermissionModel = Models.Permission;
|
||||
foundRoles.models.length.should.be.above(0);
|
||||
|
||||
should.exist(PermissionModel);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can browse permissions", function (done) {
|
||||
PermissionModel.browse().then(function (foundPermissions) {
|
||||
should.exist(foundPermissions);
|
||||
|
||||
foundPermissions.models.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can read permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can edit permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
return foundPermission.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return PermissionModel.read({id: 1});
|
||||
}).then(function (updatedPermission) {
|
||||
should.exist(updatedPermission);
|
||||
|
||||
updatedPermission.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can add permissions", function (done) {
|
||||
var newPerm = {
|
||||
name: "testperm1"
|
||||
};
|
||||
|
||||
PermissionModel.add(newPerm).then(function (createdPerm) {
|
||||
should.exist(createdPerm);
|
||||
|
||||
createdPerm.attributes.name.should.equal(newPerm.name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can delete permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
return PermissionModel['delete'](1);
|
||||
}).then(function () {
|
||||
return PermissionModel.browse();
|
||||
}).then(function (foundPermissions) {
|
||||
var hasRemovedId = foundPermissions.any(function (permission) {
|
||||
return permission.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
}());
|
||||
it("can read roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can edit roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return foundRole.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return RoleModel.read({id: 1});
|
||||
}).then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedRole.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can add roles", function (done) {
|
||||
var newRole = {
|
||||
name: "test1",
|
||||
description: "test1 description"
|
||||
};
|
||||
|
||||
RoleModel.add(newRole).then(function (createdRole) {
|
||||
should.exist(createdRole);
|
||||
|
||||
createdRole.attributes.name.should.equal(newRole.name);
|
||||
createdRole.attributes.description.should.equal(newRole.description);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can delete roles", function (done) {
|
||||
RoleModel.read({id: 1}).then(function (foundRole) {
|
||||
should.exist(foundRole);
|
||||
|
||||
return RoleModel['delete'](1);
|
||||
}).then(function () {
|
||||
return RoleModel.browse();
|
||||
}).then(function (foundRoles) {
|
||||
var hasRemovedId = foundRoles.any(function (role) {
|
||||
return role.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Permission Model", function () {
|
||||
|
||||
var PermissionModel = Models.Permission;
|
||||
|
||||
should.exist(PermissionModel);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can browse permissions", function (done) {
|
||||
PermissionModel.browse().then(function (foundPermissions) {
|
||||
should.exist(foundPermissions);
|
||||
|
||||
foundPermissions.models.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can read permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can edit permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
return foundPermission.set({name: "updated"}).save();
|
||||
}).then(function () {
|
||||
return PermissionModel.read({id: 1});
|
||||
}).then(function (updatedPermission) {
|
||||
should.exist(updatedPermission);
|
||||
|
||||
updatedPermission.get("name").should.equal("updated");
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it("can add permissions", function (done) {
|
||||
var newPerm = {
|
||||
name: "testperm1"
|
||||
};
|
||||
|
||||
PermissionModel.add(newPerm).then(function (createdPerm) {
|
||||
should.exist(createdPerm);
|
||||
|
||||
createdPerm.attributes.name.should.equal(newPerm.name);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("can delete permissions", function (done) {
|
||||
PermissionModel.read({id: 1}).then(function (foundPermission) {
|
||||
should.exist(foundPermission);
|
||||
|
||||
return PermissionModel['delete'](1);
|
||||
}).then(function () {
|
||||
return PermissionModel.browse();
|
||||
}).then(function (foundPermissions) {
|
||||
var hasRemovedId = foundPermissions.any(function (permission) {
|
||||
return permission.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
});
|
@ -1,172 +1,167 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
/*globals describe, beforeEach, it */
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
Models = require('../../shared/models');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe('Post Model', function () {
|
||||
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
Models = require('../../shared/models');
|
||||
var PostModel = Models.Post;
|
||||
|
||||
describe('Post Model', function () {
|
||||
|
||||
var PostModel = Models.Post;
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.equal(2);
|
||||
// should be in published_at, DESC order
|
||||
results.models[0].attributes.published_at.should.be.above(results.models[1].attributes.published_at);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.read({slug: firstPost.attributes.slug});
|
||||
}).then(function (found) {
|
||||
should.exist(found);
|
||||
found.attributes.title.should.equal(firstPost.attributes.title);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.edit({id: firstPost.id, title: "new title"});
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
edited.attributes.title.should.equal('new title');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add, defaulting as a draft', function (done) {
|
||||
var createdPostUpdatedDate,
|
||||
newPost = {
|
||||
title: 'Test Title 1',
|
||||
content: 'Test Content 1'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({id: createdPost.id}).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.has('uuid').should.equal(true);
|
||||
createdPost.get('status').should.equal('draft');
|
||||
createdPost.get('title').should.equal(newPost.title, "title is correct");
|
||||
createdPost.get('content').should.equal(newPost.content, "content is correct");
|
||||
createdPost.get('slug').should.equal(newPost.title.toLowerCase().replace(/ /g, '-'), 'slug is correct');
|
||||
//createdPost.get('created_at').should.be.instanceOf(Date); - why is this not true?
|
||||
createdPost.get('created_by').should.equal(1);
|
||||
createdPost.get('author_id').should.equal(1);
|
||||
createdPost.get('created_by').should.equal(createdPost.get('author_id'));
|
||||
//createdPost.get('updated_at').should.be.instanceOf(Date); - why is this not true?
|
||||
createdPost.get('updated_by').should.equal(1);
|
||||
should.equal(createdPost.get('published_at'), null);
|
||||
should.equal(createdPost.get('published_by'), null);
|
||||
|
||||
createdPostUpdatedDate = createdPost.get('updated_at');
|
||||
|
||||
// Set the status to published to check that `published_at` is set.
|
||||
return createdPost.save({status: 'published'});
|
||||
}).then(function (publishedPost) {
|
||||
publishedPost.get('published_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('published_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('updated_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.not.equal(createdPostUpdatedDate);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstPostId;
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPostId = results.models[0].id;
|
||||
|
||||
return PostModel.destroy(firstPostId);
|
||||
}).then(function () {
|
||||
return PostModel.browse();
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
|
||||
return id === firstPostId;
|
||||
});
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can fetch a paginated set, with various options', function (done) {
|
||||
this.timeout(4000);
|
||||
|
||||
helpers.insertMorePosts().then(function () {
|
||||
|
||||
return PostModel.findPage({page: 2});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(15);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({page: 5});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(5);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(0);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({limit: 30});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(1);
|
||||
paginationResult.limit.should.equal(30);
|
||||
paginationResult.posts.length.should.equal(30);
|
||||
paginationResult.pages.should.equal(2);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, where: {language: 'fr'}});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(10);
|
||||
paginationResult.posts.length.should.equal(10);
|
||||
paginationResult.pages.should.equal(3);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, status: 'all'});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.pages.should.equal(11);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
}());
|
||||
|
||||
it('can browse', function (done) {
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.equal(2);
|
||||
// should be in published_at, DESC order
|
||||
results.models[0].attributes.published_at.should.be.above(results.models[1].attributes.published_at);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.read({slug: firstPost.attributes.slug});
|
||||
}).then(function (found) {
|
||||
should.exist(found);
|
||||
found.attributes.title.should.equal(firstPost.attributes.title);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPost = results.models[0];
|
||||
|
||||
return PostModel.edit({id: firstPost.id, title: "new title"});
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
edited.attributes.title.should.equal('new title');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add, defaulting as a draft', function (done) {
|
||||
var createdPostUpdatedDate,
|
||||
newPost = {
|
||||
title: 'Test Title 1',
|
||||
content: 'Test Content 1'
|
||||
};
|
||||
|
||||
PostModel.add(newPost).then(function (createdPost) {
|
||||
return new PostModel({id: createdPost.id}).fetch();
|
||||
}).then(function (createdPost) {
|
||||
should.exist(createdPost);
|
||||
createdPost.has('uuid').should.equal(true);
|
||||
createdPost.get('status').should.equal('draft');
|
||||
createdPost.get('title').should.equal(newPost.title, "title is correct");
|
||||
createdPost.get('content').should.equal(newPost.content, "content is correct");
|
||||
createdPost.get('slug').should.equal(newPost.title.toLowerCase().replace(/ /g, '-'), 'slug is correct');
|
||||
//createdPost.get('created_at').should.be.instanceOf(Date); - why is this not true?
|
||||
createdPost.get('created_by').should.equal(1);
|
||||
createdPost.get('author_id').should.equal(1);
|
||||
createdPost.get('created_by').should.equal(createdPost.get('author_id'));
|
||||
//createdPost.get('updated_at').should.be.instanceOf(Date); - why is this not true?
|
||||
createdPost.get('updated_by').should.equal(1);
|
||||
should.equal(createdPost.get('published_at'), null);
|
||||
should.equal(createdPost.get('published_by'), null);
|
||||
|
||||
createdPostUpdatedDate = createdPost.get('updated_at');
|
||||
|
||||
// Set the status to published to check that `published_at` is set.
|
||||
return createdPost.save({status: 'published'});
|
||||
}).then(function (publishedPost) {
|
||||
publishedPost.get('published_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('published_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.be.instanceOf(Date);
|
||||
publishedPost.get('updated_by').should.equal(1);
|
||||
publishedPost.get('updated_at').should.not.equal(createdPostUpdatedDate);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstPostId;
|
||||
PostModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
results.length.should.be.above(0);
|
||||
firstPostId = results.models[0].id;
|
||||
|
||||
return PostModel.destroy(firstPostId);
|
||||
}).then(function () {
|
||||
return PostModel.browse();
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
|
||||
return id === firstPostId;
|
||||
});
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can fetch a paginated set, with various options', function (done) {
|
||||
this.timeout(4000);
|
||||
|
||||
helpers.insertMorePosts().then(function () {
|
||||
|
||||
return PostModel.findPage({page: 2});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(15);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({page: 5});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(5);
|
||||
paginationResult.limit.should.equal(15);
|
||||
paginationResult.posts.length.should.equal(0);
|
||||
paginationResult.pages.should.equal(4);
|
||||
|
||||
return PostModel.findPage({limit: 30});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(1);
|
||||
paginationResult.limit.should.equal(30);
|
||||
paginationResult.posts.length.should.equal(30);
|
||||
paginationResult.pages.should.equal(2);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, where: {language: 'fr'}});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.page.should.equal(2);
|
||||
paginationResult.limit.should.equal(10);
|
||||
paginationResult.posts.length.should.equal(10);
|
||||
paginationResult.pages.should.equal(3);
|
||||
|
||||
return PostModel.findPage({limit: 10, page: 2, status: 'all'});
|
||||
}).then(function (paginationResult) {
|
||||
paginationResult.pages.should.equal(11);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
@ -1,183 +1,178 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
Models = require('../../shared/models');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe('Settings Model', function () {
|
||||
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
Models = require('../../shared/models');
|
||||
var SettingsModel = Models.Settings;
|
||||
|
||||
describe('Settings Model', function () {
|
||||
|
||||
var SettingsModel = Models.Settings;
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstSetting;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSetting = results.models[0];
|
||||
|
||||
return SettingsModel.read(firstSetting.attributes.key);
|
||||
|
||||
}).then(function (found) {
|
||||
|
||||
should.exist(found);
|
||||
|
||||
found.attributes.value.should.equal(firstSetting.attributes.value);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit single', function (done) {
|
||||
var firstSetting;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSetting = results.models[0];
|
||||
|
||||
// The edit method has been modified to take an object of
|
||||
// key/value pairs
|
||||
firstSetting.set('value', 'new value');
|
||||
|
||||
return SettingsModel.edit(firstSetting);
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.length.should.equal(1);
|
||||
|
||||
edited = edited[0];
|
||||
|
||||
edited.attributes.key.should.equal(firstSetting.attributes.key);
|
||||
edited.attributes.value.should.equal('new value');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit multiple', function (done) {
|
||||
var model1,
|
||||
model2,
|
||||
editedModel;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
model1 = results.models[0];
|
||||
model2 = results.models[1];
|
||||
|
||||
// The edit method has been modified to take an object of
|
||||
// key/value pairs
|
||||
model1.set('value', 'new value1');
|
||||
model2.set('value', 'new value2');
|
||||
|
||||
return SettingsModel.edit([model1, model2]);
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.length.should.equal(2);
|
||||
|
||||
editedModel = edited[0];
|
||||
|
||||
editedModel.attributes.key.should.equal(model1.attributes.key);
|
||||
editedModel.attributes.value.should.equal('new value1');
|
||||
|
||||
editedModel = edited[1];
|
||||
|
||||
editedModel.attributes.key.should.equal(model2.attributes.key);
|
||||
editedModel.attributes.value.should.equal('new value2');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add', function (done) {
|
||||
var newSetting = {
|
||||
key: 'TestSetting1',
|
||||
value: 'Test Content 1'
|
||||
};
|
||||
|
||||
SettingsModel.add(newSetting).then(function (createdSetting) {
|
||||
|
||||
should.exist(createdSetting);
|
||||
createdSetting.has('uuid').should.equal(true);
|
||||
createdSetting.attributes.key.should.equal(newSetting.key, "key is correct");
|
||||
createdSetting.attributes.value.should.equal(newSetting.value, "value is correct");
|
||||
createdSetting.attributes.type.should.equal("general");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstSettingId;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSettingId = results.models[0].id;
|
||||
|
||||
return SettingsModel.destroy(firstSettingId);
|
||||
|
||||
}).then(function () {
|
||||
|
||||
return SettingsModel.browse();
|
||||
|
||||
}).then(function (newResults) {
|
||||
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstSettingId;
|
||||
});
|
||||
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
}());
|
||||
|
||||
it('can browse', function (done) {
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstSetting;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSetting = results.models[0];
|
||||
|
||||
return SettingsModel.read(firstSetting.attributes.key);
|
||||
|
||||
}).then(function (found) {
|
||||
|
||||
should.exist(found);
|
||||
|
||||
found.attributes.value.should.equal(firstSetting.attributes.value);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit single', function (done) {
|
||||
var firstSetting;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSetting = results.models[0];
|
||||
|
||||
// The edit method has been modified to take an object of
|
||||
// key/value pairs
|
||||
firstSetting.set('value', 'new value');
|
||||
|
||||
return SettingsModel.edit(firstSetting);
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.length.should.equal(1);
|
||||
|
||||
edited = edited[0];
|
||||
|
||||
edited.attributes.key.should.equal(firstSetting.attributes.key);
|
||||
edited.attributes.value.should.equal('new value');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit multiple', function (done) {
|
||||
var model1,
|
||||
model2,
|
||||
editedModel;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
model1 = results.models[0];
|
||||
model2 = results.models[1];
|
||||
|
||||
// The edit method has been modified to take an object of
|
||||
// key/value pairs
|
||||
model1.set('value', 'new value1');
|
||||
model2.set('value', 'new value2');
|
||||
|
||||
return SettingsModel.edit([model1, model2]);
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.length.should.equal(2);
|
||||
|
||||
editedModel = edited[0];
|
||||
|
||||
editedModel.attributes.key.should.equal(model1.attributes.key);
|
||||
editedModel.attributes.value.should.equal('new value1');
|
||||
|
||||
editedModel = edited[1];
|
||||
|
||||
editedModel.attributes.key.should.equal(model2.attributes.key);
|
||||
editedModel.attributes.value.should.equal('new value2');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can add', function (done) {
|
||||
var newSetting = {
|
||||
key: 'TestSetting1',
|
||||
value: 'Test Content 1'
|
||||
};
|
||||
|
||||
SettingsModel.add(newSetting).then(function (createdSetting) {
|
||||
|
||||
should.exist(createdSetting);
|
||||
createdSetting.has('uuid').should.equal(true);
|
||||
createdSetting.attributes.key.should.equal(newSetting.key, "key is correct");
|
||||
createdSetting.attributes.value.should.equal(newSetting.value, "value is correct");
|
||||
createdSetting.attributes.type.should.equal("general");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstSettingId;
|
||||
|
||||
SettingsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstSettingId = results.models[0].id;
|
||||
|
||||
return SettingsModel.destroy(firstSettingId);
|
||||
|
||||
}).then(function () {
|
||||
|
||||
return SettingsModel.browse();
|
||||
|
||||
}).then(function (newResults) {
|
||||
|
||||
var ids, hasDeletedId;
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstSettingId;
|
||||
});
|
||||
|
||||
hasDeletedId.should.equal(false);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
@ -1,163 +1,158 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var _ = require('underscore'),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
Models = require('../../shared/models'),
|
||||
when = require('when');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
require('mocha-as-promised')();
|
||||
|
||||
var _ = require('underscore'),
|
||||
should = require('should'),
|
||||
helpers = require('./helpers'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
Models = require('../../shared/models'),
|
||||
when = require('when');
|
||||
describe('User Model', function () {
|
||||
|
||||
require('mocha-as-promised')();
|
||||
var UserModel = Models.User;
|
||||
|
||||
describe('User Model', function () {
|
||||
|
||||
var UserModel = Models.User;
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function (result) {
|
||||
return when(helpers.insertDefaultUser());
|
||||
}).then(function (results) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can add first', function (done) {
|
||||
var userData = {
|
||||
password: 'testpass1',
|
||||
email_address: "test@test1.com"
|
||||
};
|
||||
|
||||
when(helpers.resetData()).then(function (result) {
|
||||
UserModel.add(userData).then(function (createdUser) {
|
||||
should.exist(createdUser);
|
||||
createdUser.has('uuid').should.equal(true);
|
||||
createdUser.attributes.password.should.not.equal(userData.password, "password was hashed");
|
||||
createdUser.attributes.email_address.should.eql(userData.email_address, "email address corred");
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t add second', function (done) {
|
||||
var userData = {
|
||||
password: 'testpass3',
|
||||
email_address: "test3@test1.com"
|
||||
};
|
||||
|
||||
return when(UserModel.add(userData)).otherwise(function (failure) {
|
||||
return failure.message.should.eql('A user is already registered. Only one user for now!');
|
||||
});
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstUser;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUser = results.models[0];
|
||||
|
||||
return UserModel.read({email_address: firstUser.attributes.email_address});
|
||||
|
||||
}).then(function (found) {
|
||||
|
||||
should.exist(found);
|
||||
|
||||
found.attributes.full_name.should.equal(firstUser.attributes.full_name);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstUser;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUser = results.models[0];
|
||||
|
||||
return UserModel.edit({id: firstUser.id, url: "some.newurl.com"});
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.attributes.url.should.equal('some.newurl.com');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can get effective permissions", function (done) {
|
||||
UserModel.effectivePermissions(1).then(function (effectivePermissions) {
|
||||
should.exist(effectivePermissions);
|
||||
|
||||
effectivePermissions.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstUserId;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUserId = results.models[0].id;
|
||||
|
||||
return UserModel.destroy(firstUserId);
|
||||
|
||||
}).then(function () {
|
||||
|
||||
return UserModel.browse();
|
||||
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
if (newResults.length < 1) {
|
||||
// Bug out if we only had one user and deleted it.
|
||||
return done();
|
||||
}
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstUserId;
|
||||
});
|
||||
|
||||
hasDeletedId.should.equal(false);
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function (result) {
|
||||
return when(helpers.insertDefaultUser());
|
||||
}).then(function (results) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
it('can add first', function (done) {
|
||||
var userData = {
|
||||
password: 'testpass1',
|
||||
email_address: "test@test1.com"
|
||||
};
|
||||
|
||||
when(helpers.resetData()).then(function (result) {
|
||||
UserModel.add(userData).then(function (createdUser) {
|
||||
should.exist(createdUser);
|
||||
createdUser.has('uuid').should.equal(true);
|
||||
createdUser.attributes.password.should.not.equal(userData.password, "password was hashed");
|
||||
createdUser.attributes.email_address.should.eql(userData.email_address, "email address corred");
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t add second', function (done) {
|
||||
var userData = {
|
||||
password: 'testpass3',
|
||||
email_address: "test3@test1.com"
|
||||
};
|
||||
|
||||
return when(UserModel.add(userData)).otherwise(function (failure) {
|
||||
return failure.message.should.eql('A user is already registered. Only one user for now!');
|
||||
});
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
var firstUser;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUser = results.models[0];
|
||||
|
||||
return UserModel.read({email_address: firstUser.attributes.email_address});
|
||||
|
||||
}).then(function (found) {
|
||||
|
||||
should.exist(found);
|
||||
|
||||
found.attributes.full_name.should.equal(firstUser.attributes.full_name);
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
var firstUser;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUser = results.models[0];
|
||||
|
||||
return UserModel.edit({id: firstUser.id, url: "some.newurl.com"});
|
||||
|
||||
}).then(function (edited) {
|
||||
|
||||
should.exist(edited);
|
||||
|
||||
edited.attributes.url.should.equal('some.newurl.com');
|
||||
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can get effective permissions", function (done) {
|
||||
UserModel.effectivePermissions(1).then(function (effectivePermissions) {
|
||||
should.exist(effectivePermissions);
|
||||
|
||||
effectivePermissions.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}, errors.logError);
|
||||
});
|
||||
|
||||
it('can delete', function (done) {
|
||||
var firstUserId;
|
||||
|
||||
UserModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
firstUserId = results.models[0].id;
|
||||
|
||||
return UserModel.destroy(firstUserId);
|
||||
|
||||
}).then(function () {
|
||||
|
||||
return UserModel.browse();
|
||||
|
||||
}).then(function (newResults) {
|
||||
var ids, hasDeletedId;
|
||||
|
||||
if (newResults.length < 1) {
|
||||
// Bug out if we only had one user and deleted it.
|
||||
return done();
|
||||
}
|
||||
|
||||
ids = _.pluck(newResults.models, "id");
|
||||
hasDeletedId = _.any(ids, function (id) {
|
||||
return id === firstUserId;
|
||||
});
|
||||
|
||||
hasDeletedId.should.equal(false);
|
||||
done();
|
||||
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
@ -1,111 +1,106 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe("Error handling", function () {
|
||||
|
||||
var should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
// Just getting rid of jslint unused error
|
||||
should.exist(errors);
|
||||
|
||||
describe("Error handling", function () {
|
||||
it("throws error objects", function () {
|
||||
var toThrow = new Error("test1"),
|
||||
runThrowError = function () {
|
||||
errors.throwError(toThrow);
|
||||
};
|
||||
|
||||
// Just getting rid of jslint unused error
|
||||
should.exist(errors);
|
||||
|
||||
it("throws error objects", function () {
|
||||
var toThrow = new Error("test1"),
|
||||
runThrowError = function () {
|
||||
errors.throwError(toThrow);
|
||||
};
|
||||
|
||||
runThrowError.should['throw']("test1");
|
||||
});
|
||||
|
||||
it("throws error strings", function () {
|
||||
var toThrow = "test2",
|
||||
runThrowError = function () {
|
||||
errors.throwError(toThrow);
|
||||
};
|
||||
|
||||
runThrowError.should['throw']("test2");
|
||||
});
|
||||
|
||||
it("throws error even if nothing passed", function () {
|
||||
var runThrowError = function () {
|
||||
errors.throwError();
|
||||
};
|
||||
|
||||
runThrowError.should['throw']("An error occurred");
|
||||
});
|
||||
|
||||
it("logs errors", function () {
|
||||
var err = new Error("test1"),
|
||||
logStub = sinon.stub(console, "log");
|
||||
|
||||
errors.logError(err);
|
||||
|
||||
// Calls log with message on Error objects
|
||||
logStub.calledWith("Error occurred: ", err.message).should.equal(true);
|
||||
|
||||
logStub.reset();
|
||||
|
||||
err = "test2";
|
||||
|
||||
errors.logError(err);
|
||||
|
||||
// Calls log with string on strings
|
||||
logStub.calledWith("Error occurred: ", err).should.equal(true);
|
||||
|
||||
logStub.restore();
|
||||
});
|
||||
|
||||
it("logs promise errors with custom messages", function (done) {
|
||||
var def = when.defer(),
|
||||
prom = def.promise,
|
||||
logStub = sinon.stub(console, "log");
|
||||
|
||||
prom.then(function () {
|
||||
throw new Error("Ran success handler");
|
||||
}, errors.logErrorWithMessage("test1"));
|
||||
|
||||
prom.otherwise(function () {
|
||||
logStub.calledWith("Error occurred: ", "test1").should.equal(true);
|
||||
logStub.restore();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
def.reject();
|
||||
});
|
||||
|
||||
it("logs promise errors and redirects", function (done) {
|
||||
var def = when.defer(),
|
||||
prom = def.promise,
|
||||
req = null,
|
||||
res = {
|
||||
redirect: function () {
|
||||
return;
|
||||
}
|
||||
},
|
||||
logStub = sinon.stub(console, "log"),
|
||||
redirectStub = sinon.stub(res, "redirect");
|
||||
|
||||
prom.then(function () {
|
||||
throw new Error("Ran success handler");
|
||||
}, errors.logErrorWithRedirect("test1", "/testurl", req, res));
|
||||
|
||||
prom.otherwise(function () {
|
||||
logStub.calledWith("Error occurred: ", "test1").should.equal(true);
|
||||
logStub.restore();
|
||||
|
||||
redirectStub.calledWith('/testurl').should.equal(true);
|
||||
redirectStub.restore();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
def.reject();
|
||||
});
|
||||
runThrowError.should['throw']("test1");
|
||||
});
|
||||
}());
|
||||
|
||||
it("throws error strings", function () {
|
||||
var toThrow = "test2",
|
||||
runThrowError = function () {
|
||||
errors.throwError(toThrow);
|
||||
};
|
||||
|
||||
runThrowError.should['throw']("test2");
|
||||
});
|
||||
|
||||
it("throws error even if nothing passed", function () {
|
||||
var runThrowError = function () {
|
||||
errors.throwError();
|
||||
};
|
||||
|
||||
runThrowError.should['throw']("An error occurred");
|
||||
});
|
||||
|
||||
it("logs errors", function () {
|
||||
var err = new Error("test1"),
|
||||
logStub = sinon.stub(console, "log");
|
||||
|
||||
errors.logError(err);
|
||||
|
||||
// Calls log with message on Error objects
|
||||
logStub.calledWith("Error occurred: ", err.message).should.equal(true);
|
||||
|
||||
logStub.reset();
|
||||
|
||||
err = "test2";
|
||||
|
||||
errors.logError(err);
|
||||
|
||||
// Calls log with string on strings
|
||||
logStub.calledWith("Error occurred: ", err).should.equal(true);
|
||||
|
||||
logStub.restore();
|
||||
});
|
||||
|
||||
it("logs promise errors with custom messages", function (done) {
|
||||
var def = when.defer(),
|
||||
prom = def.promise,
|
||||
logStub = sinon.stub(console, "log");
|
||||
|
||||
prom.then(function () {
|
||||
throw new Error("Ran success handler");
|
||||
}, errors.logErrorWithMessage("test1"));
|
||||
|
||||
prom.otherwise(function () {
|
||||
logStub.calledWith("Error occurred: ", "test1").should.equal(true);
|
||||
logStub.restore();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
def.reject();
|
||||
});
|
||||
|
||||
it("logs promise errors and redirects", function (done) {
|
||||
var def = when.defer(),
|
||||
prom = def.promise,
|
||||
req = null,
|
||||
res = {
|
||||
redirect: function () {
|
||||
return;
|
||||
}
|
||||
},
|
||||
logStub = sinon.stub(console, "log"),
|
||||
redirectStub = sinon.stub(res, "redirect");
|
||||
|
||||
prom.then(function () {
|
||||
throw new Error("Ran success handler");
|
||||
}, errors.logErrorWithRedirect("test1", "/testurl", req, res));
|
||||
|
||||
prom.otherwise(function () {
|
||||
logStub.calledWith("Error occurred: ", "test1").should.equal(true);
|
||||
logStub.restore();
|
||||
|
||||
redirectStub.calledWith('/testurl').should.equal(true);
|
||||
redirectStub.restore();
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
def.reject();
|
||||
});
|
||||
});
|
@ -1,67 +1,60 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
helpers = require('./helpers'),
|
||||
exporter = require('../../shared/data/export'),
|
||||
Exporter001 = require('../../shared/data/export/001'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe("Export", function () {
|
||||
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
helpers = require('./helpers'),
|
||||
exporter = require('../../shared/data/export'),
|
||||
Exporter001 = require('../../shared/data/export/001'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
|
||||
describe("Export", function () {
|
||||
|
||||
should.exist(exporter);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("resolves 001", function (done) {
|
||||
var exportStub = sinon.stub(Exporter001, "exportData", function () {
|
||||
return when.resolve();
|
||||
});
|
||||
|
||||
exporter("001").then(function () {
|
||||
exportStub.called.should.equal(true);
|
||||
|
||||
exportStub.restore();
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
|
||||
describe("001", function () {
|
||||
|
||||
should.exist(Exporter001);
|
||||
|
||||
it("exports data", function (done) {
|
||||
exporter("001").then(function (exportData) {
|
||||
var tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'];
|
||||
|
||||
should.exist(exportData);
|
||||
|
||||
should.exist(exportData.meta);
|
||||
should.exist(exportData.data);
|
||||
|
||||
exportData.meta.version.should.equal("001");
|
||||
|
||||
_.each(tables, function (name) {
|
||||
should.exist(exportData.data[name]);
|
||||
});
|
||||
|
||||
done();
|
||||
}, function () {
|
||||
console.log("Error in exporter");
|
||||
});
|
||||
});
|
||||
});
|
||||
should.exist(exporter);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
}());
|
||||
it("resolves 001", function (done) {
|
||||
var exportStub = sinon.stub(Exporter001, "exportData", function () {
|
||||
return when.resolve();
|
||||
});
|
||||
|
||||
exporter("001").then(function () {
|
||||
exportStub.called.should.equal(true);
|
||||
|
||||
exportStub.restore();
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
|
||||
describe("001", function () {
|
||||
|
||||
should.exist(Exporter001);
|
||||
|
||||
it("exports data", function (done) {
|
||||
exporter("001").then(function (exportData) {
|
||||
var tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'];
|
||||
|
||||
should.exist(exportData);
|
||||
|
||||
should.exist(exportData.meta);
|
||||
should.exist(exportData.data);
|
||||
|
||||
exportData.meta.version.should.equal("001");
|
||||
|
||||
_.each(tables, function (name) {
|
||||
should.exist(exportData.data[name]);
|
||||
});
|
||||
|
||||
done();
|
||||
}, function () {
|
||||
console.log("Error in exporter");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,69 +1,65 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
(function () {
|
||||
"use strict";
|
||||
var should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
_ = require('underscore'),
|
||||
path = require('path'),
|
||||
GhostNavHelper = require('../../frontend/helpers/ghostNav');
|
||||
|
||||
var should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
_ = require('underscore'),
|
||||
path = require('path'),
|
||||
GhostNavHelper = require('../../frontend/helpers/ghostNav');
|
||||
describe('ghostNav Helper', function () {
|
||||
var navTemplatePath = path.join(process.cwd(), 'core/frontend/views/nav.hbs');
|
||||
|
||||
describe('ghostNav Helper', function () {
|
||||
var navTemplatePath = path.join(process.cwd(), 'core/frontend/views/nav.hbs');
|
||||
should.exist(GhostNavHelper, "GhostNavHelper exists");
|
||||
|
||||
should.exist(GhostNavHelper, "GhostNavHelper exists");
|
||||
it('can compile the nav template', function (done) {
|
||||
var helper = new GhostNavHelper(navTemplatePath);
|
||||
|
||||
it('can compile the nav template', function (done) {
|
||||
var helper = new GhostNavHelper(navTemplatePath);
|
||||
helper.compileTemplate().then(function () {
|
||||
should.exist(helper.navTemplateFunc);
|
||||
_.isFunction(helper.navTemplateFunc).should.equal(true);
|
||||
|
||||
helper.compileTemplate().then(function () {
|
||||
should.exist(helper.navTemplateFunc);
|
||||
_.isFunction(helper.navTemplateFunc).should.equal(true);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can render nav items', function () {
|
||||
var helper = new GhostNavHelper(function (data) { return "rendered " + data.links.length; }),
|
||||
templateSpy = sinon.spy(helper, 'navTemplateFunc'),
|
||||
fakeNavItems = [{
|
||||
title: 'test1',
|
||||
url: '/test1'
|
||||
}, {
|
||||
title: 'test2',
|
||||
url: '/test2'
|
||||
}],
|
||||
rendered;
|
||||
|
||||
rendered = helper.renderNavItems(fakeNavItems);
|
||||
|
||||
// Returns a string returned from navTemplateFunc
|
||||
should.exist(rendered);
|
||||
rendered.should.equal("rendered 2");
|
||||
|
||||
templateSpy.calledWith({ links: fakeNavItems }).should.equal(true);
|
||||
});
|
||||
|
||||
it('can register with ghost', function (done) {
|
||||
var fakeGhost = {
|
||||
paths: function () {
|
||||
return {
|
||||
frontendViews: path.join(process.cwd(), 'core/frontend/views/')
|
||||
};
|
||||
},
|
||||
|
||||
registerThemeHelper: function () {
|
||||
return;
|
||||
}
|
||||
},
|
||||
registerStub = sinon.stub(fakeGhost, 'registerThemeHelper');
|
||||
|
||||
GhostNavHelper.registerWithGhost(fakeGhost).then(function () {
|
||||
registerStub.called.should.equal(true);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
}());
|
||||
|
||||
it('can render nav items', function () {
|
||||
var helper = new GhostNavHelper(function (data) { return "rendered " + data.links.length; }),
|
||||
templateSpy = sinon.spy(helper, 'navTemplateFunc'),
|
||||
fakeNavItems = [{
|
||||
title: 'test1',
|
||||
url: '/test1'
|
||||
}, {
|
||||
title: 'test2',
|
||||
url: '/test2'
|
||||
}],
|
||||
rendered;
|
||||
|
||||
rendered = helper.renderNavItems(fakeNavItems);
|
||||
|
||||
// Returns a string returned from navTemplateFunc
|
||||
should.exist(rendered);
|
||||
rendered.should.equal("rendered 2");
|
||||
|
||||
templateSpy.calledWith({ links: fakeNavItems }).should.equal(true);
|
||||
});
|
||||
|
||||
it('can register with ghost', function (done) {
|
||||
var fakeGhost = {
|
||||
paths: function () {
|
||||
return {
|
||||
frontendViews: path.join(process.cwd(), 'core/frontend/views/')
|
||||
};
|
||||
},
|
||||
|
||||
registerThemeHelper: function () {
|
||||
return;
|
||||
}
|
||||
},
|
||||
registerStub = sinon.stub(fakeGhost, 'registerThemeHelper');
|
||||
|
||||
GhostNavHelper.registerWithGhost(fakeGhost).then(function () {
|
||||
registerStub.called.should.equal(true);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
});
|
@ -1,101 +1,94 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
Ghost = require('../../ghost');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe("Ghost API", function () {
|
||||
|
||||
var should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
Ghost = require('../../ghost');
|
||||
it("is a singleton", function () {
|
||||
var logStub = sinon.stub(console, "log"),
|
||||
ghost1 = new Ghost(),
|
||||
ghost2 = new Ghost();
|
||||
|
||||
describe("Ghost API", function () {
|
||||
should.strictEqual(ghost1, ghost2);
|
||||
logStub.restore();
|
||||
});
|
||||
|
||||
it("is a singleton", function () {
|
||||
var logStub = sinon.stub(console, "log"),
|
||||
ghost1 = new Ghost(),
|
||||
ghost2 = new Ghost();
|
||||
it("uses init() to initialize", function (done) {
|
||||
var ghost = new Ghost(),
|
||||
fakeDataProvider = {
|
||||
init: function () {
|
||||
return when.resolve();
|
||||
}
|
||||
},
|
||||
dataProviderInitSpy = sinon.spy(fakeDataProvider, "init"),
|
||||
oldDataProvider = ghost.dataProvider;
|
||||
|
||||
should.strictEqual(ghost1, ghost2);
|
||||
logStub.restore();
|
||||
});
|
||||
ghost.dataProvider = fakeDataProvider;
|
||||
|
||||
it("uses init() to initialize", function (done) {
|
||||
var ghost = new Ghost(),
|
||||
fakeDataProvider = {
|
||||
init: function () {
|
||||
return when.resolve();
|
||||
}
|
||||
},
|
||||
dataProviderInitSpy = sinon.spy(fakeDataProvider, "init"),
|
||||
oldDataProvider = ghost.dataProvider;
|
||||
should.not.exist(ghost.settings());
|
||||
|
||||
ghost.dataProvider = fakeDataProvider;
|
||||
ghost.init().then(function () {
|
||||
|
||||
should.not.exist(ghost.settings());
|
||||
should.exist(ghost.settings());
|
||||
|
||||
ghost.init().then(function () {
|
||||
dataProviderInitSpy.called.should.equal(true);
|
||||
|
||||
should.exist(ghost.settings());
|
||||
ghost.dataProvider = oldDataProvider;
|
||||
|
||||
dataProviderInitSpy.called.should.equal(true);
|
||||
|
||||
ghost.dataProvider = oldDataProvider;
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
it("can register filters with specific priority", function () {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'test',
|
||||
filterPriority = 9,
|
||||
testFilterHandler = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, filterPriority, testFilterHandler);
|
||||
|
||||
should.exist(ghost.filterCallbacks[filterName]);
|
||||
should.exist(ghost.filterCallbacks[filterName][filterPriority]);
|
||||
|
||||
ghost.filterCallbacks[filterName][filterPriority].should.include(testFilterHandler);
|
||||
});
|
||||
|
||||
it("can register filters with default priority", function () {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'test',
|
||||
defaultPriority = 5,
|
||||
testFilterHandler = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, testFilterHandler);
|
||||
|
||||
should.exist(ghost.filterCallbacks[filterName]);
|
||||
should.exist(ghost.filterCallbacks[filterName][defaultPriority]);
|
||||
|
||||
ghost.filterCallbacks[filterName][defaultPriority].should.include(testFilterHandler);
|
||||
});
|
||||
|
||||
it("executes filters in priority order", function (done) {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'testpriority',
|
||||
testFilterHandler1 = sinon.spy(),
|
||||
testFilterHandler2 = sinon.spy(),
|
||||
testFilterHandler3 = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, 0, testFilterHandler1);
|
||||
ghost.registerFilter(filterName, 2, testFilterHandler2);
|
||||
ghost.registerFilter(filterName, 9, testFilterHandler3);
|
||||
|
||||
ghost.doFilter(filterName, null, function () {
|
||||
|
||||
testFilterHandler1.calledBefore(testFilterHandler2).should.equal(true);
|
||||
testFilterHandler2.calledBefore(testFilterHandler3).should.equal(true);
|
||||
|
||||
testFilterHandler3.called.should.equal(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
done();
|
||||
}).then(null, done);
|
||||
|
||||
});
|
||||
|
||||
}());
|
||||
it("can register filters with specific priority", function () {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'test',
|
||||
filterPriority = 9,
|
||||
testFilterHandler = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, filterPriority, testFilterHandler);
|
||||
|
||||
should.exist(ghost.filterCallbacks[filterName]);
|
||||
should.exist(ghost.filterCallbacks[filterName][filterPriority]);
|
||||
|
||||
ghost.filterCallbacks[filterName][filterPriority].should.include(testFilterHandler);
|
||||
});
|
||||
|
||||
it("can register filters with default priority", function () {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'test',
|
||||
defaultPriority = 5,
|
||||
testFilterHandler = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, testFilterHandler);
|
||||
|
||||
should.exist(ghost.filterCallbacks[filterName]);
|
||||
should.exist(ghost.filterCallbacks[filterName][defaultPriority]);
|
||||
|
||||
ghost.filterCallbacks[filterName][defaultPriority].should.include(testFilterHandler);
|
||||
});
|
||||
|
||||
it("executes filters in priority order", function (done) {
|
||||
var ghost = new Ghost(),
|
||||
filterName = 'testpriority',
|
||||
testFilterHandler1 = sinon.spy(),
|
||||
testFilterHandler2 = sinon.spy(),
|
||||
testFilterHandler3 = sinon.spy();
|
||||
|
||||
ghost.registerFilter(filterName, 0, testFilterHandler1);
|
||||
ghost.registerFilter(filterName, 2, testFilterHandler2);
|
||||
ghost.registerFilter(filterName, 9, testFilterHandler3);
|
||||
|
||||
ghost.doFilter(filterName, null, function () {
|
||||
|
||||
testFilterHandler1.calledBefore(testFilterHandler2).should.equal(true);
|
||||
testFilterHandler2.calledBefore(testFilterHandler3).should.equal(true);
|
||||
|
||||
testFilterHandler3.called.should.equal(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
File diff suppressed because one or more lines are too long
@ -1,85 +1,78 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
knex = require("../../shared/models/base").Knex,
|
||||
helpers = require('./helpers'),
|
||||
exporter = require('../../shared/data/export'),
|
||||
importer = require('../../shared/data/import'),
|
||||
Importer001 = require('../../shared/data/import/001'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe("Import", function () {
|
||||
|
||||
var _ = require("underscore"),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
sinon = require('sinon'),
|
||||
knex = require("../../shared/models/base").Knex,
|
||||
helpers = require('./helpers'),
|
||||
exporter = require('../../shared/data/export'),
|
||||
importer = require('../../shared/data/import'),
|
||||
Importer001 = require('../../shared/data/import/001'),
|
||||
errors = require('../../shared/errorHandling');
|
||||
|
||||
describe("Import", function () {
|
||||
|
||||
should.exist(exporter);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it("resolves 001", function (done) {
|
||||
var importStub = sinon.stub(Importer001, "importData", function () {
|
||||
return when.resolve();
|
||||
}),
|
||||
fakeData = { test: true };
|
||||
|
||||
importer("001", fakeData).then(function () {
|
||||
importStub.calledWith(fakeData).should.equal(true);
|
||||
|
||||
importStub.restore();
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
|
||||
describe("001", function () {
|
||||
this.timeout(4000);
|
||||
|
||||
should.exist(Importer001);
|
||||
|
||||
it("imports data from 001", function (done) {
|
||||
var exportData;
|
||||
// TODO: Should have static test data here?
|
||||
exporter("001").then(function (exported) {
|
||||
exportData = exported;
|
||||
|
||||
// Clear the data from all tables.
|
||||
var tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'],
|
||||
truncateOps = _.map(tables, function (name) {
|
||||
return knex(name).truncate();
|
||||
});
|
||||
|
||||
return when.all(truncateOps);
|
||||
}).then(function () {
|
||||
return importer("001", exportData);
|
||||
}).then(function (importResult) {
|
||||
// Grab the data from tables
|
||||
return when.all([
|
||||
knex("users").select(),
|
||||
knex("posts").select(),
|
||||
knex("settings").select()
|
||||
]);
|
||||
}).then(function (importedData) {
|
||||
|
||||
should.exist(importedData);
|
||||
importedData.length.should.equal(3);
|
||||
|
||||
importedData[0].length.should.equal(exportData.data.users.length);
|
||||
importedData[1].length.should.equal(exportData.data.posts.length);
|
||||
importedData[2].length.should.equal(exportData.data.settings.length);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
should.exist(exporter);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
}());
|
||||
it("resolves 001", function (done) {
|
||||
var importStub = sinon.stub(Importer001, "importData", function () {
|
||||
return when.resolve();
|
||||
}),
|
||||
fakeData = { test: true };
|
||||
|
||||
importer("001", fakeData).then(function () {
|
||||
importStub.calledWith(fakeData).should.equal(true);
|
||||
|
||||
importStub.restore();
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
|
||||
describe("001", function () {
|
||||
this.timeout(4000);
|
||||
|
||||
should.exist(Importer001);
|
||||
|
||||
it("imports data from 001", function (done) {
|
||||
var exportData;
|
||||
// TODO: Should have static test data here?
|
||||
exporter("001").then(function (exported) {
|
||||
exportData = exported;
|
||||
|
||||
// Clear the data from all tables.
|
||||
var tables = ['posts', 'users', 'roles', 'roles_users', 'permissions', 'permissions_roles', 'settings'],
|
||||
truncateOps = _.map(tables, function (name) {
|
||||
return knex(name).truncate();
|
||||
});
|
||||
|
||||
return when.all(truncateOps);
|
||||
}).then(function () {
|
||||
return importer("001", exportData);
|
||||
}).then(function (importResult) {
|
||||
// Grab the data from tables
|
||||
return when.all([
|
||||
knex("users").select(),
|
||||
knex("posts").select(),
|
||||
knex("settings").select()
|
||||
]);
|
||||
}).then(function (importedData) {
|
||||
|
||||
should.exist(importedData);
|
||||
importedData.length.should.equal(3);
|
||||
|
||||
importedData[0].length.should.equal(exportData.data.users.length);
|
||||
importedData[1].length.should.equal(exportData.data.posts.length);
|
||||
importedData[2].length.should.equal(exportData.data.settings.length);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,311 +1,304 @@
|
||||
/*globals describe, beforeEach, it*/
|
||||
var _ = require("underscore"),
|
||||
when = require('when'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
helpers = require('./helpers'),
|
||||
permissions = require('../../shared/permissions'),
|
||||
Models = require('../../shared/models'),
|
||||
UserProvider = Models.User,
|
||||
PermissionsProvider = Models.Permission,
|
||||
PostProvider = Models.Post;
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
describe('permissions', function () {
|
||||
|
||||
var _ = require("underscore"),
|
||||
when = require('when'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
errors = require('../../shared/errorHandling'),
|
||||
helpers = require('./helpers'),
|
||||
permissions = require('../../shared/permissions'),
|
||||
Models = require('../../shared/models'),
|
||||
UserProvider = Models.User,
|
||||
PermissionsProvider = Models.Permission,
|
||||
PostProvider = Models.Post;
|
||||
should.exist(permissions);
|
||||
|
||||
describe('permissions', function () {
|
||||
|
||||
should.exist(permissions);
|
||||
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function (result) {
|
||||
return when(helpers.insertDefaultUser());
|
||||
}).then(function (results) {
|
||||
done();
|
||||
});
|
||||
beforeEach(function (done) {
|
||||
helpers.resetData().then(function (result) {
|
||||
return when(helpers.insertDefaultUser());
|
||||
}).then(function (results) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// beforeEach(function (done) {
|
||||
// helpers.resetData().then(function () { done(); }, errors.throwError);
|
||||
// });
|
||||
// beforeEach(function (done) {
|
||||
// helpers.resetData().then(function () { done(); }, errors.throwError);
|
||||
// });
|
||||
|
||||
var testPerms = [
|
||||
{ act: "edit", obj: "post" },
|
||||
{ act: "edit", obj: "tag" },
|
||||
{ act: "edit", obj: "user" },
|
||||
{ act: "edit", obj: "page" },
|
||||
{ act: "add", obj: "post" },
|
||||
{ act: "add", obj: "user" },
|
||||
{ act: "add", obj: "page" },
|
||||
{ act: "remove", obj: "post" },
|
||||
{ act: "remove", obj: "user" }
|
||||
],
|
||||
currTestPermId = 1,
|
||||
// currTestUserId = 1,
|
||||
// createTestUser = function (email_address) {
|
||||
// if (!email_address) {
|
||||
// currTestUserId += 1;
|
||||
// email_address = "test" + currTestPermId + "@test.com";
|
||||
// }
|
||||
var testPerms = [
|
||||
{ act: "edit", obj: "post" },
|
||||
{ act: "edit", obj: "tag" },
|
||||
{ act: "edit", obj: "user" },
|
||||
{ act: "edit", obj: "page" },
|
||||
{ act: "add", obj: "post" },
|
||||
{ act: "add", obj: "user" },
|
||||
{ act: "add", obj: "page" },
|
||||
{ act: "remove", obj: "post" },
|
||||
{ act: "remove", obj: "user" }
|
||||
],
|
||||
currTestPermId = 1,
|
||||
// currTestUserId = 1,
|
||||
// createTestUser = function (email_address) {
|
||||
// if (!email_address) {
|
||||
// currTestUserId += 1;
|
||||
// email_address = "test" + currTestPermId + "@test.com";
|
||||
// }
|
||||
|
||||
// var newUser = {
|
||||
// id: currTestUserId,
|
||||
// email_address: email_address,
|
||||
// password: "testing123"
|
||||
// };
|
||||
// var newUser = {
|
||||
// id: currTestUserId,
|
||||
// email_address: email_address,
|
||||
// password: "testing123"
|
||||
// };
|
||||
|
||||
// return UserProvider.add(newUser);
|
||||
// },
|
||||
createPermission = function (name, act, obj) {
|
||||
if (!name) {
|
||||
currTestPermId += 1;
|
||||
name = "test" + currTestPermId;
|
||||
}
|
||||
// return UserProvider.add(newUser);
|
||||
// },
|
||||
createPermission = function (name, act, obj) {
|
||||
if (!name) {
|
||||
currTestPermId += 1;
|
||||
name = "test" + currTestPermId;
|
||||
}
|
||||
|
||||
var newPerm = {
|
||||
name: name,
|
||||
action_type: act,
|
||||
object_type: obj
|
||||
};
|
||||
|
||||
return PermissionsProvider.add(newPerm);
|
||||
},
|
||||
createTestPermissions = function () {
|
||||
var createActions = _.map(testPerms, function (testPerm) {
|
||||
return createPermission(null, testPerm.act, testPerm.obj);
|
||||
});
|
||||
|
||||
return when.all(createActions);
|
||||
var newPerm = {
|
||||
name: name,
|
||||
action_type: act,
|
||||
object_type: obj
|
||||
};
|
||||
|
||||
it('can load an actions map from existing permissions', function (done) {
|
||||
return PermissionsProvider.add(newPerm);
|
||||
},
|
||||
createTestPermissions = function () {
|
||||
var createActions = _.map(testPerms, function (testPerm) {
|
||||
return createPermission(null, testPerm.act, testPerm.obj);
|
||||
});
|
||||
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function (actionsMap) {
|
||||
should.exist(actionsMap);
|
||||
return when.all(createActions);
|
||||
};
|
||||
|
||||
actionsMap.edit.should.eql(['post', 'tag', 'user', 'page']);
|
||||
it('can load an actions map from existing permissions', function (done) {
|
||||
|
||||
actionsMap.should.equal(permissions.actionsMap);
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function (actionsMap) {
|
||||
should.exist(actionsMap);
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
actionsMap.edit.should.eql(['post', 'tag', 'user', 'page']);
|
||||
|
||||
it('can add user to role', function (done) {
|
||||
var existingUserRoles;
|
||||
|
||||
UserProvider.read({id: 1}, { withRelated: ['roles'] }).then(function (foundUser) {
|
||||
var testRole = new Models.Role({
|
||||
name: 'testrole1',
|
||||
description: 'testrole1 description'
|
||||
});
|
||||
|
||||
should.exist(foundUser);
|
||||
|
||||
should.exist(foundUser.roles());
|
||||
|
||||
existingUserRoles = foundUser.related('roles').length;
|
||||
|
||||
return testRole.save().then(function () {
|
||||
return foundUser.roles().attach(testRole);
|
||||
});
|
||||
}).then(function () {
|
||||
return UserProvider.read({id: 1}, { withRelated: ['roles'] });
|
||||
}).then(function (updatedUser) {
|
||||
should.exist(updatedUser);
|
||||
|
||||
updatedUser.related('roles').length.should.equal(existingUserRoles + 1);
|
||||
actionsMap.should.equal(permissions.actionsMap);
|
||||
|
||||
done();
|
||||
}, errors.throwError);
|
||||
});
|
||||
|
||||
it('can add user to role', function (done) {
|
||||
var existingUserRoles;
|
||||
|
||||
UserProvider.read({id: 1}, { withRelated: ['roles'] }).then(function (foundUser) {
|
||||
var testRole = new Models.Role({
|
||||
name: 'testrole1',
|
||||
description: 'testrole1 description'
|
||||
});
|
||||
|
||||
should.exist(foundUser);
|
||||
|
||||
should.exist(foundUser.roles());
|
||||
|
||||
existingUserRoles = foundUser.related('roles').length;
|
||||
|
||||
return testRole.save().then(function () {
|
||||
return foundUser.roles().attach(testRole);
|
||||
});
|
||||
}).then(function () {
|
||||
return UserProvider.read({id: 1}, { withRelated: ['roles'] });
|
||||
}).then(function (updatedUser) {
|
||||
should.exist(updatedUser);
|
||||
|
||||
updatedUser.related('roles').length.should.equal(existingUserRoles + 1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can add user permissions', function (done) {
|
||||
Models.User.read({id: 1}, { withRelated: ['permissions']}).then(function (testUser) {
|
||||
var testPermission = new Models.Permission({
|
||||
name: "test edit posts",
|
||||
action_type: 'edit',
|
||||
object_type: 'post'
|
||||
});
|
||||
|
||||
testUser.related('permissions').length.should.equal(0);
|
||||
|
||||
return testPermission.save().then(function () {
|
||||
return testUser.permissions().attach(testPermission);
|
||||
});
|
||||
}).then(function () {
|
||||
return Models.User.read({id: 1}, { withRelated: ['permissions']});
|
||||
}).then(function (updatedUser) {
|
||||
should.exist(updatedUser);
|
||||
|
||||
updatedUser.related('permissions').length.should.equal(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can add role permissions', function (done) {
|
||||
var testRole = new Models.Role({
|
||||
name: "test2",
|
||||
description: "test2 description"
|
||||
});
|
||||
|
||||
it('can add user permissions', function (done) {
|
||||
Models.User.read({id: 1}, { withRelated: ['permissions']}).then(function (testUser) {
|
||||
var testPermission = new Models.Permission({
|
||||
testRole.save()
|
||||
.then(function () {
|
||||
return testRole.load('permissions');
|
||||
})
|
||||
.then(function () {
|
||||
var rolePermission = new Models.Permission({
|
||||
name: "test edit posts",
|
||||
action_type: 'edit',
|
||||
object_type: 'post'
|
||||
});
|
||||
|
||||
testUser.related('permissions').length.should.equal(0);
|
||||
testRole.related('permissions').length.should.equal(0);
|
||||
|
||||
return testPermission.save().then(function () {
|
||||
return testUser.permissions().attach(testPermission);
|
||||
return rolePermission.save().then(function () {
|
||||
return testRole.permissions().attach(rolePermission);
|
||||
});
|
||||
}).then(function () {
|
||||
return Models.User.read({id: 1}, { withRelated: ['permissions']});
|
||||
}).then(function (updatedUser) {
|
||||
should.exist(updatedUser);
|
||||
})
|
||||
.then(function () {
|
||||
return Models.Role.read({id: testRole.id}, { withRelated: ['permissions']});
|
||||
})
|
||||
.then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedUser.related('permissions').length.should.equal(1);
|
||||
updatedRole.related('permissions').length.should.equal(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can add role permissions', function (done) {
|
||||
var testRole = new Models.Role({
|
||||
name: "test2",
|
||||
description: "test2 description"
|
||||
});
|
||||
|
||||
testRole.save()
|
||||
.then(function () {
|
||||
return testRole.load('permissions');
|
||||
})
|
||||
.then(function () {
|
||||
var rolePermission = new Models.Permission({
|
||||
name: "test edit posts",
|
||||
action_type: 'edit',
|
||||
object_type: 'post'
|
||||
});
|
||||
|
||||
testRole.related('permissions').length.should.equal(0);
|
||||
|
||||
return rolePermission.save().then(function () {
|
||||
return testRole.permissions().attach(rolePermission);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
return Models.Role.read({id: testRole.id}, { withRelated: ['permissions']});
|
||||
})
|
||||
.then(function (updatedRole) {
|
||||
should.exist(updatedRole);
|
||||
|
||||
updatedRole.related('permissions').length.should.equal(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not allow edit post without permission', function (done) {
|
||||
var fakePage = {
|
||||
id: 1
|
||||
};
|
||||
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1});
|
||||
})
|
||||
.then(function (foundUser) {
|
||||
var canThisResult = permissions.canThis(foundUser);
|
||||
|
||||
should.exist(canThisResult.edit);
|
||||
should.exist(canThisResult.edit.post);
|
||||
|
||||
return canThisResult.edit.page(fakePage);
|
||||
})
|
||||
.then(function () {
|
||||
errors.logError(new Error("Allowed edit post without permission"));
|
||||
}, function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('allows edit post with permission', function (done) {
|
||||
var fakePost = {
|
||||
id: "1"
|
||||
};
|
||||
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1});
|
||||
})
|
||||
.then(function (foundUser) {
|
||||
var newPerm = new Models.Permission({
|
||||
name: "test3 edit post",
|
||||
action_type: "edit",
|
||||
object_type: "post"
|
||||
});
|
||||
|
||||
return newPerm.save().then(function () {
|
||||
return foundUser.permissions().attach(newPerm);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1}, { withRelated: ['permissions']});
|
||||
})
|
||||
.then(function (updatedUser) {
|
||||
|
||||
// TODO: Verify updatedUser.related('permissions') has the permission?
|
||||
|
||||
var canThisResult = permissions.canThis(updatedUser);
|
||||
|
||||
should.exist(canThisResult.edit);
|
||||
should.exist(canThisResult.edit.post);
|
||||
|
||||
return canThisResult.edit.post(fakePost);
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, function () {
|
||||
errors.logError(new Error("Did not allow edit post with permission"));
|
||||
});
|
||||
});
|
||||
|
||||
it('can use permissable function on Model to allow something', function (done) {
|
||||
var testUser,
|
||||
permissableStub = sinon.stub(PostProvider, 'permissable', function () {
|
||||
return when.resolve();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// createTestUser()
|
||||
UserProvider.browse()
|
||||
.then(function (foundUser) {
|
||||
testUser = foundUser.models[0];
|
||||
|
||||
return permissions.canThis(testUser).edit.post(123);
|
||||
})
|
||||
.then(function () {
|
||||
permissableStub.restore();
|
||||
|
||||
permissableStub.calledWith(123, testUser.id, 'edit').should.equal(true);
|
||||
|
||||
done();
|
||||
})
|
||||
.otherwise(function () {
|
||||
permissableStub.restore();
|
||||
errors.logError(new Error("Did not allow testUser"));
|
||||
});
|
||||
});
|
||||
|
||||
it('can use permissable function on Model to forbid something', function (done) {
|
||||
var testUser,
|
||||
permissableStub = sinon.stub(PostProvider, 'permissable', function () {
|
||||
return when.reject();
|
||||
});
|
||||
|
||||
|
||||
// createTestUser()
|
||||
UserProvider.browse()
|
||||
.then(function (foundUser) {
|
||||
testUser = foundUser.models[0];
|
||||
|
||||
|
||||
return permissions.canThis(testUser).edit.post(123);
|
||||
})
|
||||
.then(function () {
|
||||
permissableStub.restore();
|
||||
|
||||
errors.logError(new Error("Allowed testUser to edit post"));
|
||||
})
|
||||
.otherwise(function () {
|
||||
permissableStub.restore();
|
||||
permissableStub.calledWith(123, testUser.id, 'edit').should.equal(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}());
|
||||
it('does not allow edit post without permission', function (done) {
|
||||
var fakePage = {
|
||||
id: 1
|
||||
};
|
||||
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1});
|
||||
})
|
||||
.then(function (foundUser) {
|
||||
var canThisResult = permissions.canThis(foundUser);
|
||||
|
||||
should.exist(canThisResult.edit);
|
||||
should.exist(canThisResult.edit.post);
|
||||
|
||||
return canThisResult.edit.page(fakePage);
|
||||
})
|
||||
.then(function () {
|
||||
errors.logError(new Error("Allowed edit post without permission"));
|
||||
}, function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('allows edit post with permission', function (done) {
|
||||
var fakePost = {
|
||||
id: "1"
|
||||
};
|
||||
|
||||
createTestPermissions()
|
||||
.then(permissions.init)
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1});
|
||||
})
|
||||
.then(function (foundUser) {
|
||||
var newPerm = new Models.Permission({
|
||||
name: "test3 edit post",
|
||||
action_type: "edit",
|
||||
object_type: "post"
|
||||
});
|
||||
|
||||
return newPerm.save().then(function () {
|
||||
return foundUser.permissions().attach(newPerm);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
return Models.User.read({id: 1}, { withRelated: ['permissions']});
|
||||
})
|
||||
.then(function (updatedUser) {
|
||||
|
||||
// TODO: Verify updatedUser.related('permissions') has the permission?
|
||||
|
||||
var canThisResult = permissions.canThis(updatedUser);
|
||||
|
||||
should.exist(canThisResult.edit);
|
||||
should.exist(canThisResult.edit.post);
|
||||
|
||||
return canThisResult.edit.post(fakePost);
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, function () {
|
||||
errors.logError(new Error("Did not allow edit post with permission"));
|
||||
});
|
||||
});
|
||||
|
||||
it('can use permissable function on Model to allow something', function (done) {
|
||||
var testUser,
|
||||
permissableStub = sinon.stub(PostProvider, 'permissable', function () {
|
||||
return when.resolve();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// createTestUser()
|
||||
UserProvider.browse()
|
||||
.then(function (foundUser) {
|
||||
testUser = foundUser.models[0];
|
||||
|
||||
return permissions.canThis(testUser).edit.post(123);
|
||||
})
|
||||
.then(function () {
|
||||
permissableStub.restore();
|
||||
|
||||
permissableStub.calledWith(123, testUser.id, 'edit').should.equal(true);
|
||||
|
||||
done();
|
||||
})
|
||||
.otherwise(function () {
|
||||
permissableStub.restore();
|
||||
errors.logError(new Error("Did not allow testUser"));
|
||||
});
|
||||
});
|
||||
|
||||
it('can use permissable function on Model to forbid something', function (done) {
|
||||
var testUser,
|
||||
permissableStub = sinon.stub(PostProvider, 'permissable', function () {
|
||||
return when.reject();
|
||||
});
|
||||
|
||||
|
||||
// createTestUser()
|
||||
UserProvider.browse()
|
||||
.then(function (foundUser) {
|
||||
testUser = foundUser.models[0];
|
||||
|
||||
|
||||
return permissions.canThis(testUser).edit.post(123);
|
||||
})
|
||||
.then(function () {
|
||||
permissableStub.restore();
|
||||
|
||||
errors.logError(new Error("Allowed testUser to edit post"));
|
||||
})
|
||||
.otherwise(function () {
|
||||
permissableStub.restore();
|
||||
permissableStub.calledWith(123, testUser.id, 'edit').should.equal(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user