
var _ = require('lodash'),
  redis = require('redis'),
  createGithubApi = require('./create-github-api.js');

// Session backed by Redis, but that
// attempts to lookup against GHE if
// the token is not found in the DB.
function SessionGithub(opts) {
  _.extend(this, {
    client: redis.createClient(),
    githubHost: 'api.github.com',
    debug: true,
    githubPathPrefix: '/api/v3'
  }, require('@npm/enterprise-configurator').Config(), opts)
}

SessionGithub.prototype.get = function(key, cb) {
  var _this = this;

  this.client.get(key, function(err, data) {
    if (err) cb(err);
    else if (data) cb(null, JSON.parse(data));
    else { // attempt to lookup user in GHE.
      _this._githubLookup(key, cb);
    }
  });
};

SessionGithub.prototype._githubLookup = function(key, cb) {
  var _this = this,
    github = createGithubApi(this),
    // extract the GHE key from the user-<token> string.
    token = key.split('-').splice(1).join('-');

  github.authenticate({
    type: 'oauth',
    token: token
  });

  github.user.get({}, function(err, res) {
    if (err) cb(err);
    else if (res.code < 200 || res.code >= 400) cb(Error('status = ' + res.code));
    else {
      var session = {
        name: res.login,
        email: res.email
      };

      _this.set(key, session, function(err) {
        if (err) cb(err);
        else cb(undefined, session);
      });
    }
  });
};

SessionGithub.prototype.set = function(key, session, cb) {
  this.client.set(key, JSON.stringify(session), cb);
};

module.exports = SessionGithub;

@@ -518,16 +518,66 @@
  this;%0A%0A
+  // First check if we have the session in Redis.%0A
   this.c
@@ -643,94 +643,306 @@
     
-else if (data) cb(null, JSON.parse(data));%0A    else %7B // attempt to lookup u
+// If we do, simply return the existing session.%0A    else if (data) cb(null, JSON.parse(data));%0A    else %7B%0A      // If we don't, talk to GHE instance. This can happen when, for example,%0A      // user tries logging into a different npm Enterpri
 se
-r
  in
- GHE
+stance with an%0A      // existing, logged in .npmrc
 .%0A  
@@ -1209,24 +1209,177 @@
 join('-');%0A%0A
+  // the token authenticator creates is a GitHub OAuth token, so we can simply%0A  // try authenticating with it and then fetching the authenticated user.%0A
   github.aut
@@ -1674,16 +1674,132 @@
     %7D;%0A%0A
+      // If authentication with GitHub succeeded, persist the GitHub login and%0A      // email in our session store.%0A
       _t

Add comments to GitHub session implementation