kopia lustrzana https://github.com/c9/core
				
				
				
			preview performance WIP
							rodzic
							
								
									dcc1e2b7b9
								
							
						
					
					
						commit
						10ec41d1e7
					
				| 
						 | 
				
			
			@ -0,0 +1,283 @@
 | 
			
		|||
(function(global) {
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
var token = "";
 | 
			
		||||
 | 
			
		||||
var auth = global.auth = function(options) {
 | 
			
		||||
    // can only be called once
 | 
			
		||||
    global.auth = null;
 | 
			
		||||
 | 
			
		||||
    var onLoad = options.onLoad; 
 | 
			
		||||
    var preload = options.preload || noop;
 | 
			
		||||
    var authorized = options.authorized || noop;
 | 
			
		||||
    var background = options.background || noop;
 | 
			
		||||
    
 | 
			
		||||
    importCssString("html.fulliframe, body.fulliframe {\
 | 
			
		||||
        overflow: hidden;\
 | 
			
		||||
        margin: auto;\
 | 
			
		||||
        height: 100%;\
 | 
			
		||||
        width: 100%;\
 | 
			
		||||
    }");
 | 
			
		||||
    
 | 
			
		||||
    function noop(callback) { callback(); }
 | 
			
		||||
    
 | 
			
		||||
    if (onLoad) {
 | 
			
		||||
        auth.parallel([
 | 
			
		||||
            background,
 | 
			
		||||
            auth.serial([
 | 
			
		||||
                auth.parallel([
 | 
			
		||||
                    preload,
 | 
			
		||||
                    login
 | 
			
		||||
                ]),
 | 
			
		||||
                authorized,
 | 
			
		||||
            ])
 | 
			
		||||
        ])(done);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function login(callback, errback) {
 | 
			
		||||
        var oauth = new Auth(options.clientId, options.authorizationUrl, options.loginHint);
 | 
			
		||||
        
 | 
			
		||||
        oauth.authorize(true, function(err, _token) {
 | 
			
		||||
            if (err) 
 | 
			
		||||
                return iframeLogin();
 | 
			
		||||
                
 | 
			
		||||
            token = _token.access_token;
 | 
			
		||||
            callback(null, token);
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        function iframeLogin() {
 | 
			
		||||
            errback && errback();
 | 
			
		||||
            oauth.authorize(false, function(err, _token) {
 | 
			
		||||
                if (err) return callback(err);
 | 
			
		||||
                token = _token.access_token;
 | 
			
		||||
                callback(null, token);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return function cancel() {
 | 
			
		||||
            oauth.cancel();
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function done(err) {
 | 
			
		||||
        onLoad(err, token);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return {
 | 
			
		||||
        login: login
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function bindScript(script) {
 | 
			
		||||
    if (typeof script == "function")
 | 
			
		||||
        return script;
 | 
			
		||||
    else
 | 
			
		||||
        return loadScript.bind(null, script, token);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auth.serial = function(list) {
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        serial(list.map(bindScript), callback);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
auth.parallel = function(list) {
 | 
			
		||||
    return function(callback) {
 | 
			
		||||
        parallel(list.map(bindScript), callback);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function loadScript(path, token, callback) {
 | 
			
		||||
    var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
 | 
			
		||||
    var s = document.createElement('script');
 | 
			
		||||
 | 
			
		||||
    var and = path.indexOf("?") >= 0 ? "&" : "?";
 | 
			
		||||
    s.src = path + (token ? and + "access_token=" + encodeURIComponent(token) : "");
 | 
			
		||||
    head.appendChild(s);
 | 
			
		||||
 | 
			
		||||
    s.onload = s.onreadystatechange = function(_, isAbort) {
 | 
			
		||||
        if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
 | 
			
		||||
            s = s.onload = s.onreadystatechange = null;
 | 
			
		||||
            if (!isAbort)
 | 
			
		||||
                callback();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// copied from ace/lib/dom
 | 
			
		||||
function importCssString(cssText) {
 | 
			
		||||
    var style;
 | 
			
		||||
    
 | 
			
		||||
    if (document.createStyleSheet) {
 | 
			
		||||
        style = document.createStyleSheet();
 | 
			
		||||
        style.cssText = cssText;
 | 
			
		||||
    } else {
 | 
			
		||||
        style = document.createElementNS
 | 
			
		||||
            ? document.createElementNS("http://www.w3.org/1999/xhtml", "style")
 | 
			
		||||
            : document.createElement("style");
 | 
			
		||||
 | 
			
		||||
        style.appendChild(document.createTextNode(cssText));
 | 
			
		||||
 | 
			
		||||
        (document.head || document.getElementsByTagName("head")[0] || document.documentElement).appendChild(style);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function serial(handlers, callback) {
 | 
			
		||||
    (function loop(i) {
 | 
			
		||||
        if (i >= handlers.length) return callback();
 | 
			
		||||
        
 | 
			
		||||
        handlers[i](function(err) {
 | 
			
		||||
            if (err) return callback(err);
 | 
			
		||||
            
 | 
			
		||||
            loop(i+1);
 | 
			
		||||
        });
 | 
			
		||||
    })(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parallel(handlers, callback) {
 | 
			
		||||
    var hadErr = false;
 | 
			
		||||
    var count = 0;
 | 
			
		||||
    handlers.forEach(function(handler) {
 | 
			
		||||
        handler(function(err) {
 | 
			
		||||
            if (hadErr) return;
 | 
			
		||||
            if (err) {
 | 
			
		||||
                hadErr = true;
 | 
			
		||||
                return callback(err);
 | 
			
		||||
            }
 | 
			
		||||
            count += 1;
 | 
			
		||||
            if (count == handlers.length)
 | 
			
		||||
                return callback();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// install exactly one global listener
 | 
			
		||||
var listeners = {};
 | 
			
		||||
window.addEventListener("message", function(e) {
 | 
			
		||||
    var token = e.data.token;
 | 
			
		||||
    if (token) {
 | 
			
		||||
        for (var url in listeners) {
 | 
			
		||||
            if (url.indexOf(e.origin) === 0) {
 | 
			
		||||
                var callback = listeners[url][token.state];
 | 
			
		||||
                delete listeners[url][token.state];
 | 
			
		||||
                if (callback) callback(null, token);
 | 
			
		||||
 | 
			
		||||
                // make sure later listeners can't steal the token
 | 
			
		||||
                e.data.token = null;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}, true);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Auth(clientId, authorizationUrl, loginHint) {
 | 
			
		||||
    this.clientId = clientId;
 | 
			
		||||
    this.authorizationUrl = authorizationUrl;
 | 
			
		||||
    this.loginHint = loginHint;
 | 
			
		||||
    listeners[authorizationUrl] = {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Auth.prototype.authorize = function(immediate, callback) {
 | 
			
		||||
    if (typeof immediate == "function")
 | 
			
		||||
        return this.authorize({}, immediate);
 | 
			
		||||
    
 | 
			
		||||
    immediate = immediate || false;
 | 
			
		||||
    
 | 
			
		||||
    var that = this;
 | 
			
		||||
    this.state = uid(15);
 | 
			
		||||
    
 | 
			
		||||
    var url = this.authorizationUrl + 
 | 
			
		||||
        "?response_type=postmessage" +
 | 
			
		||||
        "&client_id=" + encodeURIComponent(this.clientId) +
 | 
			
		||||
        "&state=" + encodeURIComponent(this.state) +
 | 
			
		||||
        "&style=overlay";
 | 
			
		||||
        
 | 
			
		||||
    if (this.loginHint)
 | 
			
		||||
        url += "&login_hint=" + encodeURIComponent(this.loginHint || "");
 | 
			
		||||
        
 | 
			
		||||
    if (immediate)
 | 
			
		||||
        url += "&immediate=1";
 | 
			
		||||
    
 | 
			
		||||
    var frame = this._createFrame(url, immediate);
 | 
			
		||||
    var timeout = immediate ? 3000 : 0;
 | 
			
		||||
 | 
			
		||||
    if (timeout) {
 | 
			
		||||
        var timer = setTimeout(function() {
 | 
			
		||||
            that._unpoll();
 | 
			
		||||
            callback(new Error("Login timed out"));
 | 
			
		||||
        }, timeout);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    this._removeFrame = function() {
 | 
			
		||||
        clearTimeout(timer);
 | 
			
		||||
        
 | 
			
		||||
        frame.parentNode.removeChild(frame);
 | 
			
		||||
        document.documentElement.className = document.documentElement.className.replace(/\bfulliframe\b/, "");
 | 
			
		||||
        document.body.className = document.body.className.replace(/\bfulliframe\b/, "");
 | 
			
		||||
        that._removeFrame = null;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    this._poll(function(err, token) {
 | 
			
		||||
        if (that._removeFrame)
 | 
			
		||||
            that._removeFrame();
 | 
			
		||||
        
 | 
			
		||||
        if (err)
 | 
			
		||||
            return callback(err);
 | 
			
		||||
            
 | 
			
		||||
        if (token.error) {
 | 
			
		||||
            err = new Error(token.error);
 | 
			
		||||
            err.code = token.error_code;
 | 
			
		||||
            return callback(err);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        that.token = token;
 | 
			
		||||
        return callback(null, token);
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Auth.prototype.cancel = function() {
 | 
			
		||||
    this._unpoll();
 | 
			
		||||
    if (this._removeFrame)
 | 
			
		||||
        this._removeFrame();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Auth.prototype._createFrame = function(url, hidden) {
 | 
			
		||||
    var frame = document.createElement("iframe");
 | 
			
		||||
    frame.setAttribute("src", url);
 | 
			
		||||
    frame.setAttribute("frameborder", "0");
 | 
			
		||||
    if (hidden) {
 | 
			
		||||
        frame.style.width = "1000px";
 | 
			
		||||
        frame.style.height = "1000px";
 | 
			
		||||
        frame.style.left = "-10000px";
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        frame.style.width = "100%";
 | 
			
		||||
        frame.style.height = "100%";
 | 
			
		||||
        frame.style.zIndex = "300000";
 | 
			
		||||
        document.documentElement.className += " fulliframe";
 | 
			
		||||
        document.body.className += " fulliframe";
 | 
			
		||||
    }
 | 
			
		||||
    frame.style.position = "absolute";
 | 
			
		||||
    document.body.appendChild(frame);
 | 
			
		||||
    return frame;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Auth.prototype._poll = function(callback) {
 | 
			
		||||
    listeners[this.authorizationUrl][this.state] = callback;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Auth.prototype._unpoll = function() {
 | 
			
		||||
    delete listeners[this.authorizationUrl][this.state];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function uid(length) {
 | 
			
		||||
    var buf = new Uint8Array(new ArrayBuffer(length));
 | 
			
		||||
    (window.crypto || window.msCrypto).getRandomValues(buf);
 | 
			
		||||
    
 | 
			
		||||
    return btoa(Array.prototype.reduce.call(buf, function(s, c) {
 | 
			
		||||
        return s + String.fromCharCode(c);
 | 
			
		||||
    }, "")).slice(0, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
})(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
"use strict";
 | 
			
		||||
 | 
			
		||||
var assert = require("assert");
 | 
			
		||||
var url = require("url");
 | 
			
		||||
var Cloud9LegayStrategy = require("./legacy_strategy");
 | 
			
		||||
var cookieSignature = require("cookie-signature");
 | 
			
		||||
var decrypt = require("c9/crypt").decrypt;
 | 
			
		||||
var login = require("connect-ensure-login");
 | 
			
		||||
 | 
			
		||||
plugin.consumes = [
 | 
			
		||||
    "db",
 | 
			
		||||
    "passport",
 | 
			
		||||
    "connect.redirect",
 | 
			
		||||
    "connect.cookieparser",
 | 
			
		||||
    "session-store"
 | 
			
		||||
];
 | 
			
		||||
plugin.provides = ["c9.login"];
 | 
			
		||||
 | 
			
		||||
module.exports = plugin;
 | 
			
		||||
 | 
			
		||||
function plugin(options, imports, register) {
 | 
			
		||||
    assert(options.appId, "Option 'appId' is required");
 | 
			
		||||
    assert(options.ideBaseUrl, "Option 'ideBaseUrl' is required");
 | 
			
		||||
    assert(options.baseUrl, "Option 'baseUrl' is required");
 | 
			
		||||
    assert(options.ssoCookie, "Option 'ssoCookie' is required");
 | 
			
		||||
    assert(options.ssoSecret, "Option 'ssoSecret' is required");
 | 
			
		||||
    
 | 
			
		||||
    var db = imports.db;
 | 
			
		||||
    var passport = imports.passport;
 | 
			
		||||
    var sessionStore = imports["session-store"];
 | 
			
		||||
 | 
			
		||||
    // use the 'proxy' cookie to have federated logout
 | 
			
		||||
    passport.useStart(function(req, res, next) {
 | 
			
		||||
        var hash;
 | 
			
		||||
        // anonymous login
 | 
			
		||||
        if (!req.cookies || !(hash = req.cookies[options.ssoCookie]))
 | 
			
		||||
            return done();
 | 
			
		||||
            
 | 
			
		||||
        var encrypted = cookieSignature.unsign(hash, options.ssoSecret);
 | 
			
		||||
        if (!encrypted)
 | 
			
		||||
            return done();
 | 
			
		||||
                
 | 
			
		||||
        var sessionId = decrypt(encrypted, options.ssoSecret);
 | 
			
		||||
        
 | 
			
		||||
        sessionStore.get(sessionId, function(err, session) {
 | 
			
		||||
            if (err) return done(err);
 | 
			
		||||
            done(null, session && session.uid);
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        function done(err, ssoUid) {
 | 
			
		||||
            if (err) return next(err);
 | 
			
		||||
            ssoUid = ssoUid || -1;
 | 
			
		||||
            var session = req.session;
 | 
			
		||||
            if (session && session.passport && session.passport.user && session.passport.user != ssoUid) {
 | 
			
		||||
                return req.session.regenerate(function(err) {
 | 
			
		||||
                    if (err) return next(err);
 | 
			
		||||
                    
 | 
			
		||||
                    if (session.returnTo)
 | 
			
		||||
                        req.session.returnTo = session.returnTo;
 | 
			
		||||
                        
 | 
			
		||||
                    delete req.user;
 | 
			
		||||
                    next();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                if (!req.session.passport)
 | 
			
		||||
                    req.session.passport = {};
 | 
			
		||||
                
 | 
			
		||||
                req.session.passport.user = ssoUid;
 | 
			
		||||
                next();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    var cloud9Strategy = new Cloud9LegayStrategy({
 | 
			
		||||
        clientID: options.appId,
 | 
			
		||||
        ideBaseUrl: options.ideBaseUrl,
 | 
			
		||||
        callback: options.baseUrl + "/auth/c9l/callback",
 | 
			
		||||
        db: db
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    passport.use(cloud9Strategy);
 | 
			
		||||
 | 
			
		||||
    passport.section.get("/c9l", passport.authenticate("c9l"));
 | 
			
		||||
    passport.section.get("/c9l/callback", [
 | 
			
		||||
        passport.authenticate("c9l"),
 | 
			
		||||
        function(req, res, next) {
 | 
			
		||||
            var user = req.user;
 | 
			
		||||
            
 | 
			
		||||
            if (user) {
 | 
			
		||||
                req.login(user, function(err) {
 | 
			
		||||
                    if (err) return next(err);
 | 
			
		||||
                    res.returnTo(req, "/");
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                res.redirect("/auth/c9l");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ]);
 | 
			
		||||
    
 | 
			
		||||
    register(null, {
 | 
			
		||||
        "c9.login": {
 | 
			
		||||
            ensureLoggedIn: function() {
 | 
			
		||||
                return function(req, res, next) {
 | 
			
		||||
                    var redirect = options.baseUrl + "/_auth/c9l";
 | 
			
		||||
                    var nonce = req.parsedUrl.query.__c9_preview_id__;
 | 
			
		||||
                    
 | 
			
		||||
                    if (nonce) {
 | 
			
		||||
                        redirect += "?nonce=" + encodeURIComponent(nonce);
 | 
			
		||||
                        delete req.parsedUrl.query.__c9_preview_id__;
 | 
			
		||||
                        delete req.parsedUrl.search;
 | 
			
		||||
                        req.originalUrl = url.format(req.parsedUrl);
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    login.ensureLoggedIn({
 | 
			
		||||
                        redirectTo: redirect
 | 
			
		||||
                    })(req, res, next);
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
var passport = require('passport');
 | 
			
		||||
var util = require('util');
 | 
			
		||||
var InternalOAuthError = require("passport-oauth").InternalOAuthError;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function Cloud9Legacy(options) {
 | 
			
		||||
    passport.Strategy.call(this);
 | 
			
		||||
    this.name = 'c9l';
 | 
			
		||||
  
 | 
			
		||||
    this.clientID = options.clientID;
 | 
			
		||||
    this.ideBaseUrl = options.ideBaseUrl;
 | 
			
		||||
    this.callback = options.callback;
 | 
			
		||||
    this.db = options.db;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherit from `passport.Strategy`.
 | 
			
		||||
 */
 | 
			
		||||
util.inherits(Cloud9Legacy, passport.Strategy);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Authenticate request based on the contents of a HTTP Basic authorization
 | 
			
		||||
 * header.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} req
 | 
			
		||||
 * @api protected
 | 
			
		||||
 */
 | 
			
		||||
Cloud9Legacy.prototype.authenticate = function(req, options) {
 | 
			
		||||
    var that = this;
 | 
			
		||||
    options = options || {};
 | 
			
		||||
    
 | 
			
		||||
    // the callback handler
 | 
			
		||||
    if (req.query && req.query.code) {
 | 
			
		||||
        this.db.AccessToken
 | 
			
		||||
            .findOne({
 | 
			
		||||
                token: req.query.code
 | 
			
		||||
            })
 | 
			
		||||
            .populate("user")
 | 
			
		||||
            .exec(function(err, token) {
 | 
			
		||||
                if (err)
 | 
			
		||||
                    return that.error(new InternalOAuthError('failed to obtain access token', err));
 | 
			
		||||
                
 | 
			
		||||
                req.session.token = req.query.code;
 | 
			
		||||
                that.success(token.user);
 | 
			
		||||
            });
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    var nonce = req.parsedUrl.query.nonce;
 | 
			
		||||
    if (nonce) {
 | 
			
		||||
        this.redirect(
 | 
			
		||||
            this.ideBaseUrl + 
 | 
			
		||||
            "/api/nc/auth" +
 | 
			
		||||
            "?response_type=nonce" +
 | 
			
		||||
            "&client_id=" + encodeURIComponent(this.clientID + "_nonce") +
 | 
			
		||||
            "&nonce=" + encodeURIComponent(nonce)
 | 
			
		||||
        );
 | 
			
		||||
    } 
 | 
			
		||||
    else {
 | 
			
		||||
        this.redirect(
 | 
			
		||||
            this.ideBaseUrl + 
 | 
			
		||||
            "/api/nc/auth" +
 | 
			
		||||
            "?response_type=token" +
 | 
			
		||||
            "&client_id=" + encodeURIComponent(this.clientID) +
 | 
			
		||||
            "&login_hint=" + encodeURIComponent(options.loginHint || "")
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expose `Cloud9Legacy`.
 | 
			
		||||
 */ 
 | 
			
		||||
module.exports = Cloud9Legacy;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,135 @@
 | 
			
		|||
"use strict";
 | 
			
		||||
 | 
			
		||||
var assert = require("assert");
 | 
			
		||||
var frontdoor = require("frontdoor");
 | 
			
		||||
var cookie = require("cookie");
 | 
			
		||||
var Passport = require("passport").Passport;
 | 
			
		||||
var Cloud9Strategy = require("./strategy");
 | 
			
		||||
 | 
			
		||||
plugin.consumes = [
 | 
			
		||||
    "session",
 | 
			
		||||
    "connect.redirect"
 | 
			
		||||
];
 | 
			
		||||
plugin.provides = ["c9.login"];
 | 
			
		||||
 | 
			
		||||
module.exports = plugin;
 | 
			
		||||
 | 
			
		||||
function plugin(options, imports, register) {
 | 
			
		||||
    assert(options.appId, "Option 'appId' is required");
 | 
			
		||||
    assert(options.appSecret, "Option 'appSecret' is required");
 | 
			
		||||
    assert(options.callback, "Option 'callback' is required");
 | 
			
		||||
    assert(options.logout, "Option 'logout' is required");
 | 
			
		||||
    assert(options.baseUrl, "Option 'baseUrl' is required");
 | 
			
		||||
    assert(options.domain, "Option 'domain' is required");
 | 
			
		||||
    assert(options.ssoCookie, "Option 'ssoCookie' is required");
 | 
			
		||||
    assert(options.ssoCookie.name, "Option 'ssoCookie.name' is required");
 | 
			
		||||
    assert(options.ssoCookie.maxAge, "Option 'ssoCookie.maxAge' is required");
 | 
			
		||||
    
 | 
			
		||||
    var session = imports.session;
 | 
			
		||||
    var passport = new Passport();
 | 
			
		||||
    
 | 
			
		||||
    session.use(passport.initialize());
 | 
			
		||||
    session.use(function(req, res, next) {
 | 
			
		||||
        passport.session()(req, res, function(err) {
 | 
			
		||||
            if (err) return next(err);
 | 
			
		||||
            if (!req.user) return next();
 | 
			
		||||
            
 | 
			
		||||
            var uid = req.cookies[options.ssoCookie.name];
 | 
			
		||||
            if (uid != req.user.id) {
 | 
			
		||||
                req.logout();
 | 
			
		||||
                return next();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            next();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    passport.serializeUser(function(user, done) {
 | 
			
		||||
        var id;
 | 
			
		||||
        try {
 | 
			
		||||
            id = JSON.stringify(user);
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            return done(e);
 | 
			
		||||
        }
 | 
			
		||||
        done(null, id);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    passport.deserializeUser(function(id, done) {
 | 
			
		||||
        var user;
 | 
			
		||||
        try {
 | 
			
		||||
            user = JSON.parse(id);
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            return done(e);
 | 
			
		||||
        }
 | 
			
		||||
        done(null, user);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var cloud9Strategy = new Cloud9Strategy({
 | 
			
		||||
        clientID: options.appId,
 | 
			
		||||
        clientSecret: options.appSecret,
 | 
			
		||||
        callbackURL: options.callback,
 | 
			
		||||
        userProfileURL: options.userProfileURL,
 | 
			
		||||
        baseUrl: options.baseUrl,
 | 
			
		||||
    }, function(accessToken, refreshToken, params, profile, done) {
 | 
			
		||||
        var user = {
 | 
			
		||||
            id: profile.id,
 | 
			
		||||
            username: profile.username,
 | 
			
		||||
            fullname: profile.displayName ? profile.displayName.trim() : profile.username,
 | 
			
		||||
            token: accessToken
 | 
			
		||||
        };
 | 
			
		||||
        done(null, user);
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    passport.use(cloud9Strategy);
 | 
			
		||||
 | 
			
		||||
    var api = frontdoor();
 | 
			
		||||
    passport.section = api.section("auth");
 | 
			
		||||
    session.use(api);
 | 
			
		||||
 | 
			
		||||
    passport.section.get("/logout", function(req, res, next) {
 | 
			
		||||
        res.redirect(options.baseUrl + "/logout?redirect_uri=" + encodeURIComponent(options.logout));
 | 
			
		||||
    });
 | 
			
		||||
    passport.section.get("/cloud9", passport.authenticate("cloud9"));
 | 
			
		||||
    passport.section.get("/cloud9/callback", function(req, res, next) {
 | 
			
		||||
        passport.authenticate("cloud9", function(err, user, info) {
 | 
			
		||||
            if (err) return next(err);
 | 
			
		||||
 | 
			
		||||
            if (user) {
 | 
			
		||||
                req.login(user, function(err) {
 | 
			
		||||
                    if (err) return next(err);
 | 
			
		||||
                    setCookie(res, req.user.id, options.ssoCookie.maxAge);
 | 
			
		||||
                    res.returnTo(req, "/");
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                res.redirect("/auth/cloud9");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        })(req, res, next);
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    passport.section.get("/cloud9/logout", function(req, res, next) {
 | 
			
		||||
        req.logout();
 | 
			
		||||
        clearCookie(res);
 | 
			
		||||
        res.redirect("/");
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    function clearCookie(res) {
 | 
			
		||||
        setCookie(res, "", new Date(1));    
 | 
			
		||||
    }
 | 
			
		||||
    function setCookie(res, value, ttl) {
 | 
			
		||||
        res.setHeader("Set-Cookie", cookie.serialize(options.ssoCookie.name, value, { 
 | 
			
		||||
            domain: "." + options.domain,
 | 
			
		||||
            path: "/",
 | 
			
		||||
            expires: ttl instanceof Date ? ttl : new Date(Date.now() + ttl),
 | 
			
		||||
            secure: true,
 | 
			
		||||
            httpOnly: true
 | 
			
		||||
        }));    
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    register(null, {
 | 
			
		||||
        "c9.login": passport
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
var util = require('util');
 | 
			
		||||
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
 | 
			
		||||
var InternalOAuthError = require('passport-oauth').InternalOAuthError;
 | 
			
		||||
 | 
			
		||||
function Strategy(options, verify) {
 | 
			
		||||
    options = options || {};
 | 
			
		||||
    var baseUrl = options.baseUrl || "https://auth.c9.io/oauth";
 | 
			
		||||
    
 | 
			
		||||
    options.authorizationURL = baseUrl + "/authorize";
 | 
			
		||||
    options.tokenURL = baseUrl + "/access_token";
 | 
			
		||||
    options.scopeSeparator = ",";
 | 
			
		||||
    
 | 
			
		||||
    OAuth2Strategy.call(this, options, verify);
 | 
			
		||||
    this.name = "cloud9";
 | 
			
		||||
    this._userProfileURL = options.userProfileURL || "https://api.c9.io/user";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
util.inherits(Strategy, OAuth2Strategy);
 | 
			
		||||
 | 
			
		||||
Strategy.prototype.userProfile = function(accessToken, done) {
 | 
			
		||||
    this._oauth2.useAuthorizationHeaderforGET(true);
 | 
			
		||||
    this._oauth2.get(this._userProfileURL, accessToken, function (err, body, res) {
 | 
			
		||||
        if (err)
 | 
			
		||||
            return done(new InternalOAuthError('failed to fetch user profile', err));
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            var json = JSON.parse(body);
 | 
			
		||||
            
 | 
			
		||||
            var profile = { provider: "cloud9" };
 | 
			
		||||
            profile.id = json.id;
 | 
			
		||||
            profile.displayName = json.name;
 | 
			
		||||
            profile.username = json.login;
 | 
			
		||||
            profile.emails = [{ value: json.email }];
 | 
			
		||||
            
 | 
			
		||||
            profile._raw = body;
 | 
			
		||||
            profile._json = json;
 | 
			
		||||
            
 | 
			
		||||
            done(null, profile);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          done(e);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = Strategy;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,13 +73,27 @@ define(function(require, exports, module) {
 | 
			
		|||
                        req.projectSession.role = role;
 | 
			
		||||
                        req.projectSession.pid = project.id;
 | 
			
		||||
                        
 | 
			
		||||
                        next();
 | 
			
		||||
                        var type = project.scm;
 | 
			
		||||
                        req.projectSession.type = type;
 | 
			
		||||
                        
 | 
			
		||||
                        if (type != "docker")
 | 
			
		||||
                            return next();
 | 
			
		||||
                        
 | 
			
		||||
                        project.populate("remote", function(err) {
 | 
			
		||||
                            if (err) return next(err);
 | 
			
		||||
                            
 | 
			
		||||
                            var meta = project.remote.metadata;
 | 
			
		||||
                            if (meta && meta.host && meta.cid)
 | 
			
		||||
                                req.projectSession.proxyUrl = "http://" + meta.host + ":9000/" + meta.cid;
 | 
			
		||||
 | 
			
		||||
                            next();
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function proxyCall(getServer) {
 | 
			
		||||
        function getProxyUrl(getServer) {
 | 
			
		||||
            return function(req, res, next) {
 | 
			
		||||
                var server = req.projectSession.vfsServer;
 | 
			
		||||
                if (!server) {
 | 
			
		||||
| 
						 | 
				
			
			@ -90,11 +104,19 @@ define(function(require, exports, module) {
 | 
			
		|||
                    server = req.projectSession.vfsServer = server.internalUrl || server.url;
 | 
			
		||||
                }
 | 
			
		||||
                        
 | 
			
		||||
                var path = req.params.path;
 | 
			
		||||
                
 | 
			
		||||
                var url = server + "/" + req.projectSession.pid + "/preview" + req.params.path;
 | 
			
		||||
                var url = server + "/" + req.projectSession.pid + "/preview";
 | 
			
		||||
                if (req.session.token)
 | 
			
		||||
                    url += "?access_token=" + encodeURIComponent(req.session.token);
 | 
			
		||||
                    
 | 
			
		||||
                req.proxyUrl = url;
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function proxyCall() {
 | 
			
		||||
            return function(req, res, next) {
 | 
			
		||||
                
 | 
			
		||||
                var path = req.params.path;
 | 
			
		||||
                var url = req.proxyUrl + path;
 | 
			
		||||
 | 
			
		||||
                var parsedUrl = parseUrl(url);
 | 
			
		||||
                var httpModule = parsedUrl.protocol == "https:" ? https : http;
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +304,7 @@ define(function(require, exports, module) {
 | 
			
		|||
            "preview.handler": {
 | 
			
		||||
                getProjectSession: getProjectSession,
 | 
			
		||||
                getRole: getRole,
 | 
			
		||||
                getProxyUrl: getProxyUrl,
 | 
			
		||||
                proxyCall: proxyCall
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,9 +49,10 @@ define(function(require, exports, module) {
 | 
			
		|||
            requestTimeout(15*60*1000),
 | 
			
		||||
            handler.getProjectSession(),
 | 
			
		||||
            handler.getRole(db),
 | 
			
		||||
            handler.proxyCall(function() {
 | 
			
		||||
            handler.getProxyUrl(function() {
 | 
			
		||||
                return vfsServers ? vfsServers[0] : null;
 | 
			
		||||
            })
 | 
			
		||||
            }),
 | 
			
		||||
            handler.proxyCall()
 | 
			
		||||
        ]); 
 | 
			
		||||
        
 | 
			
		||||
        api.error(function(err, req, res, next) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,11 +137,12 @@ function plugin(options, imports, register) {
 | 
			
		|||
            req.session = {};
 | 
			
		||||
            next();
 | 
			
		||||
        },
 | 
			
		||||
        previewHandler.proxyCall(function() {
 | 
			
		||||
        previewHandler.getProxyUrl(function() {
 | 
			
		||||
            return {
 | 
			
		||||
                url: "http://localhost:" + options.options.port + "/vfs"
 | 
			
		||||
            };
 | 
			
		||||
        })
 | 
			
		||||
        }),
 | 
			
		||||
        previewHandler.proxyCall()
 | 
			
		||||
    ]);
 | 
			
		||||
    
 | 
			
		||||
    api.get("/preview", function(req, res, next) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue