Skip to content

Commit

Permalink
Implment devMode
Browse files Browse the repository at this point in the history
  • Loading branch information
Megapixel99 committed Feb 2, 2021
1 parent d6a8632 commit 27b7483
Showing 1 changed file with 57 additions and 26 deletions.
83 changes: 57 additions & 26 deletions lib/passport-cas.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ var url = require('url')
*
* Authentication is done by redirecting the user to the CAS login page. The
* user will return with a ticket in the querystring. This ticket is then
* validated by the application against the CAS server to obtain the username
* validated by the application against the CAS server to obtain the username
* and profile.
*
* (CAS optionally allows the application to obtain tickets for 3rd party
* (CAS optionally allows the application to obtain tickets for 3rd party
* services on behalf of the user. This requires the use of a PGT callback
* server, which can be run with the PgtServer() function also from this
* module.)
Expand Down Expand Up @@ -46,19 +46,20 @@ var url = require('url')
* - `propertyMap` Optional. A basic key-value object for mapping extended user attributes from CAS to passport's profile format.
* - `passReqToCallback` Optional. When `true`, `req` is the first argument to the verify callback (default: `false`)
* - `sslCA` Optional. SSL CA bundle to use to validate the PGT server.
* - `devMode` Optional. Useful when testing locally, assumes a CAS session was successfully created
*
* Example:
*
* var CasStrategy = require('passport-cas2').Strategy;
* var cas = new CasStrategy({
* casURL: 'https://signin.example.com/cas',
* propertyMap: {
* propertyMap: {
* id: 'guid',
* givenName: 'givenname',
* familyName: 'surname',
* emails: 'defaultmail'
* }
* },
* },
* function(username, profile, done) {
* User.findOrCreate(..., function(err, user) {
* done(err, user);
Expand All @@ -77,20 +78,21 @@ function CasStrategy(options, verify) {
options = undefined;
}
options = options || {};

if (!verify) { throw new TypeError('CasStrategy requires a verify callback'); }
if (!options.casURL) { throw new TypeError('CasStrategy requires a casURL option'); }

Strategy.call(this);
this.name = 'cas';
this._verify = verify;
this._passReqToCallback = options.passReqToCallback;

this.casBaseUrl = options.casURL;
this.devMode = options.devMode;
this.casPgtUrl = options.pgtURL || undefined;
this.casPropertyMap = options.propertyMap || {};
this.casSessionKey = options.sessionKey || 'cas';

this.cas = new CAS({
base_url: this.casBaseUrl,
version: 2,
Expand All @@ -99,7 +101,7 @@ function CasStrategy(options, verify) {
ssl_key: options.sslKey,
ssl_ca: options.sslCA
});

}

/**
Expand All @@ -117,14 +119,44 @@ util.inherits(CasStrategy, Strategy);
CasStrategy.prototype.authenticate = function(req, options) {
if (!req._passport) { return this.error(new Error('passport.initialize() middleware not in use')); }
options = options || {};

var self = this;
var reqURL = url.parse(req.originalUrl || req.url, true);
var service;


// The provided `verify` callback will call this on completion
function verified(err, user, info) {
if (!self.devMode) {
if (err) { return self.error(err); }
if (!user) { return self.fail(info); }
}
self.success(user, info);
}

if (self.devMode) {
var username = 'test_user';
var profile = {
provider: 'CAS',
id: username,
displayName: username,
name: {
familyName: null,
givenName: null,
middleName: null,
},
emails: [],
};
if (self._passReqToCallback) {
self._verify(req, username, profile, verified);
} else {
self._verify(username, profile, verified);
}
return;
}

// `ticket` is present if user is already authenticated/authorized by CAS
var ticket = reqURL.query['ticket'];

// The `service` string is the current URL, minus the ticket
delete reqURL.query['ticket'];
service = url.format({
Expand All @@ -133,15 +165,15 @@ CasStrategy.prototype.authenticate = function(req, options) {
pathname: req.headers['x-proxied-request-uri'] || reqURL.pathname,
query: reqURL.query
});

if (!ticket) {
// Redirect to CAS server for authentication
self.redirect(self.casBaseUrl + '/login?service=' + encodeURIComponent(service), 307);
}
else {
// User has returned from CAS site with a ticket
self.cas.validate(ticket, function(err, status, username, extended) {

// Ticket validation failed
if (err) {
var date = new Date();
Expand All @@ -160,7 +192,7 @@ CasStrategy.prototype.authenticate = function(req, options) {
self.fail(err);
}
}

// Validation successful
else {
// The provided `verify` callback will call this on completion
Expand All @@ -169,13 +201,13 @@ CasStrategy.prototype.authenticate = function(req, options) {
if (!user) { return self.fail(info); }
self.success(user, info);
}

req.session[self.casSessionKey] = {};

if (self.casPgtUrl) {
req.session[self.casSessionKey].PGTIOU = extended.PGTIOU;
}

var attributes = extended.attributes;
var profile = {
provider: 'CAS',
Expand All @@ -188,7 +220,7 @@ CasStrategy.prototype.authenticate = function(req, options) {
},
emails: []
};

// Map relevant extended attributes returned by CAS into the profile
for (var key in profile) {
if (key == 'name') {
Expand All @@ -202,7 +234,7 @@ CasStrategy.prototype.authenticate = function(req, options) {
}
delete attributes[mappedKey];
}
}
}
else if (key == 'emails') {
var mappedKey = self.casPropertyMap.emails || 'emails';
var emails = attributes[mappedKey];
Expand All @@ -229,7 +261,7 @@ CasStrategy.prototype.authenticate = function(req, options) {
var value = attributes[mappedKey];
if (Array.isArray(value)) {
profile[key] = value[0];
}
}
else if (value) {
profile[key] = value;
}
Expand All @@ -240,14 +272,14 @@ CasStrategy.prototype.authenticate = function(req, options) {
for (var key in attributes) {
profile[key] = attributes[key];
}

if (self._passReqToCallback) {
self._verify(req, username, profile, verified);
} else {
self._verify(username, profile, verified);
}
}

}, service);
}
};
Expand Down Expand Up @@ -307,7 +339,7 @@ CasStrategy.prototype.getProxyTicket = function(req, targetService, done) {
err = new Error('PGTIOU token not found. Make sure pgtURL option is correct, and the CAS server allows proxies.');
}
}

if (err) {
return done(err);
}
Expand All @@ -333,7 +365,7 @@ module.exports.Strategy = CasStrategy;
* This is the server needed to obtain CAS tickets for 3rd party services on
* behalf of the user. It is typically run as a separate process from the
* application. Multiple applications may share the same PGT callback server.
*
*
* @param {String} casURL
* The URL of the CAS server.
* @param {String} pgtURL
Expand Down Expand Up @@ -367,4 +399,3 @@ function PgtServer(casURL, pgtURL, serverCertificate, serverKey, serverCA) {
* Expose `PgtServer`.
*/
module.exports.PgtServer = PgtServer;

0 comments on commit 27b7483

Please sign in to comment.