Skip to content

Commit

Permalink
Initial rate limiting middleware hook, reverted a change to the Gru…
Browse files Browse the repository at this point in the history
…nt file, such that 'test' runs jshint & mocha tests, updated turtle.io dep, fixing mistakes missed during erroneous 'test' phase
  • Loading branch information
avoidwork committed Aug 5, 2014
1 parent c042c49 commit 8d6815e
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 19 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## 0.3.0
- Added rate limiting
- Reverted a change to the Grunt file, such that 'test' runs jshint & mocha tests

## 0.2.0
- Created `Tenso.redirect(req, res, uri)`, & `Tenso.error(req, res, status, arg)`
- Added `local` authentication, which is controlled by config
Expand Down
5 changes: 3 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = function (grunt) {
"src/factory.js",
"src/hypermedia.js",
"src/prepare.js",
"src/rate.js",
"src/response.js",
"src/outro.js"
],
Expand Down Expand Up @@ -103,7 +104,7 @@ module.exports = function (grunt) {

// aliases
grunt.registerTask("build", ["concat", "sed", "sass"]);
grunt.registerTask("test", ["mochaTest"]);
grunt.registerTask("default", ["build", "jshint"]);
grunt.registerTask("test", ["jshint", "mochaTest"]);
grunt.registerTask("default", ["build", "test"]);
grunt.registerTask("package", ["default", "test", "jsdoc"]);
};
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ This is a sample configuration for Tensō, without authentication or SSL. This w
```

## Authentication
Planned authentication options are `Basic Auth`, `OAuth2 Bearer Token`, `Twitter`, & `Facebook`.
Planned authentication options include `OAuth2 (generic)`, `Twitter`, & `Facebook`.

### Basic Auth
`Basic Auth` will be applied to the entire API if enabled.
Expand Down Expand Up @@ -167,6 +167,9 @@ The `protect` Array is the endpoints that will be protected by `local` authentic
}
```

## Rate Limiting
Rate limiting is controlled by configuration, and is disabled by default.

## Logging
Standard log levels are supported, and are emitted (by configuration) to `stdout` & `stderr`, & `syslog`.

Expand Down
4 changes: 4 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,9 @@
"ssl": {
"key": null,
"cert": null
},
"rate": {
"enabled": false,
"limit": 1000
}
}
38 changes: 30 additions & 8 deletions lib/tenso.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* @license BSD-3 <https://raw.github.com/avoidwork/tenso/master/LICENSE>
* @link http://avoidwork.github.io/tenso
* @module tenso
* @version 0.2.0
* @version 0.3.0
*/
( function () {
"use strict";

var TurtleIO = require( "turtle.io" ),
SERVER = "tenso/0.2.0",
SERVER = "tenso/0.3.0",
CONFIG = require( __dirname + "/../config.json" ),
keigai = require( "keigai" ),
util = keigai.util,
Expand All @@ -21,6 +21,7 @@ var TurtleIO = require( "turtle.io" ),
clone = util.clone,
iterate = util.iterate,
merge = util.merge,
parse = util.parse,
uuid = util.uuid,
session = require( "express-session" ),
passport = require( "passport" ),
Expand All @@ -35,7 +36,7 @@ function Tenso () {
this.hostname = "";
this.messages = {};
this.server = new TurtleIO();
this.version = "0.2.0";
this.version = "0.3.0";
}

/**
Expand Down Expand Up @@ -200,11 +201,10 @@ function auth ( obj, config ) {
} )();
}
else if ( config.auth.local.enabled ) {
config.routes.get[config.auth.local.login] = "POST to authenticate"
config.routes.get[config.auth.local.login] = "POST credentials to authenticate";
config.routes.post = config.routes.post || {};
config.routes.post[config.auth.local.login] = function ( req, res ) {
var args = array.cast( arguments ),
session;
config.routes.post[config.auth.local.login] = function ( req ) {
var args = array.cast( arguments );

if ( req.session === undefined ) {
req.sessionStore.get( req.sessionId, function ( session ) {
Expand All @@ -225,7 +225,8 @@ function auth ( obj, config ) {
else {
config.auth.local.auth.apply( obj, args );
}
}
};

obj.server.use( config.auth.local.middleware );
}
}
Expand All @@ -242,6 +243,14 @@ function auth ( obj, config ) {
* @return {Object} Tenso instance
*/
function bootstrap ( obj, config ) {
// Early middleware hook for rate limiting
if ( config.rate.enabled ) {
obj.server.use( function ( req, res, next ) {
rate.call( obj, req, res, next );
} );
}

// Bootstrapping configuration
config = auth( obj, config );
config.headers = config.headers || {};
config.headers.server = SERVER;
Expand Down Expand Up @@ -416,6 +425,19 @@ function prepare ( data, error, status ) {
};
}

/**
* Rate limiting middleware
*
* @method rate
* @param {Object} req Client request
* @param {Object} res Client response
* @param {Function} next Next middleware
* @return {Undefined} undefined
*/
function rate ( req, res, next ) {
next();
}

/**
* Creates a response
*
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "tenso",
"description": "Tensō is a REST API facade for node.js, designed to simplify the implementation of APIs.",
"version": "0.2.0",
"version": "0.3.0",
"homepage": "http://avoidwork.github.io/tenso",
"author": {
"name": "Jason Mulligan",
Expand Down Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"keigai": "0.6.1",
"turtle.io": "2.2.2",
"turtle.io": "2.2.3",
"express-session": "^1.7.2",
"passport": "0.2.0",
"passport-http-bearer": "1.0.1"
Expand Down
10 changes: 5 additions & 5 deletions src/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,10 @@ function auth ( obj, config ) {
} )();
}
else if ( config.auth.local.enabled ) {
config.routes.get[config.auth.local.login] = "POST to authenticate"
config.routes.get[config.auth.local.login] = "POST credentials to authenticate";
config.routes.post = config.routes.post || {};
config.routes.post[config.auth.local.login] = function ( req, res ) {
var args = array.cast( arguments ),
session;
config.routes.post[config.auth.local.login] = function ( req ) {
var args = array.cast( arguments );

if ( req.session === undefined ) {
req.sessionStore.get( req.sessionId, function ( session ) {
Expand All @@ -130,7 +129,8 @@ function auth ( obj, config ) {
else {
config.auth.local.auth.apply( obj, args );
}
}
};

obj.server.use( config.auth.local.middleware );
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
* @return {Object} Tenso instance
*/
function bootstrap ( obj, config ) {
// Early middleware hook for rate limiting
if ( config.rate.enabled ) {
obj.server.use( function ( req, res, next ) {
rate.call( obj, req, res, next );
} );
}

// Bootstrapping configuration
config = auth( obj, config );
config.headers = config.headers || {};
config.headers.server = SERVER;
Expand Down
1 change: 1 addition & 0 deletions src/intro.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var TurtleIO = require( "turtle.io" ),
clone = util.clone,
iterate = util.iterate,
merge = util.merge,
parse = util.parse,
uuid = util.uuid,
session = require( "express-session" ),
passport = require( "passport" ),
Expand Down
12 changes: 12 additions & 0 deletions src/rate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Rate limiting middleware
*
* @method rate
* @param {Object} req Client request
* @param {Object} res Client response
* @param {Function} next Next middleware
* @return {Undefined} undefined
*/
function rate ( req, res, next ) {
next();
}
2 changes: 1 addition & 1 deletion test/tenso_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ describe("Local", function () {
.get("/login")
.expectStatus(200)
.expectValue("data.link", [])
.expectValue("data.result", "POST to authenticate")
.expectValue("data.result", "POST credentials to authenticate")
.expectValue("error", null)
.expectValue("status", 200)
.end(function(err) {
Expand Down

0 comments on commit 8d6815e

Please sign in to comment.