Skip to content
This repository
Browse code

Initial commit.

  • Loading branch information...
commit 83ec9f932d0f74656e46fe26151975750bfeb638 0 parents
Jared Hanson authored
2  .gitignore
... ...
@@ -0,0 +1,2 @@
  1
+.DS_Store
  2
+node_modules
8  .npmignore
... ...
@@ -0,0 +1,8 @@
  1
+*.md
  2
+.DS_Store
  3
+.git*
  4
+Makefile
  5
+docs/
  6
+examples/
  7
+support/
  8
+test/
20  LICENSE
... ...
@@ -0,0 +1,20 @@
  1
+(The MIT License)
  2
+
  3
+Copyright (c) 2011 Jared Hanson
  4
+
  5
+Permission is hereby granted, free of charge, to any person obtaining a copy of
  6
+this software and associated documentation files (the "Software"), to deal in
  7
+the Software without restriction, including without limitation the rights to
  8
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9
+the Software, and to permit persons to whom the Software is furnished to do so,
  10
+subject to the following conditions:
  11
+
  12
+The above copyright notice and this permission notice shall be included in all
  13
+copies or substantial portions of the Software.
  14
+
  15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  Makefile
... ...
@@ -0,0 +1,19 @@
  1
+NODE = node
  2
+TEST = vows
  3
+TESTS ?= test/*-test.js
  4
+
  5
+test:
  6
+	@NODE_ENV=test NODE_PATH=lib $(TEST) $(TEST_FLAGS) $(TESTS)
  7
+
  8
+docs: docs/api.html
  9
+
  10
+docs/api.html: lib/passport-http-bearer/*.js
  11
+	dox \
  12
+		--title Passport-HTTP-Bearer \
  13
+		--desc "HTTP Bearer authentication strategy for Passport" \
  14
+		$(shell find lib/passport-http-bearer/* -type f) > $@
  15
+
  16
+docclean:
  17
+	rm -f docs/*.{1,html}
  18
+
  19
+.PHONY: test docs docclean
30  README.md
Source Rendered
... ...
@@ -0,0 +1,30 @@
  1
+# Passport-HTTP-Bearer
  2
+
  3
+HTTP Bearer authentication strategy for [Passport](https://github.com/jaredhanson/passport).
  4
+
  5
+## Credits
  6
+
  7
+  - [Jared Hanson](http://github.com/jaredhanson)
  8
+
  9
+## License
  10
+
  11
+(The MIT License)
  12
+
  13
+Copyright (c) 2011 Jared Hanson
  14
+
  15
+Permission is hereby granted, free of charge, to any person obtaining a copy of
  16
+this software and associated documentation files (the "Software"), to deal in
  17
+the Software without restriction, including without limitation the rights to
  18
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  19
+the Software, and to permit persons to whom the Software is furnished to do so,
  20
+subject to the following conditions:
  21
+
  22
+The above copyright notice and this permission notice shall be included in all
  23
+copies or substantial portions of the Software.
  24
+
  25
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  26
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  27
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  28
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  29
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  30
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15  lib/passport-http-bearer/index.js
... ...
@@ -0,0 +1,15 @@
  1
+/**
  2
+ * Module dependencies.
  3
+ */
  4
+var Strategy = require('./strategy');
  5
+
  6
+
  7
+/**
  8
+ * Framework version.
  9
+ */
  10
+exports.version = '0.1.0';
  11
+
  12
+/**
  13
+ * Expose constructors.
  14
+ */
  15
+exports.Strategy = Strategy;
76  lib/passport-http-bearer/strategy.js
... ...
@@ -0,0 +1,76 @@
  1
+/**
  2
+ * Module dependencies.
  3
+ */
  4
+var passport = require('passport')
  5
+  , util = require('util');
  6
+
  7
+function Strategy(options, validate) {
  8
+  if (typeof options == 'function') {
  9
+    validate = options;
  10
+    options = {};
  11
+  }
  12
+  if (!validate) throw new Error('HTTP Bearer authentication strategy requires a validate function');
  13
+  
  14
+  passport.Strategy.call(this);
  15
+  this.name = 'bearer';
  16
+  this._validate = validate;
  17
+  this._realm = options.realm || 'Users';
  18
+}
  19
+
  20
+/**
  21
+ * Inherit from `passport.Strategy`.
  22
+ */
  23
+util.inherits(Strategy, passport.Strategy);
  24
+
  25
+/**
  26
+ * Authenticate request based on the contents of a HTTP Bearer authorization
  27
+ * header, body parameter, or query parameter.
  28
+ *
  29
+ * @param {Object} req
  30
+ * @api protected
  31
+ */
  32
+Strategy.prototype.authenticate = function(req) {
  33
+  var token = undefined;
  34
+  
  35
+  if (req.headers && req.headers['authorization']) {
  36
+    var parts = req.headers['authorization'].split(' ');
  37
+    if (parts.length == 2) {
  38
+      var scheme = parts[0]
  39
+        , credentials = parts[1];
  40
+        
  41
+      if (/Bearer/i.test(scheme)) {
  42
+        token = credentials;
  43
+      }
  44
+    }
  45
+  }
  46
+  else if (req.body && req.body['access_token']) {
  47
+    token = req.body['access_token'];
  48
+  }
  49
+  else if (req.query && req.query['access_token']) {
  50
+    token = req.query['access_token'];
  51
+  }
  52
+  
  53
+  if (!token) { return this.fail(this._challenge()); }
  54
+  
  55
+  var self = this;
  56
+  this._validate(token, function(err, user) {
  57
+    if (err) { return self.error(err); }
  58
+    if (!user) { return self.fail(self._challenge()); }
  59
+    self.success(user);
  60
+  });
  61
+}
  62
+
  63
+/**
  64
+ * Authentication challenge.
  65
+ *
  66
+ * @api private
  67
+ */
  68
+Strategy.prototype._challenge = function() {
  69
+  return 'Bearer realm="' + this._realm + '"';
  70
+}
  71
+
  72
+
  73
+/**
  74
+ * Expose `Strategy`.
  75
+ */ 
  76
+module.exports = Strategy;
16  package.json
... ...
@@ -0,0 +1,16 @@
  1
+{
  2
+  "name": "passport-http-bearer",
  3
+  "version": "0.1.0",
  4
+  "description": "HTTP Bearer authentication strategy for Passport.",
  5
+  "author": "Jared Hanson <jaredhanson@gmail.com> (http://www.jaredhanson.net/)",
  6
+  "repository": {
  7
+    "type": "git",
  8
+    "url": "http://github.com/jaredhanson/passport-http-bearer.git"
  9
+  },
  10
+  "main": "./lib/passport-http-bearer",
  11
+  "dependencies": {
  12
+    "passport": ">= 0.1.2"
  13
+  },
  14
+  "engines": { "node": ">= 0.4.0" },
  15
+  "keywords": ["passport", "http", "bearer", "authn", "authentication"]
  16
+}
15  test/index-test.js
... ...
@@ -0,0 +1,15 @@
  1
+var vows = require('vows');
  2
+var assert = require('assert');
  3
+var util = require('util');
  4
+var bearer = require('passport-http-bearer');
  5
+
  6
+
  7
+vows.describe('passport-http-bearer').addBatch({
  8
+  
  9
+  'module': {
  10
+    'should report a version': function (x) {
  11
+      assert.isString(bearer.version);
  12
+    },
  13
+  },
  14
+  
  15
+}).export(module);
195  test/strategy-test.js
... ...
@@ -0,0 +1,195 @@
  1
+var vows = require('vows');
  2
+var assert = require('assert');
  3
+var util = require('util');
  4
+var BearerStrategy = require('passport-http-bearer/strategy');
  5
+
  6
+
  7
+vows.describe('BearerStrategy').addBatch({
  8
+  
  9
+  'strategy': {
  10
+    topic: function() {
  11
+      return new BearerStrategy(function() {});
  12
+    },
  13
+    
  14
+    'should be named bearer': function (strategy) {
  15
+      assert.equal(strategy.name, 'bearer');
  16
+    },
  17
+  },
  18
+  
  19
+  'strategy handling a valid request with authorization header': {
  20
+    topic: function() {
  21
+      var strategy = new BearerStrategy(function(token, done) {
  22
+        done(null, { token: token });
  23
+      });
  24
+      return strategy;
  25
+    },
  26
+    
  27
+    'after augmenting with actions': {
  28
+      topic: function(strategy) {
  29
+        var self = this;
  30
+        var req = {};
  31
+        strategy.success = function(user) {
  32
+          self.callback(null, user);
  33
+        }
  34
+        strategy.fail = function() {
  35
+          self.callback(new Error('should not be called'));
  36
+        }
  37
+        
  38
+        req.headers = {};
  39
+        req.headers.authorization = 'Bearer vF9dft4qmT';
  40
+        process.nextTick(function () {
  41
+          strategy.authenticate(req);
  42
+        });
  43
+      },
  44
+      
  45
+      'should not generate an error' : function(err, user) {
  46
+        assert.isNull(err);
  47
+      },
  48
+      'should authenticate' : function(err, user) {
  49
+        assert.equal(user.token, 'vF9dft4qmT');
  50
+      },
  51
+    },
  52
+  },
  53
+  
  54
+  'strategy handling a valid request with form-encoded body': {
  55
+    topic: function() {
  56
+      var strategy = new BearerStrategy(function(token, done) {
  57
+        done(null, { token: token });
  58
+      });
  59
+      return strategy;
  60
+    },
  61
+    
  62
+    'after augmenting with actions': {
  63
+      topic: function(strategy) {
  64
+        var self = this;
  65
+        var req = {};
  66
+        strategy.success = function(user) {
  67
+          self.callback(null, user);
  68
+        }
  69
+        strategy.fail = function() {
  70
+          self.callback(new Error('should not be called'));
  71
+        }
  72
+        
  73
+        req.body = {};
  74
+        req.body.access_token = 'vF9dft4qmT';
  75
+        process.nextTick(function () {
  76
+          strategy.authenticate(req);
  77
+        });
  78
+      },
  79
+      
  80
+      'should not generate an error' : function(err, user) {
  81
+        assert.isNull(err);
  82
+      },
  83
+      'should authenticate' : function(err, user) {
  84
+        assert.equal(user.token, 'vF9dft4qmT');
  85
+      },
  86
+    },
  87
+  },
  88
+  
  89
+  'strategy handling a valid request with URI query': {
  90
+    topic: function() {
  91
+      var strategy = new BearerStrategy(function(token, done) {
  92
+        done(null, { token: token });
  93
+      });
  94
+      return strategy;
  95
+    },
  96
+    
  97
+    'after augmenting with actions': {
  98
+      topic: function(strategy) {
  99
+        var self = this;
  100
+        var req = {};
  101
+        strategy.success = function(user) {
  102
+          self.callback(null, user);
  103
+        }
  104
+        strategy.fail = function() {
  105
+          self.callback(new Error('should not be called'));
  106
+        }
  107
+        
  108
+        req.query = {};
  109
+        req.query.access_token = 'vF9dft4qmT';
  110
+        process.nextTick(function () {
  111
+          strategy.authenticate(req);
  112
+        });
  113
+      },
  114
+      
  115
+      'should not generate an error' : function(err, user) {
  116
+        assert.isNull(err);
  117
+      },
  118
+      'should authenticate' : function(err, user) {
  119
+        assert.equal(user.token, 'vF9dft4qmT');
  120
+      },
  121
+    },
  122
+  },
  123
+  
  124
+  'strategy handling a request without authorization credentials': {
  125
+    topic: function() {
  126
+      var strategy = new BearerStrategy(function(token, done) {
  127
+        done(null, { token: token });
  128
+      });
  129
+      return strategy;
  130
+    },
  131
+    
  132
+    'after augmenting with actions': {
  133
+      topic: function(strategy) {
  134
+        var self = this;
  135
+        var req = {};
  136
+        strategy.success = function(user) {
  137
+          self.callback(new Error('should not be called'));
  138
+        }
  139
+        strategy.fail = function(challenge) {
  140
+          self.callback(null, challenge);
  141
+        }
  142
+        
  143
+        process.nextTick(function () {
  144
+          strategy.authenticate(req);
  145
+        });
  146
+      },
  147
+      
  148
+      'should fail authentication with challenge' : function(err, challenge) {
  149
+        // fail action was called, resulting in test callback
  150
+        assert.isNull(err);
  151
+        assert.equal(challenge, 'Bearer realm="Users"');
  152
+      },
  153
+    },
  154
+  },
  155
+  
  156
+  'strategy handling a request without authorization credentials and realm option set': {
  157
+    topic: function() {
  158
+      var strategy = new BearerStrategy({ realm: 'Administrators' },
  159
+        function(token, done) {
  160
+          done(null, { token: token });
  161
+        });
  162
+      return strategy;
  163
+    },
  164
+    
  165
+    'after augmenting with actions': {
  166
+      topic: function(strategy) {
  167
+        var self = this;
  168
+        var req = {};
  169
+        strategy.success = function(user) {
  170
+          self.callback(new Error('should not be called'));
  171
+        }
  172
+        strategy.fail = function(challenge) {
  173
+          self.callback(null, challenge);
  174
+        }
  175
+        
  176
+        process.nextTick(function () {
  177
+          strategy.authenticate(req);
  178
+        });
  179
+      },
  180
+      
  181
+      'should fail authentication with challenge' : function(err, challenge) {
  182
+        // fail action was called, resulting in test callback
  183
+        assert.isNull(err);
  184
+        assert.equal(challenge, 'Bearer realm="Administrators"');
  185
+      },
  186
+    },
  187
+  },
  188
+  
  189
+  'strategy constructed without a validate callback': {
  190
+    'should throw an error': function (strategy) {
  191
+      assert.throws(function() { new BearerStrategy() });
  192
+    },
  193
+  },
  194
+  
  195
+}).export(module);

0 notes on commit 83ec9f9

Please sign in to comment.
Something went wrong with that request. Please try again.