Permalink
Browse files

v0.1.0: create/edit blog posts

The version includes:

* API path: PUT /post/:postid
* validating write access and schema to/of a blog post
* test data: /post/test-post

The post doc schema:

```json
{
  "_id": "", // e.g. hello-world
  "_rev": "",
  "_attachements": {
    "static.html": {} //published post
  },
  "title": "Hello World!", //content src
  "teaser": "", //content src
  "markdown": "", //content src
  "created_at": "",
  "edited_at": "",
  "publish_at": "",
  "type": "blogpost"
}
```

Write access is given to admins and the userrole "writer".
  • Loading branch information...
llabball committed Jan 26, 2014
1 parent fd6fcf7 commit f9a52bb83de9190b853c9457b59173318983bc29
Showing with 108 additions and 1 deletion.
  1. +8 −0 _docs/test-post.json
  2. +1 −1 couchapp.json
  3. +7 −0 rewrites.json
  4. +34 −0 validate_doc_update.js
  5. +58 −0 vendor/validateDocUpdateUtils.js
@@ -0,0 +1,8 @@
{
"edited_at": "2014-01-08T22:35:59.249Z",
"markdown": "## Heading\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n## Heading\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n## Heading\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"title": "Hello World\n\nswrer!",
"created_at": "2014-01-08T22:35:59.249Z",
"teaser": "This is a test blog post to test the installation.",
"type": "blogpost"
}
@@ -1,5 +1,5 @@
{
"name": "StaticCouchBlog",
"description": "A web blog system to create, edit, preview and publish posts. The application is performance orienteted for the reads - it serves them finally as static files.",
"version": "0.0.1"
"version": "0.1.0"
}
@@ -0,0 +1,7 @@
[
{
"to": "../../:pid",
"from": "post/:pid",
"method": "PUT"
}
]
@@ -0,0 +1,34 @@
function (newDoc, oldDoc, userCtx, secObj) {
var v = require('vendor/validateDocUpdateUtils').init(newDoc, oldDoc, userCtx, secObj)
if (!userCtx.name)
v.unauthorized('please sign in')
if (!v.isRole('writer') && !v.isAdmin())
v.unauthorized('permission denied')
if (newDoc._deleted === true)
return
var content_properties = ['markdown', 'teaser', 'title']
for (var i = 0; i < content_properties.length; i++) {
var prop = content_properties[i]
v.require(prop)
v.assert(newDoc[prop].length > 0, 'doc.markdown is empty')
}
v.require('type')
v.matches('type', /^blogpost$/, 'doc.type must be blogpost')
v.require('created_at')
v.dateFormat('created_at')
v.unchanged('created_at')
v.require('edited_at')
v.dateFormat('edited_at')
v.dateAfter('created_at', 'edited_at')
if (!newDoc.published_at) return
v.dateFormat(newDoc.published_at)
v.dateAfter('edited_at', 'published_at')
}
@@ -0,0 +1,58 @@
exports.init = function(newDoc, oldDoc, userCtx, secObj) {
var v = {};
v.forbidden = function(message) {
throw({forbidden : message});
};
v.unauthorized = function(message) {
throw({unauthorized : message});
};
v.assert = function(should, message) {
if (!should) v.forbidden(message);
}
v.isAdmin = function() {
return userCtx.roles.indexOf('_admin') != -1
};
v.isRole = function(role) {
return userCtx.roles.indexOf(role) != -1
};
v.require = function() {
for (var i=0; i < arguments.length; i++) {
var field = arguments[i];
message = "The '"+field+"' field is required.";
if (typeof newDoc[field] == "undefined") v.forbidden(message);
};
};
v.unchanged = function(field) {
if (oldDoc && oldDoc[field] != newDoc[field])
v.forbidden("You may not change the '"+field+"' field.");
};
v.matches = function(field, regex, message) {
if (!newDoc[field].match(regex)) {
message = message || "Format of '"+field+"' field is invalid.";
v.forbidden(message);
}
};
// this ensures that the date will be UTC, parseable, and collate correctly
v.dateFormat = function(field) {
message = "Sorry, '"+field+"' is not a valid date format. Try: 2010-02-24T17:00:03.432Z";
v.matches(field, /\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d*)?Z/, message);
}
v.dateAfter = function(date, dateEqualOrAfter, message) {
if (new Date(newDoc[date]).valueOf() <= new Date(dateEqualOrAfter).valueOf()) {
message = message || dateEqualOrAfter+"' must be equal or after "+date;
v.forbidden(message);
}
}
return v;
};

0 comments on commit f9a52bb

Please sign in to comment.