<commit_before>/**
 * Module dependencies.
 */
var util = require('util'), 
	OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
	InternalOAuthError = require('passport-oauth').InternalOAuthError,
  crypto= require('crypto'),
  querystring= require('querystring'),
  https= require('https'),
  http= require('http'),
  url= require('url')
  request = require('request');


/**
 * `Strategy` constructor.
 *
 * The Yahoo authentication strategy authenticates requests by delegating to
 * Yahoo using the OAuth protocol.
 *
 * Applications must supply a `verify` callback which accepts a `token`,
 * `tokenSecret` and service-specific `profile`, and then calls the `done`
 * callback supplying a `user`, which should be set to `false` if the
 * credentials are not valid.  If an exception occured, `err` should be set.
 *
 * Options:
 *   - `consumerKey`     identifies client to Yahoo
 *   - `consumerSecret`  secret used to establish ownership of the consumer key
 *   - `callbackURL`     URL to which Yahoo will redirect the user after obtaining authorization
 *
 * Examples:
 *
 *     passport.use(new YahooStrategy({
 *         consumerKey: '123-456-789',
 *         consumerSecret: 'shhh-its-a-secret'
 *         callbackURL: 'https://www.example.net/auth/yahoo/callback'
 *       },
 *       function(token, tokenSecret, profile, done) {
 *         User.findOrCreate(..., function (err, user) {
 *           done(err, user);
 *         });
 *       }
 *     ));
 *
 * @param {Object} options
 * @param {Function} verify
 * @api public
 */
function Strategy(options, verify) {
  //https://api.login.yahoo.com/oauth2/request_auth
  options = options || {};
  
  options.authorizationURL = options.authorizationURL || 'https://api.login.yahoo.com/oauth2/request_auth';
  options.tokenURL = options.tokenURL || 'https://api.login.yahoo.com/oauth2/get_token';
  options.profileURL = options.profileURL || 'https://social.yahooapis.com/v1/user/:xoauthYahooGuid/profile?format=json';

  OAuth2Strategy.call(this, options, verify);

  this._options = options;
  this.name = 'yahoo';
}

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


/**
 * Override authenticate: 
 * inspired from post: http://yahoodevelopers.tumblr.com/post/105969451213/implementing-yahoo-oauth2-authentication
 *
 */
OAuth2Strategy.prototype.authenticate = function(req, options) {
  options = options || {};
  var self = this;
  
  if (req.query && req.query.error) {
    // TODO: Error information pertaining to OAuth 2.0 flows is encoded in the
    //       query parameters, and should be propagated to the application.
    return this.fail();
  }
  
  var callbackURL = options.callbackURL || this._callbackURL;
  if (callbackURL) {
    var parsed = url.parse(callbackURL);
    if (!parsed.protocol) {
      // The callback URL is relative, resolve a fully qualified URL from the
      // URL of the originating request.
      callbackURL = url.resolve(utils.originalURL(req), callbackURL);
    }
  }
  
  if (req.query && req.query.code) {
    var code = req.query.code;
    console.log('the yahoo code: ', req.query, code, self._options, self._options._clientSecret, self._options._clientId);

    var params= params || {};
    params['client_id'] = self._options._clientId;
    params['client_secret'] = self._options._clientSecret;
    var codeParam = (params.grant_type === 'refresh_token') ? 'refresh_token' : 'authorization_code';
    params[codeParam]= code;

    var post_data= querystring.stringify( params );
    var post_headers= {
      'Content-Type': 'application/json'
    };

    var _authorization = [
      'Basic: ',
      new Buffer(self._options.clientID + ':' + self._options.clientSecret).toString('base64')
    ].join('');
    
    var request_options = {
      url: self._options.tokenURL,
      headers: {
        Authorization: _authorization
      },
      rejectUnauthorized: false,
      json: true,
      form: {
        code: code,
        redirect_uri: self._options.callbackURL,
        grant_type: codeParam
      }
    };

    request.post(request_options, function(err, response, body) {
      if (err) { return self.error(new InternalOAuthError('failed to obtain access token', err)); }

      var results = body;
      var guid = body.xoauth_yahoo_guid;
      var accessToken = body.access_token;
      var refreshToken = body.refresh_token;

      self._loadUserProfile({
        accessToken: accessToken,
        xoauth_yahoo_guid: guid
      }, function(err, profile) {
        if(err) return self.error(err);

        function verified(error, user, info) {
          if(error) return self.error(error);
          if(!user) return self.fail(info);

          return self.success(user, info);
        }

        if(self._passReqToCallback) {
          self._verify(req.accessToken, refreshToken, profile, verified);
        }else {
          self._verify(accessToken, refreshToken, profile, verified);
        }
      });
    });
  } else {
    // NOTE: The module oauth (0.9.5), which is a dependency, automatically adds
    //       a 'type=web_server' parameter to the query portion of the URL.
    //       This appears to be an artifact from an earlier draft of OAuth 2.0
    //       (draft 22, as of the time of this writing).  This parameter is not
    //       necessary, but its presence does not appear to cause any issues.
    
    var params = this.authorizationParams(options);
    params['response_type'] = 'code';
    params['redirect_uri'] = callbackURL;

    console.log('here: ', params);

    var scope = options.scope || this._scope;
    if (scope) {
      if (Array.isArray(scope)) { scope = scope.join(this._scopeSeparator); }
      params.scope = scope;
    }<commit_msg>updated callback _verify to include results raw response<commit_after>/**
 * Module dependencies.
 */
var util = require('util'), 
	OAuth2Strategy = require('passport-oauth').OAuth2Strategy,
	InternalOAuthError = require('passport-oauth').InternalOAuthError,
  crypto= require('crypto'),
  querystring= require('querystring'),
  https= require('https'),
  http= require('http'),
  url= require('url')
  request = require('request');


/**
 * `Strategy` constructor.
 *
 * The Yahoo authentication strategy authenticates requests by delegating to
 * Yahoo using the OAuth protocol.
 *
 * Applications must supply a `verify` callback which accepts a `token`,
 * `tokenSecret` and service-specific `profile`, and then calls the `done`
 * callback supplying a `user`, which should be set to `false` if the
 * credentials are not valid.  If an exception occured, `err` should be set.
 *
 * Options:
 *   - `consumerKey`     identifies client to Yahoo
 *   - `consumerSecret`  secret used to establish ownership of the consumer key
 *   - `callbackURL`     URL to which Yahoo will redirect the user after obtaining authorization
 *
 * Examples:
 *
 *     passport.use(new YahooStrategy({
 *         consumerKey: '123-456-789',
 *         consumerSecret: 'shhh-its-a-secret'
 *         callbackURL: 'https://www.example.net/auth/yahoo/callback'
 *       },
 *       function(token, tokenSecret, profile, done) {
 *         User.findOrCreate(..., function (err, user) {
 *           done(err, user);
 *         });
 *       }
 *     ));
 *
 * @param {Object} options
 * @param {Function} verify
 * @api public
 */
function Strategy(options, verify) {
  //https://api.login.yahoo.com/oauth2/request_auth
  options = options || {};
  
  options.authorizationURL = options.authorizationURL || 'https://api.login.yahoo.com/oauth2/request_auth';
  options.tokenURL = options.tokenURL || 'https://api.login.yahoo.com/oauth2/get_token';
  options.profileURL = options.profileURL || 'https://social.yahooapis.com/v1/user/:xoauthYahooGuid/profile?format=json';

  OAuth2Strategy.call(this, options, verify);

  this._options = options;
  this.name = 'yahoo';
}

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


/**
 * Override authenticate: 
 * inspired from post: http://yahoodevelopers.tumblr.com/post/105969451213/implementing-yahoo-oauth2-authentication
 *
 */
OAuth2Strategy.prototype.authenticate = function(req, options) {
  options = options || {};
  var self = this;
  
  if (req.query && req.query.error) {
    // TODO: Error information pertaining to OAuth 2.0 flows is encoded in the
    //       query parameters, and should be propagated to the application.
    return this.fail();
  }
  
  var callbackURL = options.callbackURL || this._callbackURL;
  if (callbackURL) {
    var parsed = url.parse(callbackURL);
    if (!parsed.protocol) {
      // The callback URL is relative, resolve a fully qualified URL from the
      // URL of the originating request.
      callbackURL = url.resolve(utils.originalURL(req), callbackURL);
    }
  }
  
  if (req.query && req.query.code) {
    var code = req.query.code;
    console.log('the yahoo code: ', req.query, code, self._options, self._options._clientSecret, self._options._clientId);

    var params= params || {};
    params['client_id'] = self._options._clientId;
    params['client_secret'] = self._options._clientSecret;
    var codeParam = (params.grant_type === 'refresh_token') ? 'refresh_token' : 'authorization_code';
    params[codeParam]= code;

    var post_data= querystring.stringify( params );
    var post_headers= {
      'Content-Type': 'application/json'
    };

    var _authorization = [
      'Basic: ',
      new Buffer(self._options.clientID + ':' + self._options.clientSecret).toString('base64')
    ].join('');
    
    var request_options = {
      url: self._options.tokenURL,
      headers: {
        Authorization: _authorization
      },
      rejectUnauthorized: false,
      json: true,
      form: {
        code: code,
        redirect_uri: self._options.callbackURL,
        grant_type: codeParam
      }
    };

    request.post(request_options, function(err, response, body) {
      if (err) { return self.error(new InternalOAuthError('failed to obtain access token', err)); }

      var results = body;
      var guid = body.xoauth_yahoo_guid;
      var accessToken = body.access_token;
      var refreshToken = body.refresh_token;

      self._loadUserProfile({
        accessToken: accessToken,
        xoauth_yahoo_guid: guid
      }, function(err, profile) {
        if(err) return self.error(err);

        function verified(error, user, info) {
          if(error) return self.error(error);
          if(!user) return self.fail(info);

          return self.success(user, info);
        }

        if(self._passReqToCallback) {
          self._verify(req, accessToken, refreshToken, results, profile, verified);
        }else {
          self._verify(accessToken, refreshToken, results, profile, verified);
        }
      });
    });
  } else {
    // NOTE: The module oauth (0.9.5), which is a dependency, automatically adds
    //       a 'type=web_server' parameter to the query portion of the URL.
    //       This appears to be an artifact from an earlier draft of OAuth 2.0
    //       (draft 22, as of the time of this writing).  This parameter is not
    //       necessary, but its presence does not appear to cause any issues.
    
    var params = this.authorizationParams(options);
    params['response_type'] = 'code';
    params['redirect_uri'] = callbackURL;

    console.log('here: ', params);

    var scope = options.scope || this._scope;
    if (scope) {
      if (Array.isArray(scope)) { scope = scope.join(this._scopeSeparator); }
      params.scope = scope;
    }
{'fraction_non_alphanumeric': 0.12603734439834025, 'fraction_numerical': 0.007261410788381743, 'mean_word_length': 2.99482044198895, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 10, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '228179', 'n_tokens_mistral': 3475, 'n_tokens_neox': 3355, 'n_words': 880}