/**
 * Module dependencies.
 */
var passport = require('passport')
  , util = require('util')
  , AuthenticationError = require('./errors/authenticationerror');

function Strategy(options, validate) {
  if (typeof options == 'function') {
    validate = options;
    options = {};
  }
  if (!validate) throw new Error('HTTP Bearer authentication strategy requires a validate function');
  
  passport.Strategy.call(this);
  this.name = 'bearer';
  this._validate = validate;
  this._realm = options.realm || 'Users';
  if (options.scope) {
    this._scope = (Array.isArray(options.scope)) ? options.scope : [ options.scope ];
  }
}

/**
 * Inherit from `passport.Strategy`.
 */
util.inherits(Strategy, passport.Strategy);

/**
 * Authenticate request based on the contents of a HTTP Bearer authorization
 * header, body parameter, or query parameter.
 *
 * @param {Object} req
 * @api protected
 */
Strategy.prototype.authenticate = function(req) {
  var token = undefined;
  
  if (req.headers && req.headers['authorization']) {
    var parts = req.headers['authorization'].split(' ');
    if (parts.length == 2) {
      var scheme = parts[0]
        , credentials = parts[1];
        
      if (/Bearer/i.test(scheme)) {
        token = credentials;
      }
    } else {
      return this.fail(400);
    }
  }
  else if (req.body && req.body['access_token']) {
    token = req.body['access_token'];
  }
  else if (req.query && req.query['access_token']) {
    token = req.query['access_token'];
  }
  
  if (!token) { return this.fail(this._challenge()); }
  
  var self = this;
  this._validate(token, function(err, user) {
    if (err instanceof AuthenticationError) {
      var status;
      if (err.code === 'invalid_request') { status = 400; }
      else if (err.code === 'insufficient_scope') { status = 403; }
      
      return self.fail(self._challenge(err.code, err.message, err.uri), status);
    }
    if (err) { return self.error(err); }
    if (!user) { return self.fail(self._challenge()); }
    self.success(user);
  });
}

/**
 * Authentication challenge.
 *
 * @api private
 */
Strategy.prototype._challenge = function(code, desc, uri) {
  var challenge = 'Bearer realm="' + this._realm + '"';
  if (this._scope) {
    challenge += ', scope="' + this._scope.join(' ') + '"';
  }
  if (code) {
    challenge += ', error="' + code + '"';
  }
  if (desc && desc.length) {
    challenge += ', error_description="' + desc + '"';
  }
  if (uri && uri.length) {
    challenge += ', error_uri="' + uri + '"';
  }
  
  return challenge;
}


/**
 * Expose `Strategy`.
 */ 
module.exports = Strategy;

@@ -155,16 +155,1633 @@
 ror');%0A%0A
+%0A/**%0A * %60Strategy%60 constructor.%0A *%0A * The HTTP Bearer authentication strategy authenticates requests based on%0A * a bearer token contained in the %60Authorization%60 header field, %60access_token%60%0A * body parameter, or %60access_token%60 query parameter.%0A *%0A * Applications must supply a %60validate%60 callback which accepts a %60token%60, and%0A * then calls the %60done%60 callback supplying a %60user%60, which should be set to%0A * %60false%60 if the token is not valid.  If a token-related authentication error%0A * occurs, %60err%60 should be set to an %60AuthenticationError%60 containing relevant%0A * information to be returned to the client in the authentication challenge.  If%0A * an exception occured, %60err%60 should be set to a generic %60Error%60.%0A *%0A * Options:%0A *   - %60realm%60  authentication realm, defaults to %22Users%22%0A *   - %60scope%60  list of scope values indicating the required scope of the access token for accessing the requested resource%0A *%0A * Examples:%0A *%0A *     passport.use(new BearerStrategy(%0A *       function(token, done) %7B%0A *         User.findByToken(%7B token: token %7D, function (err, user) %7B%0A *           if (err) %7B return done(err); %7D%0A *           if (!user) %7B return done(null, false); %7D%0A *           if (!sufficientScope(user, token)) %7B return done(new bearer.AuthenticationError('', 'insufficient_scope')); %7D%0A *           return done(null, user);%0A *         %7D);%0A *       %7D%0A *     ));%0A *%0A * For further details on HTTP Bearer authentication, refer to %5BThe OAuth 2.0 Authorization Protocol: Bearer Tokens%5D(http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer)%0A *%0A * @param %7BObject%7D options%0A * @param %7BFunction%7D validate%0A * @api public%0A */%0A
 function

Document Strategy.