From 0119048bd12aae798a22bcd6d743b1470182fcd7 Mon Sep 17 00:00:00 2001 From: Takahashi Misato Date: Thu, 10 Jan 2013 22:32:39 +0900 Subject: [PATCH] first commit --- README.md | 0 examples/deskcom/app.js | 99 ++++++++++++++++++++++++ examples/deskcom/package.json | 9 +++ examples/deskcom/views/account.ejs | 2 + examples/deskcom/views/index.ejs | 5 ++ examples/deskcom/views/layout.ejs | 21 +++++ examples/deskcom/views/login.ejs | 1 + lib/passport-deskcom/index.js | 8 ++ lib/passport-deskcom/strategy.js | 118 +++++++++++++++++++++++++++++ package.json | 37 +++++++++ test/index-test.js | 12 +++ test/strategy-test.js | 22 ++++++ 12 files changed, 334 insertions(+) create mode 100644 README.md create mode 100644 examples/deskcom/app.js create mode 100644 examples/deskcom/package.json create mode 100644 examples/deskcom/views/account.ejs create mode 100644 examples/deskcom/views/index.ejs create mode 100644 examples/deskcom/views/layout.ejs create mode 100644 examples/deskcom/views/login.ejs create mode 100644 lib/passport-deskcom/index.js create mode 100644 lib/passport-deskcom/strategy.js create mode 100644 package.json create mode 100644 test/index-test.js create mode 100644 test/strategy-test.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/deskcom/app.js b/examples/deskcom/app.js new file mode 100644 index 0000000..2c289e8 --- /dev/null +++ b/examples/deskcom/app.js @@ -0,0 +1,99 @@ +var express = require('express') + , passport = require('passport') + , util = require('util') + , DeskcomStrategy = require('passport-deskcom').Strategy; + +var DESKCOM_CONSUMER_KEY = "-----"; +var DESKCOM_CONSUMER_SECRET = "------"; + +passport.serializeUser(function(user, done) { + done(null, user); +}); + +passport.deserializeUser(function(obj, done) { + done(null, obj); +}); + +passport.use( + new DeskcomStrategy( + { + consumerKey: DESKCOM_CONSUMER_KEY, + consumerSecret: DESKCOM_CONSUMER_SECRET, + site: "https://spotlight.desk.com", + callbackURL: "http://127.0.0.1:3000/auth/deskcom/callback" + }, + function(token, tokenSecret, profile, done) { + process.nextTick(function () { + return done(null, profile); + }); + } + ) +); + +var express = require("express"); +var app = express(); + +// configure Express +app.configure(function() { + app.set('views', __dirname + '/views'); + app.set('view engine', 'ejs'); + app.use(express.logger()); + app.use(express.cookieParser()); + app.use(express.bodyParser()); + app.use(express.methodOverride()); + app.use(express.session({ secret: 'keyboard cat' })); + // Initialize Passport! Also use passport.session() middleware, to support + // persistent login sessions (recommended). + app.use(passport.initialize()); + app.use(passport.session()); + app.use(app.router); + app.use(express.static(__dirname + '/public')); +}); + + +app.get('/', function(req, res){ + res.render('index', { user: req.user }); +}); + +app.get('/account', ensureAuthenticated, function(req, res){ + res.render('account', { user: req.user }); +}); + +app.get('/login', function(req, res){ + res.render('login', { user: req.user }); +}); + +// GET /auth/deskcom +// Use passport.authenticate() as route middleware to authenticate the +// request. The first step in Twitter authentication will involve redirecting +// the user to desk.com. After authorization, the Twitter will redirect +// the user back to this application at /auth/deskcom/callback +app.get('/auth/deskcom', + passport.authenticate('deskcom'), + function(req, res){ + // The request will be redirected to Twitter for authentication, so this + // function will not be called. + }); + +// GET /auth/deskcom/callback +// Use passport.authenticate() as route middleware to authenticate the +// request. If authentication fails, the user will be redirected back to the +// login page. Otherwise, the primary route function function will be called, +// which, in this example, will redirect the user to the home page. +app.get('/auth/deskcom/callback', + passport.authenticate('deskcom', { failureRedirect: '/login' }), + function(req, res) { + res.redirect('/'); + }); + +app.get('/logout', function(req, res){ + req.logout(); + res.redirect('/'); +}); + +app.listen(3000); + +function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) { return next(); } + res.redirect('/login') +} diff --git a/examples/deskcom/package.json b/examples/deskcom/package.json new file mode 100644 index 0000000..806abb1 --- /dev/null +++ b/examples/deskcom/package.json @@ -0,0 +1,9 @@ +{ + "name": "passport-deskcom-examples-signin", + "version": "0.0.0", + "dependencies": { + "express": ">= 0.0.0", + "ejs": ">= 0.0.0", + "passport": ">= 0.0.0" + } +} diff --git a/examples/deskcom/views/account.ejs b/examples/deskcom/views/account.ejs new file mode 100644 index 0000000..eaa02a2 --- /dev/null +++ b/examples/deskcom/views/account.ejs @@ -0,0 +1,2 @@ +

ID: <%= user.id %>

+

Username: <%= user.name %>

\ No newline at end of file diff --git a/examples/deskcom/views/index.ejs b/examples/deskcom/views/index.ejs new file mode 100644 index 0000000..77ad23e --- /dev/null +++ b/examples/deskcom/views/index.ejs @@ -0,0 +1,5 @@ +<% if (!user) { %> +

Welcome! Please log in.

+<% } else { %> +

Hello, <%= user.name %>.

+<% } %> \ No newline at end of file diff --git a/examples/deskcom/views/layout.ejs b/examples/deskcom/views/layout.ejs new file mode 100644 index 0000000..a4165b2 --- /dev/null +++ b/examples/deskcom/views/layout.ejs @@ -0,0 +1,21 @@ + + + + Passport-Deskcom Example + + + <% if (!user) { %> +

+ Home | + Log In +

+ <% } else { %> +

+ Home | + Account | + Log Out +

+ <% } %> + <%- body %> + + \ No newline at end of file diff --git a/examples/deskcom/views/login.ejs b/examples/deskcom/views/login.ejs new file mode 100644 index 0000000..88e6e9c --- /dev/null +++ b/examples/deskcom/views/login.ejs @@ -0,0 +1 @@ +login deskcom \ No newline at end of file diff --git a/lib/passport-deskcom/index.js b/lib/passport-deskcom/index.js new file mode 100644 index 0000000..da09260 --- /dev/null +++ b/lib/passport-deskcom/index.js @@ -0,0 +1,8 @@ +var Strategy = require('./strategy'); + +var pkg_info = require('pkginfo') +pkg_info(module, 'version'); + +exports.Strategy = Strategy; + + diff --git a/lib/passport-deskcom/strategy.js b/lib/passport-deskcom/strategy.js new file mode 100644 index 0000000..ab9f5dc --- /dev/null +++ b/lib/passport-deskcom/strategy.js @@ -0,0 +1,118 @@ +/** + * Module dependencies. + */ + +var util = require('util') + , _ = require('underscore') + , OAuthStrategy = require('passport-oauth').OAuthStrategy + , InternalOAuthError = require('passport-oauth').OAuthStrategy.InternalOAuthError; + +/** + * Const parameters + */ +var DESK_COM_TOKEN_PATH = '/oauth/request_token'; +var DESK_COM_ACCESS_TOKEN_PATH = '/oauth/access_token'; +var DESK_COM_AUTH_PATH = '/oauth/authorize'; +var DESK_CRETENTIAL_PATH = '/api/v1/account/verify_credentials.json'; + +var DESK_COM_SESSION_KEY = 'oauth:deskcom:'; + +/** + * `Strategy` constructor. + * + * Desk.com authentication strategy + * Oauth1.0a protocol + * + * Options: + * - `consumerKey` identifies client to Deskcom + * - `consumerSecret` secret used to establish ownership of the consumer key + * - `callbackURL` URL to which Deskcom will redirect the user after obtaining authorization + * + * Examples: + * + * passport.use(new DeskcomStrategy({ + * consumerKey: '*************', + * consumerSecret: '***************', + * site: 'https://yoursite.desk.com', + * }, + * function (token, tokenSecret, profile, done) { + * + * } + * }); + * + * @param {Object} options + * @param {Function} verify + * @api public + */ +function Strategy(options, verify) { + options = options || {}; + if (!options.site) { + throw new Error('DesckcomStrategy requires desk.com site url'); + } + options.requestTokenURL = options.requestTokenURL || options.site+DESK_COM_TOKEN_PATH; + options.accessTokenURL = options.accessTokenURL || options.site+DESK_COM_ACCESS_TOKEN_PATH; + options.userAuthorizationURL = options.userAuthorizationURL || options.site+DESK_COM_AUTH_PATH; + options.sessionKey = options.sessionKey || DESK_COM_SESSION_KEY + + this.DESK_CRETENTIAL_URL = options.site+DESK_CRETENTIAL_PATH; + + console.log(options); + OAuthStrategy.call(this, options, verify); + this.name = 'deskcom'; +} + +util.inherits(Strategy, OAuthStrategy); + +module.exports = Strategy; + +/** + * Authenticate request by delegating to Desk.com using OAuth. + * + * @param req + * @param options + * @return {*} + * @api protected + */ +Strategy.prototype.authenticate = function(req, options) { + if (req.query && req.query.denied) { + return this.fail(); + } + OAuthStrategy.prototype.authenticate.call(this, req, options); +} + +/** + * Retrieve user profile from Desk.com. + * + * @param {String} token + * @param {String} tokenSecret + * @param {Object} params + * @param {Function} done + * @api protected + */ +Strategy.prototype.userProfile = function(token, tokenSecret, params, done) { + this._oauth.get(this.DESK_CRETENTIAL_URL, token, tokenSecret, function (err, body, res) { + if (err) { + return done(new InternalOAuthError('failed to fetch user CRETENTIAL', err)); + } + try { + var json = JSON.parse(body); + var profile = _.clone(json.user); + profile.provider = 'deskcom'; + profile._raw = body; + profile._json = json; + done(null, profile); + } catch (e) { + done(e); + } + }); +} + +/** + * Expose `Strategy`. + */ +module.exports = Strategy; + + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..babeccf --- /dev/null +++ b/package.json @@ -0,0 +1,37 @@ +{ + "name": "passport-deskcom", + "version": "0.0.1", + "description": "Desk.com authentication strategy for Passport.", + "author": { + "name": "Misato Takahashi", + "email": "misato_takahashi@spotlig.ht", + "url": "http://www.smapo.jp/" + }, + "repository": { + "type": "git", + "url": "git://github.com/mistat/passport-deskcom.git" + }, + "bugs": { + "url": "http://github.com/mistat/passport-deskcom/issues" + }, + "main": "./lib/passport-deskcom", + "dependencies": { + "pkginfo": "0.2.x", + "passport-oauth": "0.1.x", + "underscore": ">0.0.0" + }, + "devDependencies": { + "vows": "0.6.x" + }, + "scripts": { + "test": "NODE_PATH=lib node_modules/.bin/vows test/*-test.js" + }, + "engines": { "node": ">= 0.4.0" }, + "licenses": [ + { + "type": "MIT", + "url": "http://www.opensource.org/licenses/MIT" + } + ], + "keywords": ["passport", "deskcom", "auth", "authn", "authentication", "identity"] +} diff --git a/test/index-test.js b/test/index-test.js new file mode 100644 index 0000000..e71591d --- /dev/null +++ b/test/index-test.js @@ -0,0 +1,12 @@ +var vows = require('vows'); +var assert = require('assert'); +var util = require('util'); +var deskcom = require('passport-deskcom'); + +vows.describe('passport-deskcom').addBatch({ + 'module': { + 'should report a version' : function (x) { + assert.isString(deskcom.version); + } + } +}).export(module); diff --git a/test/strategy-test.js b/test/strategy-test.js new file mode 100644 index 0000000..bcd5299 --- /dev/null +++ b/test/strategy-test.js @@ -0,0 +1,22 @@ +var vows = require('vows'); +var assert = require('assert'); +var util = require('util'); +var DeskcomStrategy = require('passport-deskcom/strategy'); + +vows.describe('DeskcomStrategy').addBatch({ + 'strategy': { + topic: function() { + return new DeskcomStrategy({ + consumerKey: 'desk-com-test-key', + consumerSecret: 'desk-com-test-secret', + site: 'https://example.desk.com/' + }, + function() {}); + }, + + 'should be name deskcom' : function (strategy) { + assert.equal(strategy.name, 'deskcom'); + } + + } +}).export(module);