Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit.

  • Loading branch information...
commit 38a52c788596d4c4d3d1c705c25608a9a33983d1 0 parents
@jaredhanson authored
2  .gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+node_modules
8 .npmignore
@@ -0,0 +1,8 @@
+*.md
+.DS_Store
+.git*
+Makefile
+docs/
+examples/
+support/
+test/
20 LICENSE
@@ -0,0 +1,20 @@
+(The MIT License)
+
+Copyright (c) 2011 Jared Hanson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 Makefile
@@ -0,0 +1,19 @@
+NODE = node
+TEST = vows
+TESTS ?= test/*-test.js
+
+test:
+ @NODE_ENV=test NODE_PATH=lib $(TEST) $(TEST_FLAGS) $(TESTS)
+
+docs: docs/api.html
+
+docs/api.html: lib/passport-github/*.js
+ dox \
+ --title Passport-GitHub \
+ --desc "GitHub authentication strategy for Passport" \
+ $(shell find lib/passport-github/* -type f) > $@
+
+docclean:
+ rm -f docs/*.{1,html}
+
+.PHONY: test docs docclean
31 README.md
@@ -0,0 +1,31 @@
+# Passport-GitHub
+
+[Passport](https://github.com/jaredhanson/passport) strategy for authenticating
+with GitHub using the OAuth 2.0 API.
+
+## Credits
+
+ - [Jared Hanson](http://github.com/jaredhanson)
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 Jared Hanson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 lib/passport-github/index.js
@@ -0,0 +1,15 @@
+/**
+ * Module dependencies.
+ */
+var Strategy = require('./strategy');
+
+
+/**
+ * Framework version.
+ */
+exports.version = '0.1.0';
+
+/**
+ * Expose constructors.
+ */
+exports.Strategy = Strategy;
98 lib/passport-github/strategy.js
@@ -0,0 +1,98 @@
+/**
+ * Module dependencies.
+ */
+var util = require('util')
+ , OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
+
+
+/**
+ * `Strategy` constructor.
+ *
+ * The GitHub authentication strategy authenticates requests by delegating to
+ * GitHub using the OAuth 2.0 protocol.
+ *
+ * Applications must supply a `verify` callback which accepts an `accessToken`,
+ * `refreshToken` 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:
+ * - `clientID` your GitHub application's Client ID
+ * - `clientSecret` your GitHub application's Client Secret
+ * - `callbackURL` URL to which GitHub will redirect the user after granting authorization
+ *
+ * Examples:
+ *
+ * passport.use(new GitHubStrategy({
+ * clientID: '123-456-789',
+ * clientSecret: 'shhh-its-a-secret'
+ * callbackURL: 'https://www.example.net/auth/github/callback'
+ * },
+ * function(accessToken, refreshToken, profile, done) {
+ * User.findOrCreate(..., function (err, user) {
+ * done(err, user);
+ * });
+ * }
+ * ));
+ *
+ * @param {Object} options
+ * @param {Function} verify
+ * @api public
+ */
+function Strategy(options, verify) {
+ options = options || {};
+ options.authorizationURL = options.authorizationURL || 'https://github.com/login/oauth/authorize';
+ options.tokenURL = options.tokenURL || 'https://github.com/login/oauth/access_token';
+
+ OAuth2Strategy.call(this, options, verify);
+ this.name = 'github';
+}
+
+/**
+ * Inherit from `OAuth2Strategy`.
+ */
+util.inherits(Strategy, OAuth2Strategy);
+
+
+/**
+ * Retrieve user profile from GitHub.
+ *
+ * This function constructs a normalized profile, with the following properties:
+ *
+ * - `provider` always set to `github`
+ * - `id` the user's GitHub ID
+ * - `username` the user's GitHub username
+ * - `displayName` the user's full name
+ * - `profileUrl` the URL of the profile for the user on GitHub
+ * - `emails` the user's email addresses
+ *
+ * @param {String} accessToken
+ * @param {Function} done
+ * @api protected
+ */
+Strategy.prototype.userProfile = function(accessToken, done) {
+ this._oauth2.getProtectedResource('https://api.github.com/user', accessToken, function (err, body, res) {
+ if (err) { return done(err); }
+
+ try {
+ o = JSON.parse(body);
+
+ var profile = { provider: 'github' };
+ profile.id = o.id;
+ profile.displayName = o.name;
+ profile.username = o.login;
+ profile.profileUrl = o.html_url;
+ profile.emails = [{ value: o.email }];
+
+ done(null, profile);
+ } catch(e) {
+ done(e);
+ }
+ });
+}
+
+
+/**
+ * Expose `Strategy`.
+ */
+module.exports = Strategy;
16 package.json
@@ -0,0 +1,16 @@
+{
+ "name": "passport-github",
+ "version": "0.1.0",
+ "description": "GitHub authentication strategy for Passport.",
+ "author": "Jared Hanson <jaredhanson@gmail.com> (http://www.jaredhanson.net/)",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/jaredhanson/passport-github.git"
+ },
+ "main": "./lib/passport-github",
+ "dependencies": {
+ "passport-oauth": ">= 0.1.0"
+ },
+ "engines": { "node": ">= 0.4.0" },
+ "keywords": ["passport", "github", "auth", "authn", "authentication", "identity"]
+}
15 test/index-test.js
@@ -0,0 +1,15 @@
+var vows = require('vows');
+var assert = require('assert');
+var util = require('util');
+var github = require('passport-github');
+
+
+vows.describe('passport-github').addBatch({
+
+ 'module': {
+ 'should report a version': function (x) {
+ assert.isString(github.version);
+ },
+ },
+
+}).export(module);
105 test/strategy-test.js
@@ -0,0 +1,105 @@
+var vows = require('vows');
+var assert = require('assert');
+var util = require('util');
+var GitHubStrategy = require('passport-github/strategy');
+
+
+vows.describe('GitHubStrategy').addBatch({
+
+ 'strategy': {
+ topic: function() {
+ return new GitHubStrategy({
+ clientID: 'ABC123',
+ clientSecret: 'secret'
+ },
+ function() {});
+ },
+
+ 'should be named github': function (strategy) {
+ assert.equal(strategy.name, 'github');
+ },
+ },
+
+ 'strategy when loading user profile': {
+ topic: function() {
+ var strategy = new GitHubStrategy({
+ clientID: 'ABC123',
+ clientSecret: 'secret'
+ },
+ function() {});
+
+ // mock
+ strategy._oauth2.getProtectedResource = function(url, accessToken, callback) {
+ var body = '{ "login": "octocat", "id": 1, "name": "monalisa octocat", "email": "octocat@github.com", "html_url": "https://github.com/octocat" }';
+
+ callback(null, body, undefined);
+ }
+
+ return strategy;
+ },
+
+ 'when told to load user profile': {
+ topic: function(strategy) {
+ var self = this;
+ function done(err, profile) {
+ self.callback(err, profile);
+ }
+
+ process.nextTick(function () {
+ strategy.userProfile('access-token', done);
+ });
+ },
+
+ 'should not error' : function(err, req) {
+ assert.isNull(err);
+ },
+ 'should load profile' : function(err, profile) {
+ assert.equal(profile.provider, 'github');
+ assert.equal(profile.id, '1');
+ assert.equal(profile.username, 'octocat');
+ assert.equal(profile.displayName, 'monalisa octocat');
+ assert.equal(profile.profileUrl, 'https://github.com/octocat');
+ assert.length(profile.emails, 1);
+ assert.equal(profile.emails[0].value, 'octocat@github.com');
+ },
+ },
+ },
+
+ 'strategy when loading user profile and encountering an error': {
+ topic: function() {
+ var strategy = new GitHubStrategy({
+ clientID: 'ABC123',
+ clientSecret: 'secret'
+ },
+ function() {});
+
+ // mock
+ strategy._oauth2.getProtectedResource = function(url, accessToken, callback) {
+ callback(new Error('something-went-wrong'));
+ }
+
+ return strategy;
+ },
+
+ 'when told to load user profile': {
+ topic: function(strategy) {
+ var self = this;
+ function done(err, profile) {
+ self.callback(err, profile);
+ }
+
+ process.nextTick(function () {
+ strategy.userProfile('access-token', done);
+ });
+ },
+
+ 'should error' : function(err, req) {
+ assert.isNotNull(err);
+ },
+ 'should not load profile' : function(err, profile) {
+ assert.isUndefined(profile);
+ },
+ },
+ },
+
+}).export(module);
Please sign in to comment.
Something went wrong with that request. Please try again.