<commit_before>/*global NB:true NB$:true $:true rangy:true alert:true wgxpath:true jQuery:true getElementCSSSelector:true console:true */
(function(GLOB){
    var _scrollTimerID=null;
    var _scrollCounter=0;
    if ("NB$" in window){
        var $ = NB$;
    }

    var $str        = "NB$" in window ? "NB$" : "jQuery";
    var cssApplier = null;
    var lastClicked = {set: [], clicked: null};

    var restore = function(loc) {
        var sel = rangy.getSelection();
        sel.restoreCharacterRanges(getElementsByXPath(document, loc.path1)[0],
                                   [{backward: loc.path2 === "true",
                                               characterRange: {
                                               start: loc.offset1,
                                               end: loc.offset2
                                           }
                                       }]);
        placeAnnotation(sel, loc);
    };

    var restoreBatch = function(object, callback) {
        var start = (new Date()).getTime();
        var current;

        for (var key in object) {
            current = (new Date()).getTime();
            if (current - start > 150) {
                window.setTimeout(restoreBatch, 10, object, callback);
                return;
            }

            restore(object[key]);
            delete object[key];
        }

        callback();
    };

    GLOB.html = {
        id: "docviewHtml5"
    };

    GLOB.html.init = function () {

        var countChildChars = function(_char, _this) {
            var char = _char;

            // count text nodes as well (includes whitespace)
            $(_this).contents().each(function() {
                  if (this.nodeType === 1) {
                      $(this).attr("data_char", char);
                      countChildChars(char, this);
                  }
                  char += ($(this).text()).length;
            });
        };

        countChildChars(0, $("body")[0]);

        $.concierge.addListeners(GLOB.html,{
                page: function(evt){
                   // _render();
                },
                note_hover: function(event){
                    $(".nb-comment-highlight[id_item="+event.value+"]").addClass("hovered");
                },
                note_out: function(event){
                    $(".nb-comment-highlight[id_item="+event.value+"]").removeClass("hovered");
                },
                visibility: function(event){
                    console.warn("TODO", event);
                },
                select_thread: function(event){
                    $(".nb-comment-highlight.selected").removeClass("selected");
                    $(".nb-comment-highlight[id_item="+event.value+"]").addClass("selected");

                    var viewTop = $(window).scrollTop();
                    var viewBottom = viewTop + $(window).height() * 0.9;
                    var elementTop = $(".nb-comment-highlight[id_item="+event.value+"]").offset().top;

                    if (viewTop > elementTop || viewBottom < elementTop) {

                        $("body, html").animate({scrollTop: $(".nb-comment-highlight[id_item="+event.value+"]").offset().top - $(window).height() / 4});
                     }
                }
            },
            GLOB.html.id);

        rangy.init();

        $(window).scroll(function(evt){
                var timerID = _scrollTimerID;
                if (timerID !== null){
                    window.clearTimeout(timerID);
                    _scrollTimerID =  null;
                }
                timerID = window.setTimeout(function(){
                        $.concierge.logHistory("scrolling", ["s",$("html").scrollTop(),$(window).height(), _scrollCounter++, $("body").height(),$.concierge.get_state("file") ].join(","));
                    }, 300);
                _scrollTimerID =  timerID;
            });

        // Wrap elements with nb-comment-fresh which is then selected by jQuery and operated on properly;
        // the styled element must have an nb-comment-highlight class.
        cssApplier = rangy.createCssClassApplier("nb-comment-fresh", { normalize: true });

        // Make sure concierge won't steal our keys!
        $.concierge.keydown_block = false;

        // Global key-down monitor
        $(document).keydown(function(event) {
            // If there are no current drafts, we don't interfere.
            if ($(".nb-placeholder").length === 0) {
                return true;
            }

            // If we are currently interacting with an input, button, or textarea, we don't interfere.
            if (document.activeElement.nodeType === "INPUT" ||
                document.activeElement.nodeType === "BUTTON" ||
                document.activeElement.nodeType === "TEXTAREA") {
                return true;
            }

            // If certain key combinations are being pressed, do not interfere.
            if (event.altKey === true || event.ctrlKey === true) {
                return true;
            }

            // If the key is an escape, we discard the draft if it is empty
            if (event.keyCode === 27) {
                $.concierge.trigger({ type: "discard_if_empty", value: {}});
                return true;
            }

            // If the key is not a chracter, do not interfere.
            if (event.keyCode < 48 ||
               (event.keyCode > 90 && event.keyCoe < 96) ||
               (event.keyCode > 111 && event.keyCode < 186)) {
                return true;
            }

            // Keypress only has characters pressed, so we do not neet check for
            // arrow keys, or CTRL+C and other combinations
            $.concierge.trigger({ type: "focus_thread", value: {}});

        });

        // Initialize Highlighting Event
        $("body>*").not(".nb_sidebar").mouseup(function (event) {
                var sel = rangy.getSelection();

                if (sel.isCollapsed){
                    $.concierge.trigger({ type: "discard_if_empty", value: {}});
                    return;
                }

                if (sel.containsNode($(".nb_sidebar")[0], true)) {
                    $.concierge.trigger({ type: "discard_if_empty", value: {}});
                    return;
                }

                // must call before applyToRanges, otherwise sel is gone
                var element = event.target;

                if ($(element).hasClass("nb-comment-highlight")) {
                    element = ($(element).parents("*:not(.nb-comment-highlight)"))[0];
                }

                var range = sel.saveCharacterRanges(element);

                var target = getElementXPath(element);

                insertPlaceholderAnnotation(sel);

                if ( $(element).attr("data_char") === undefined) {
                    // we have a problem
                    $.L("Error: target does not have data_char attribute", element);
                }

                $.concierge.trigger({
                    type: "new_thread",
                    value: {
                        html5range:{
                            path1: target,
                            path2: range[0].backward,
                            offset1: range[0].characterRange.start,
                            offset2: range[0].characterRange.end,
                            apparent_height: parseInt($(element).attr("data_char"), 10) +
                                Math.min(range[0].characterRange.start, range[0].characterRange.end)
                        },
                        suppressFocus: true
                    }
                });

                sel.restoreCharacterRanges(element, range);

            });

        GLOB.pers.store.register({
            update: function (action, payload, items_fieldname) {
                var key;

                if (items_fieldname === "draft") {
                    var draft;
                    for (draft in payload.diff) { break; }

                    if (action === "remove") {
                        $(".nb-comment-highlight.nb-placeholder[id_item=" + draft + "]").contents().unwrap();
                    } else if (action === "add") {
                        $(".nb-comment-highlight.nb-placeholder").attr("id_item", draft);
                    }

                }

                if (action === "remove" && items_fieldname === "location") {
                    for (key in payload.diff) {
                        $(".nb-comment-highlight[id_item=" + key + "]").contents().unwrap();
                    }
                }

                if (action === "add" && items_fieldname === "html5location") {
                    restoreBatch($.extend(true, {}, payload.diff), function(){ });
                }

        }}, {html5location: null, draft: null, location: null});

        // fix IE XPath implementation
        wgxpath.install();

    };

    // must be called only on inner-most element
    var hasConflicts = function (element) {
        return ($(element).parents(".nb-comment-highlight").length > 0);
    };

    // TODO: refactor such that there is more code re-use between placeAnnotation
    // on the one hand, and insert/activatePlaceholderAnnotation on the other.
    var placeAnnotation = function (selection, loc) {
        var uid = loc.id_location;

        // quit if annotation already placed
        if ($(".nb-comment-highlight[id_item=" + uid + "]").length > 0) {
            return;
        }

        // apply nb-comment-fresh to ranges
        cssApplier.applyToSelection(selection);
        selection.removeAllRanges();

        // jQuery Treatment
        $("span.nb-comment-fresh.nb-comment-highlight").removeClass("nb-comment-fresh").wrapInner('');
        $("span.nb-comment-fresh")
            .addClass("nb-comment-highlight")
            .removeClass("nb-comment-fresh")
            .attr("id_item", uid)
            .hover(
                function(){$.concierge.trigger({type:"note_hover", value: uid});},
                function(){$.concierge.trigger({type:"note_out", value: uid});})
            .click(
                function (event) {
                    if (!rangy.getSelection().isCollapsed){ return;}

                    if (hasConflicts(this)) {
                        var ids = [];
                        var id = 0;

                        ids.push($(this).attr("id_item"));

                        $(this).parents(".nb-comment-highlight").each(function () {
                                ids.push($(this).attr("id_item"));
                        });

                        if ($(lastClicked.set).not(ids).length === 0 && $(ids).not(lastClicked.set).length === 0) {
                            for (id = 0; id < ids.length; id++) {
                                if (ids[id] === lastClicked.clicked) { break; }
                            }
                            id = (id + 1) % ids.length;
                        }

                        $.concierge.trigger({type:"select_thread", value: ids[id]});
                        lastClicked = {set: ids, clicked: ids[id]};

                    } else {
                        $.concierge.trigger({type:"select_thread", value: uid});
                        lastClicked = {set: [uid], clicked: uid};
                    }
                    event.stopPropagation();
            });
    };

    var insertPlaceholderAnnotation = function (selection) {
        // apply nb-comment-fresh to ranges
        cssApplier.applyToSelection(selection);
        selection.removeAllRanges();

        // jQuery Treatment
        $("span.nb-comment-fresh.nb-comment-highlight").removeClass("nb-comment-fresh").wrapInner('');
        $("span.nb-comment-fresh")
            .addClass("nb-comment-highlight")
            .addClass("nb-placeholder")
            .removeClass("nb-comment-fresh")
            .attr("id_item", 0);

        // remove placeholder comment after 0.25 seconds if we do not receive a "draft created" event (i.e. the concierge
        // did not allow the creation of the draft). We check this by seeing if id_item is still 0.
        window.setTimeout(function() {
            $(".nb-placeholder[id_item=0]").contents().unwrap();
        }, 250);
    };

    GLOB.html.clearAnnotations = function () {
        $(".nb-comment-highlight").contents().unwrap();
    };

    var trim = function (text) {
        return text.replace(/^\s*|\s*$/g, "");
    };

    var trimLeft = function (text) {
        return text.replace(/^\s+/, "");
    };

    var trimRight = function (text) {
        return text.replace(/\s+$/, "");
    };

    // ************************************************************************************************
    // XPath

    /**
     * Gets an XPath for an element which describes its hierarchical location.
     */
    var getElementXPath = function (element) {
        if (element && element.id){
            return '//*[@id="' + element.id + '"]';
        }
        else{
            return getElementTreeXPath(element);
        }
    };

    var getElementTreeXPath = function (element) {
        var paths = [];

        // Use nodeName (instead of localName) so namespace prefix is included (if any).
        for (; element && element.nodeType === 1; element = element.parentNode) {
            var index = 0;
            var tagName, pathIndex, fullName;
            var terminate = false;

            if (element.id) {
                fullName = '/*[@id="' + element.id + '"]';
                terminate = true;
            } else {

                for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) {
                    // Ignore document type declaration.
                    if (sibling.nodeType === Node.DOCUMENT_TYPE_NODE){
                        continue;
                    }

                    if (sibling.nodeName === element.nodeName){
                        ++index;
                    }
                }

                tagName = element.nodeName.toLowerCase();
                pathIndex = (index ? "[" + (index + 1) + "]" : "");
                fullName = tagName + pathIndex;

            }

            paths.splice(0, 0, fullName);

            if (terminate) {
                break;
            }
        }

        return paths.length ? "/" + paths.join("/") : null;
    };

    var getElementsByXPath = function (doc, xpath) {
        var nodes = [];

        try {
            var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
            for (var item = result.iterateNext() ; item; item = result.iterateNext()){
                nodes.push(item);}
        }
        catch (exc) {
            // Invalid xpath expressions make their way here sometimes.  If that happens,
            // we still want to return an empty set without an exception.
        }

        return nodes;
    };

})(NB);
<commit_msg>fixed html scrolling bug<commit_after>/*global NB:true NB$:true $:true rangy:true alert:true wgxpath:true jQuery:true getElementCSSSelector:true console:true */
(function(GLOB){
    var _scrollTimerID=null;
    var _scrollCounter=0;
    if ("NB$" in window){
        var $ = NB$;
    }

    var $str        = "NB$" in window ? "NB$" : "jQuery";
    var cssApplier = null;
    var lastClicked = {set: [], clicked: null};

    var restore = function(loc) {
        var sel = rangy.getSelection();
        sel.restoreCharacterRanges(getElementsByXPath(document, loc.path1)[0],
                                   [{backward: loc.path2 === "true",
                                               characterRange: {
                                               start: loc.offset1,
                                               end: loc.offset2
                                           }
                                       }]);
        placeAnnotation(sel, loc);
    };

    var restoreBatch = function(object, callback) {
        var start = (new Date()).getTime();
        var current;

        for (var key in object) {
            current = (new Date()).getTime();
            if (current - start > 150) {
                window.setTimeout(restoreBatch, 10, object, callback);
                return;
            }

            restore(object[key]);
            delete object[key];
        }

        callback();
    };

    GLOB.html = {
        id: "docviewHtml5"
    };

    GLOB.html.init = function () {

        var countChildChars = function(_char, _this) {
            var char = _char;

            // count text nodes as well (includes whitespace)
            $(_this).contents().each(function() {
                  if (this.nodeType === 1) {
                      $(this).attr("data_char", char);
                      countChildChars(char, this);
                  }
                  char += ($(this).text()).length;
            });
        };

        countChildChars(0, $("body")[0]);

        $.concierge.addListeners(GLOB.html,{
                page: function(evt){
                   // _render();
                },
                note_hover: function(event){
                    $(".nb-comment-highlight[id_item="+event.value+"]").addClass("hovered");
                },
                note_out: function(event){
                    $(".nb-comment-highlight[id_item="+event.value+"]").removeClass("hovered");
                },
                visibility: function(event){
                    console.warn("TODO", event);
                },
                select_thread: function(event){
                    $(".nb-comment-highlight.selected").removeClass("selected");
                    $(".nb-comment-highlight[id_item="+event.value+"]").addClass("selected");

                    var viewTop = $(window).scrollTop();
                    // use window.innerHeight if available, else use document.body.clientHeight,
                    // else use documentElement.clientHeight
                    var viewBottom =
                        viewTop +
                        (window.innerHeight || document.body.clientHeight || window.document.documentElement.clientHeight) * 0.9;
                    var elementTop = $(".nb-comment-highlight[id_item="+event.value+"]").offset().top;

                    if (viewTop > elementTop || viewBottom < elementTop) {

                        $("body, html").animate({scrollTop: $(".nb-comment-highlight[id_item="+event.value+"]").offset().top - $(window).height() / 4});
                     }
                }
            },
            GLOB.html.id);

        rangy.init();

        $(window).scroll(function(evt){
                var timerID = _scrollTimerID;
                if (timerID !== null){
                    window.clearTimeout(timerID);
                    _scrollTimerID =  null;
                }
                timerID = window.setTimeout(function(){
                        $.concierge.logHistory("scrolling", ["s",$("html").scrollTop(),$(window).height(), _scrollCounter++, $("body").height(),$.concierge.get_state("file") ].join(","));
                    }, 300);
                _scrollTimerID =  timerID;
            });

        // Wrap elements with nb-comment-fresh which is then selected by jQuery and operated on properly;
        // the styled element must have an nb-comment-highlight class.
        cssApplier = rangy.createCssClassApplier("nb-comment-fresh", { normalize: true });

        // Make sure concierge won't steal our keys!
        $.concierge.keydown_block = false;

        // Global key-down monitor
        $(document).keydown(function(event) {
            // If there are no current drafts, we don't interfere.
            if ($(".nb-placeholder").length === 0) {
                return true;
            }

            // If we are currently interacting with an input, button, or textarea, we don't interfere.
            if (document.activeElement.nodeType === "INPUT" ||
                document.activeElement.nodeType === "BUTTON" ||
                document.activeElement.nodeType === "TEXTAREA") {
                return true;
            }

            // If certain key combinations are being pressed, do not interfere.
            if (event.altKey === true || event.ctrlKey === true) {
                return true;
            }

            // If the key is an escape, we discard the draft if it is empty
            if (event.keyCode === 27) {
                $.concierge.trigger({ type: "discard_if_empty", value: {}});
                return true;
            }

            // If the key is not a chracter, do not interfere.
            if (event.keyCode < 48 ||
               (event.keyCode > 90 && event.keyCoe < 96) ||
               (event.keyCode > 111 && event.keyCode < 186)) {
                return true;
            }

            // Keypress only has characters pressed, so we do not neet check for
            // arrow keys, or CTRL+C and other combinations
            $.concierge.trigger({ type: "focus_thread", value: {}});

        });

        // Initialize Highlighting Event
        $("body>*").not(".nb_sidebar").mouseup(function (event) {
                var sel = rangy.getSelection();

                if (sel.isCollapsed){
                    $.concierge.trigger({ type: "discard_if_empty", value: {}});
                    return;
                }

                if (sel.containsNode($(".nb_sidebar")[0], true)) {
                    $.concierge.trigger({ type: "discard_if_empty", value: {}});
                    return;
                }

                // must call before applyToRanges, otherwise sel is gone
                var element = event.target;

                if ($(element).hasClass("nb-comment-highlight")) {
                    element = ($(element).parents("*:not(.nb-comment-highlight)"))[0];
                }

                var range = sel.saveCharacterRanges(element);

                var target = getElementXPath(element);

                insertPlaceholderAnnotation(sel);

                if ( $(element).attr("data_char") === undefined) {
                    // we have a problem
                    $.L("Error: target does not have data_char attribute", element);
                }

                $.concierge.trigger({
                    type: "new_thread",
                    value: {
                        html5range:{
                            path1: target,
                            path2: range[0].backward,
                            offset1: range[0].characterRange.start,
                            offset2: range[0].characterRange.end,
                            apparent_height: parseInt($(element).attr("data_char"), 10) +
                                Math.min(range[0].characterRange.start, range[0].characterRange.end)
                        },
                        suppressFocus: true
                    }
                });

                sel.restoreCharacterRanges(element, range);

            });

        GLOB.pers.store.register({
            update: function (action, payload, items_fieldname) {
                var key;

                if (items_fieldname === "draft") {
                    var draft;
                    for (draft in payload.diff) { break; }

                    if (action === "remove") {
                        $(".nb-comment-highlight.nb-placeholder[id_item=" + draft + "]").contents().unwrap();
                    } else if (action === "add") {
                        $(".nb-comment-highlight.nb-placeholder").attr("id_item", draft);
                    }

                }

                if (action === "remove" && items_fieldname === "location") {
                    for (key in payload.diff) {
                        $(".nb-comment-highlight[id_item=" + key + "]").contents().unwrap();
                    }
                }

                if (action === "add" && items_fieldname === "html5location") {
                    restoreBatch($.extend(true, {}, payload.diff), function(){ });
                }

        }}, {html5location: null, draft: null, location: null});

        // fix IE XPath implementation
        wgxpath.install();

    };

    // must be called only on inner-most element
    var hasConflicts = function (element) {
        return ($(element).parents(".nb-comment-highlight").length > 0);
    };

    // TODO: refactor such that there is more code re-use between placeAnnotation
    // on the one hand, and insert/activatePlaceholderAnnotation on the other.
    var placeAnnotation = function (selection, loc) {
        var uid = loc.id_location;

        // quit if annotation already placed
        if ($(".nb-comment-highlight[id_item=" + uid + "]").length > 0) {
            return;
        }

        // apply nb-comment-fresh to ranges
        cssApplier.applyToSelection(selection);
        selection.removeAllRanges();

        // jQuery Treatment
        $("span.nb-comment-fresh.nb-comment-highlight").removeClass("nb-comment-fresh").wrapInner('');
        $("span.nb-comment-fresh")
            .addClass("nb-comment-highlight")
            .removeClass("nb-comment-fresh")
            .attr("id_item", uid)
            .hover(
                function(){$.concierge.trigger({type:"note_hover", value: uid});},
                function(){$.concierge.trigger({type:"note_out", value: uid});})
            .click(
                function (event) {
                    if (!rangy.getSelection().isCollapsed){ return;}

                    if (hasConflicts(this)) {
                        var ids = [];
                        var id = 0;

                        ids.push($(this).attr("id_item"));

                        $(this).parents(".nb-comment-highlight").each(function () {
                                ids.push($(this).attr("id_item"));
                        });

                        if ($(lastClicked.set).not(ids).length === 0 && $(ids).not(lastClicked.set).length === 0) {
                            for (id = 0; id < ids.length; id++) {
                                if (ids[id] === lastClicked.clicked) { break; }
                            }
                            id = (id + 1) % ids.length;
                        }

                        $.concierge.trigger({type:"select_thread", value: ids[id]});
                        lastClicked = {set: ids, clicked: ids[id]};

                    } else {
                        $.concierge.trigger({type:"select_thread", value: uid});
                        lastClicked = {set: [uid], clicked: uid};
                    }
                    event.stopPropagation();
            });
    };

    var insertPlaceholderAnnotation = function (selection) {
        // apply nb-comment-fresh to ranges
        cssApplier.applyToSelection(selection);
        selection.removeAllRanges();

        // jQuery Treatment
        $("span.nb-comment-fresh.nb-comment-highlight").removeClass("nb-comment-fresh").wrapInner('');
        $("span.nb-comment-fresh")
            .addClass("nb-comment-highlight")
            .addClass("nb-placeholder")
            .removeClass("nb-comment-fresh")
            .attr("id_item", 0);

        // remove placeholder comment after 0.25 seconds if we do not receive a "draft created" event (i.e. the concierge
        // did not allow the creation of the draft). We check this by seeing if id_item is still 0.
        window.setTimeout(function() {
            $(".nb-placeholder[id_item=0]").contents().unwrap();
        }, 250);
    };

    GLOB.html.clearAnnotations = function () {
        $(".nb-comment-highlight").contents().unwrap();
    };

    var trim = function (text) {
        return text.replace(/^\s*|\s*$/g, "");
    };

    var trimLeft = function (text) {
        return text.replace(/^\s+/, "");
    };

    var trimRight = function (text) {
        return text.replace(/\s+$/, "");
    };

    // ************************************************************************************************
    // XPath

    /**
     * Gets an XPath for an element which describes its hierarchical location.
     */
    var getElementXPath = function (element) {
        if (element && element.id){
            return '//*[@id="' + element.id + '"]';
        }
        else{
            return getElementTreeXPath(element);
        }
    };

    var getElementTreeXPath = function (element) {
        var paths = [];

        // Use nodeName (instead of localName) so namespace prefix is included (if any).
        for (; element && element.nodeType === 1; element = element.parentNode) {
            var index = 0;
            var tagName, pathIndex, fullName;
            var terminate = false;

            if (element.id) {
                fullName = '/*[@id="' + element.id + '"]';
                terminate = true;
            } else {

                for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) {
                    // Ignore document type declaration.
                    if (sibling.nodeType === Node.DOCUMENT_TYPE_NODE){
                        continue;
                    }

                    if (sibling.nodeName === element.nodeName){
                        ++index;
                    }
                }

                tagName = element.nodeName.toLowerCase();
                pathIndex = (index ? "[" + (index + 1) + "]" : "");
                fullName = tagName + pathIndex;

            }

            paths.splice(0, 0, fullName);

            if (terminate) {
                break;
            }
        }

        return paths.length ? "/" + paths.join("/") : null;
    };

    var getElementsByXPath = function (doc, xpath) {
        var nodes = [];

        try {
            var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
            for (var item = result.iterateNext() ; item; item = result.iterateNext()){
                nodes.push(item);}
        }
        catch (exc) {
            // Invalid xpath expressions make their way here sometimes.  If that happens,
            // we still want to return an empty set without an exception.
        }

        return nodes;
    };

})(NB);
<|endoftext|>


<commit_before>const oauth2orize = require('oauth2orize');
const passport = require('passport');
const login = require('connect-ensure-login');
const path = require('path');

const services = require('../../services/index');
const config = require('../../config');
const tokenService = services.token;
const authCodeService = services.authorizationCode;
const authService = services.auth;

const expiresIn = config.systemConfig.accessTokens.timeToExpiry / 1000;

// Create OAuth 2.0 server
const server = oauth2orize.createServer();

// Register serialialization and deserialization functions.
//
// When a client redirects a user to user authorization endpoint, an
// authorization transaction is initiated. To complete the transaction, the
// user must authenticate and approve the authorization request. Because this
// may involve multiple HTTP request/response exchanges, the transaction is
// stored in the session.
//
// An application must supply serialization functions, which determine how the
// client object is serialized into the session. Typically this will be a
// simple matter of serializing the client's ID, and deserializing by finding
// the client by ID from the database.

server.serializeClient((consumer, done) => done(null, consumer));

server.deserializeClient((consumer, done) => {
  const id = consumer.id;

  return authService.validateConsumer(id)
    .then(foundConsumer => {
      if (!foundConsumer) return done(null, false);
      return done(null, consumer);
    })
    .catch(done);
});

// Register supported grant types.
//
// OAuth 2.0 specifies a framework that allows users to grant client
// applications limited access to their protected resources. It does this
// through a process of the user granting access, and the client exchanging
// the grant for an access token.

// Grant authorization codes. The callback takes the `client` requesting
// authorization, the `redirectUri` (which is used as a verifier in the
// subsequent exchange), the authenticated `user` granting access, and
// their response, which contains approved scope, duration, etc. as parsed by
// the application. The application issues a code, which is bound to these
// values, and will be exchanged for an access token.

server.grant(oauth2orize.grant.code((consumer, redirectUri, user, ares, done) => {
  const code = {
    consumerId: consumer.id,
    redirectUri: redirectUri,
    userId: user.id
  };

  if (consumer.authorizedScopes) code.scopes = consumer.authorizedScopes;

  return authCodeService.save(code)
    .then((codeObj) => {
      return done(null, codeObj.id);
    })
    .catch(done);
}));

// Grant implicit authorization. The callback takes the `client` requesting
// authorization, the authenticated `user` granting access, and
// their response, which contains approved scope, duration, etc. as parsed by
// the application. The application issues a token, which is bound to these
// values.

server.grant(oauth2orize.grant.token((consumer, authenticatedUser, ares, done) => {
  const tokenCriteria = {
    consumerId: consumer.id,
    authenticatedUserId: authenticatedUser.id,
    redirectUri: consumer.redirectUri,
    authType: 'oauth2'
  };

  if (consumer.authorizedScopes) tokenCriteria.scopes = consumer.authorizedScopes;

  return tokenService.findOrSave(tokenCriteria)
    .then(token => {
      return done(null, token.access_token);
    })
    .catch(done);
}));

// Exchange authorization codes for access tokens. The callback accepts the
// `client`, which is exchanging `code` and any `redirectUri` from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the user who authorized the
// code.

server.exchange(oauth2orize.exchange.code((consumer, code, redirectUri, done) => {
  const codeCriteria = {
    id: code,
    consumerId: consumer.id,
    redirectUri: redirectUri
  };

  authCodeService.find(codeCriteria)
    .then(codeObj => {
      if (!codeObj) {
        return done(null, false);
      }

      const tokenCriteria = {
        consumerId: consumer.id,
        authenticatedUserId: codeObj.userId,
        authType: 'oauth2'
      };

      if (codeObj.scopes) tokenCriteria.scopes = codeObj.scopes;

      if (config.systemConfig.accessTokens.tokenType === 'jwt') {
        return tokenService
          .createJWT({ consumerId: consumer.id, scopes: codeObj.scopes })
          .then(res => done(null, res))
          .catch(done);
      }

      return tokenService.findOrSave(tokenCriteria, { includeRefreshToken: true })
        .then(token => done(null, token.access_token, token.refresh_token, { expires_in: expiresIn }));
    })
    .catch(done);
}));

// Exchange user id and password for access tokens. The callback accepts the
// `client`, which is exchanging the user's name and password from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the user who authorized the code.

server.exchange(oauth2orize.exchange.password((consumer, username, password, scopes, done) => {
  // Validate the consumer
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      if (!consumer) return done(null, false);

      return authService.authenticateCredential(username, password, 'basic-auth')
        .then(user => {
          if (!user) return done(null, false);

          return Promise.all([user, scopes ? authService.authorizeCredential(consumer.id, 'oauth2', scopes) : true]);
        })
        .then(([user, authorized]) => {
          if (!authorized) return done(null, false);

          const tokenCriteria = {
            consumerId: consumer.id,
            authenticatedUser: user.id
          };

          if (scopes) tokenCriteria.scopes = scopes;

          if (config.systemConfig.accessTokens.tokenType === 'jwt') {
            return tokenService
              .createJWT({ consumerId: consumer.id, scopes })
              .then(res => done(null, res))
              .catch(done);
          }

          return tokenService.findOrSave(tokenCriteria, { includeRefreshToken: true })
            .then(token => done(null, token.access_token, token.refresh_token, { expires_in: expiresIn }));
        })
        .catch(done);
    });
}));

// Exchange the client id and password/secret for an access token. The callback accepts the
// `client`, which is exchanging the client's id and password/secret from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the client who authorized the code.

server.exchange(oauth2orize.exchange.clientCredentials((consumer, scopes, done) => {
  // Validate the client
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      let scopeAuthorizationPromise;

      if (!consumer) return done(null, false);

      if (scopes) {
        scopeAuthorizationPromise = authService.authorizeCredential(consumer.id, 'oauth2', scopes);
      } else scopeAuthorizationPromise = Promise.resolve(true);

      return scopeAuthorizationPromise;
    })
    .then(authorized => {
      if (!authorized) return done(null, false);

      const tokenCriteria = {
        consumerId: consumer.id,
        authType: 'oauth2'
      };

      if (scopes) tokenCriteria.scopes = scopes;

      if (config.systemConfig.accessTokens.tokenType === 'jwt') {
        return tokenService
          .createJWT({ consumerId: consumer.id, scopes })
          .then(res => done(null, res))
          .catch(done);
      }

      return tokenService.findOrSave(tokenCriteria)
        .then(token => done(null, token.access_token, null));
    })
    .catch(done);
}));

// Exchange Refresh Token
server.exchange(oauth2orize.exchange.refreshToken(function (consumer, refreshToken, done) {
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      if (!consumer) {
        return done(null, false);
      }

      return tokenService.getTokenObject(refreshToken);
    })
    .then(tokenObj => {
      if (!tokenObj) {
        return done(null, false);
      }

      return tokenService.findOrSave(tokenObj)
        .then(token => done(null, token.access_token, null, { expires_in: expiresIn }));
    })
    .catch(done);
}));

// User authorization endpoint.
//
// `authorization` middleware accepts a `validate` callback which is
// responsible for validating the client making the authorization request. In
// doing so, is recommended that the `redirectUri` be checked against a
// registered value, although security requirements may vary accross
// implementations. Once validated, the `done` callback must be invoked with
// a `client` instance, as well as the `redirectUri` to which the user will be
// redirected after an authorization decision is obtained.
//
// This middleware simply initializes a new authorization transaction. It is
// the application's responsibility to authenticate the user and render a dialog
// to obtain their approval (displaying details about the client requesting
// authorization). We accomplish that here by routing through `ensureLoggedIn()`
// first, and rendering the `dialog` view.

module.exports.authorization = [
  login.ensureLoggedIn(),
  server.authorization((req, done) => {
    return authService.validateConsumer(req.clientID)
      .then(consumer => {
        if (!consumer || consumer.redirectUri !== req.redirectURI) return done(null, false);

        if (!req.scope) {
          return done(null, consumer, req.redirectURI);
        }

        return authService.authorizeCredential(req.clientID, 'oauth2', req.scope)
          .then(authorized => {
            if (!authorized) {
              return done(null, false);
            }

            consumer.authorizedScopes = req.scope;

            return done(null, consumer, req.redirectURI);
          });
      }).catch(done);
  }),
  (request, response) => {
    response.set('transaction_id', request.oauth2.transactionID);
    response.render(path.join(__dirname, 'views/dialog'), { transactionId: request.oauth2.transactionID, user: request.user, client: request.oauth2.client });
  }
];

// User decision endpoint.
//
// `decision` middleware processes a user's decision to allow or deny access
// requested by a client application. Based on the grant type requested by the
// client, the above grant middleware configured above will be invoked to send
// a response.

exports.decision = [
  login.ensureLoggedIn(),
  server.decision()
];

// Token endpoint.
//
// `token` middleware handles client requests to exchange authorization grants
// for access tokens. Based on the grant type being exchanged, the above
// exchange middleware will be invoked to handle the request. Clients must
// authenticate when making requests to this endpoint.

exports.token = [
  passport.authenticate(['basic', 'oauth2-client-password'], { session: false }),
  server.token(),
  server.errorHandler()
];
<commit_msg>Add expires in property in client flow<commit_after>const oauth2orize = require('oauth2orize');
const passport = require('passport');
const login = require('connect-ensure-login');
const path = require('path');

const services = require('../../services/index');
const config = require('../../config');
const tokenService = services.token;
const authCodeService = services.authorizationCode;
const authService = services.auth;

const expiresIn = config.systemConfig.accessTokens.timeToExpiry / 1000;

// Create OAuth 2.0 server
const server = oauth2orize.createServer();

// Register serialialization and deserialization functions.
//
// When a client redirects a user to user authorization endpoint, an
// authorization transaction is initiated. To complete the transaction, the
// user must authenticate and approve the authorization request. Because this
// may involve multiple HTTP request/response exchanges, the transaction is
// stored in the session.
//
// An application must supply serialization functions, which determine how the
// client object is serialized into the session. Typically this will be a
// simple matter of serializing the client's ID, and deserializing by finding
// the client by ID from the database.

server.serializeClient((consumer, done) => done(null, consumer));

server.deserializeClient((consumer, done) => {
  const id = consumer.id;

  return authService.validateConsumer(id)
    .then(foundConsumer => {
      if (!foundConsumer) return done(null, false);
      return done(null, consumer);
    })
    .catch(done);
});

// Register supported grant types.
//
// OAuth 2.0 specifies a framework that allows users to grant client
// applications limited access to their protected resources. It does this
// through a process of the user granting access, and the client exchanging
// the grant for an access token.

// Grant authorization codes. The callback takes the `client` requesting
// authorization, the `redirectUri` (which is used as a verifier in the
// subsequent exchange), the authenticated `user` granting access, and
// their response, which contains approved scope, duration, etc. as parsed by
// the application. The application issues a code, which is bound to these
// values, and will be exchanged for an access token.

server.grant(oauth2orize.grant.code((consumer, redirectUri, user, ares, done) => {
  const code = {
    consumerId: consumer.id,
    redirectUri: redirectUri,
    userId: user.id
  };

  if (consumer.authorizedScopes) code.scopes = consumer.authorizedScopes;

  return authCodeService.save(code)
    .then((codeObj) => {
      return done(null, codeObj.id);
    })
    .catch(done);
}));

// Grant implicit authorization. The callback takes the `client` requesting
// authorization, the authenticated `user` granting access, and
// their response, which contains approved scope, duration, etc. as parsed by
// the application. The application issues a token, which is bound to these
// values.

server.grant(oauth2orize.grant.token((consumer, authenticatedUser, ares, done) => {
  const tokenCriteria = {
    consumerId: consumer.id,
    authenticatedUserId: authenticatedUser.id,
    redirectUri: consumer.redirectUri,
    authType: 'oauth2'
  };

  if (consumer.authorizedScopes) tokenCriteria.scopes = consumer.authorizedScopes;

  return tokenService.findOrSave(tokenCriteria)
    .then(token => {
      return done(null, token.access_token);
    })
    .catch(done);
}));

// Exchange authorization codes for access tokens. The callback accepts the
// `client`, which is exchanging `code` and any `redirectUri` from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the user who authorized the
// code.

server.exchange(oauth2orize.exchange.code((consumer, code, redirectUri, done) => {
  const codeCriteria = {
    id: code,
    consumerId: consumer.id,
    redirectUri: redirectUri
  };

  authCodeService.find(codeCriteria)
    .then(codeObj => {
      if (!codeObj) {
        return done(null, false);
      }

      const tokenCriteria = {
        consumerId: consumer.id,
        authenticatedUserId: codeObj.userId,
        authType: 'oauth2'
      };

      if (codeObj.scopes) tokenCriteria.scopes = codeObj.scopes;

      if (config.systemConfig.accessTokens.tokenType === 'jwt') {
        return tokenService
          .createJWT({ consumerId: consumer.id, scopes: codeObj.scopes })
          .then(res => done(null, res))
          .catch(done);
      }

      return tokenService.findOrSave(tokenCriteria, { includeRefreshToken: true })
        .then(token => done(null, token.access_token, token.refresh_token, { expires_in: expiresIn }));
    })
    .catch(done);
}));

// Exchange user id and password for access tokens. The callback accepts the
// `client`, which is exchanging the user's name and password from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the user who authorized the code.

server.exchange(oauth2orize.exchange.password((consumer, username, password, scopes, done) => {
  // Validate the consumer
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      if (!consumer) return done(null, false);

      return authService.authenticateCredential(username, password, 'basic-auth')
        .then(user => {
          if (!user) return done(null, false);

          return Promise.all([user, scopes ? authService.authorizeCredential(consumer.id, 'oauth2', scopes) : true]);
        })
        .then(([user, authorized]) => {
          if (!authorized) return done(null, false);

          const tokenCriteria = {
            consumerId: consumer.id,
            authenticatedUser: user.id
          };

          if (scopes) tokenCriteria.scopes = scopes;

          if (config.systemConfig.accessTokens.tokenType === 'jwt') {
            return tokenService
              .createJWT({ consumerId: consumer.id, scopes })
              .then(res => done(null, res))
              .catch(done);
          }

          return tokenService.findOrSave(tokenCriteria, { includeRefreshToken: true })
            .then(token => done(null, token.access_token, token.refresh_token, { expires_in: expiresIn }));
        })
        .catch(done);
    });
}));

// Exchange the client id and password/secret for an access token. The callback accepts the
// `client`, which is exchanging the client's id and password/secret from the
// authorization request for verification. If these values are validated, the
// application issues an access token on behalf of the client who authorized the code.

server.exchange(oauth2orize.exchange.clientCredentials((consumer, scopes, done) => {
  // Validate the client
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      let scopeAuthorizationPromise;

      if (!consumer) return done(null, false);

      if (scopes) {
        scopeAuthorizationPromise = authService.authorizeCredential(consumer.id, 'oauth2', scopes);
      } else scopeAuthorizationPromise = Promise.resolve(true);

      return scopeAuthorizationPromise;
    })
    .then(authorized => {
      if (!authorized) return done(null, false);

      const tokenCriteria = {
        consumerId: consumer.id,
        authType: 'oauth2'
      };

      if (scopes) tokenCriteria.scopes = scopes;

      if (config.systemConfig.accessTokens.tokenType === 'jwt') {
        return tokenService
          .createJWT({ consumerId: consumer.id, scopes })
          .then(res => done(null, res))
          .catch(done);
      }

      return tokenService.findOrSave(tokenCriteria)
        .then(token => done(null, token.access_token, null, { expires_in: expiresIn }));
    })
    .catch(done);
}));

// Exchange Refresh Token
server.exchange(oauth2orize.exchange.refreshToken(function (consumer, refreshToken, done) {
  return authService.validateConsumer(consumer.id)
    .then(consumer => {
      if (!consumer) {
        return done(null, false);
      }

      return tokenService.getTokenObject(refreshToken);
    })
    .then(tokenObj => {
      if (!tokenObj) {
        return done(null, false);
      }

      return tokenService.findOrSave(tokenObj)
        .then(token => done(null, token.access_token, null, { expires_in: expiresIn }));
    })
    .catch(done);
}));

// User authorization endpoint.
//
// `authorization` middleware accepts a `validate` callback which is
// responsible for validating the client making the authorization request. In
// doing so, is recommended that the `redirectUri` be checked against a
// registered value, although security requirements may vary accross
// implementations. Once validated, the `done` callback must be invoked with
// a `client` instance, as well as the `redirectUri` to which the user will be
// redirected after an authorization decision is obtained.
//
// This middleware simply initializes a new authorization transaction. It is
// the application's responsibility to authenticate the user and render a dialog
// to obtain their approval (displaying details about the client requesting
// authorization). We accomplish that here by routing through `ensureLoggedIn()`
// first, and rendering the `dialog` view.

module.exports.authorization = [
  login.ensureLoggedIn(),
  server.authorization((req, done) => {
    return authService.validateConsumer(req.clientID)
      .then(consumer => {
        if (!consumer || consumer.redirectUri !== req.redirectURI) return done(null, false);

        if (!req.scope) {
          return done(null, consumer, req.redirectURI);
        }

        return authService.authorizeCredential(req.clientID, 'oauth2', req.scope)
          .then(authorized => {
            if (!authorized) {
              return done(null, false);
            }

            consumer.authorizedScopes = req.scope;

            return done(null, consumer, req.redirectURI);
          });
      }).catch(done);
  }),
  (request, response) => {
    response.set('transaction_id', request.oauth2.transactionID);
    response.render(path.join(__dirname, 'views/dialog'), { transactionId: request.oauth2.transactionID, user: request.user, client: request.oauth2.client });
  }
];

// User decision endpoint.
//
// `decision` middleware processes a user's decision to allow or deny access
// requested by a client application. Based on the grant type requested by the
// client, the above grant middleware configured above will be invoked to send
// a response.

exports.decision = [
  login.ensureLoggedIn(),
  server.decision()
];

// Token endpoint.
//
// `token` middleware handles client requests to exchange authorization grants
// for access tokens. Based on the grant type being exchanged, the above
// exchange middleware will be invoked to handle the request. Clients must
// authenticate when making requests to this endpoint.

exports.token = [
  passport.authenticate(['basic', 'oauth2-client-password'], { session: false }),
  server.token(),
  server.errorHandler()
];
<|endoftext|>


<commit_before>/*
 config object structure
 {
 "host": <string> shows the location of the webGME server //not really used by internally run interpreters = NUII,
 "project": <string> show the name of the project,
 "token": <string> authentication token for REST API //NUII,
 "selected": <string> gives the URL / path of the selected object , you can convert URL to path,
 "commit": <string> the hash / URL part of the selected commit, you can convert URL part to hash,
 "root": <string> the hash / URL of the root object, you can convert URL to hash,
 "branch": <string> the name of the selected branch
 }
 */
var requirejs = require("requirejs");
var program = require('commander');
var CONFIG = require('./config.json');

requirejs.config({
    nodeRequire: require,
    baseUrl: __dirname,
    paths: {
        //interpreters: 'interpreters'
    }
});

// TODO: get this from command line argument
program.option('-i, --interpreterPath <name>', 'Path to given interpreter.', './src/interpreters/CyPhyLight.CyPhy2Modelica/CyPhyLight.CyPhy2Modelica');
program.option('-s, --selectedObjID <webGMEID>', 'ID to selected component.', '/-1/-1/-3/-16');
program.parse(process.argv);
var interpreterName = program.interpreterPath;
//var interpreterName = './interpreters/DsmlApiGenerator/DsmlApiGenerator';
var selectedID = program.selectedObjID;
console.log('Given interpreter : %j', interpreterName);

// FIXME: dependency does matter!
requirejs([interpreterName, 'webgme'],
    function(Interpreter, WebGME){
        console.log(Interpreter);
        var Core = WebGME.core,
            Storage = WebGME.serverUserStorage;

        //somehow you should build up a config object for the interpreter
        //and get the name of the interpreter
        //now we start with a predefined ones

        var loadMetaNodes = function (context, callback) {

             // get meta members
            var metaIDs = context.core.getMemberPaths(context.rootNode, 'MetaAspectSet');

            var len = metaIDs.length;

            var nodeObjs = [];

            var allObjectsLoadedHandler = function () {
                var len2 = nodeObjs.length;

                var nameObjMap = {};

                while (len2--) {
                    var nodeObj = nodeObjs[len2];

                    nameObjMap[context.core.getAttribute(nodeObj, 'name')] = nodeObj;
                }

                context.META = nameObjMap;
                callback(null, context);
            };

            var loadedMetaObjectHandler = function (err, nodeObj) {
                nodeObjs.push(nodeObj);

                if (nodeObjs.length === metaIDs.length) {
                    allObjectsLoadedHandler();
                }
            };

            while (len--) {
                context.core.loadByPath(context.rootNode, metaIDs[len], loadedMetaObjectHandler);
            }
        };

        var getContext = function(config,callback) {
            var context = { storage: new Storage({'host':config.host, 'port':config.port, 'database':config.database})};
            context.storage.openDatabase(function(err){
                console.log('database is open');

                    if (!err) {
                        context.storage.openProject(config.project,function(err,project){
                            if(!err){
                                context.project = project;
                                context.projectName = config.project;
                                context.core = new Core(context.project,{corerel:2});
                                context.commitHash = config.commit;
                                context.selected = config.selected;

                                var loadCommitHashAndRun = function (commitHash) {
                                    context.project.loadObject(commitHash, function(err, commitObj) {
                                        if(!err && commitObj !== null && commitObj !== undefined){
                                            context.core.loadRoot(commitObj.root, function(err, rootNode) {
                                                if(!err){
                                                    context.rootNode = rootNode;
                                                    if(typeof context.selected === 'string'){
                                                        context.core.loadByPath(context.rootNode, context.selected, function (err, selectedNode) {
                                                            if(!err){
                                                                context.selectedNode = selectedNode;
                                                                loadMetaNodes(context, callback);
                                                            } else {
                                                                callback("unable to load selected object",context);
                                                            }
                                                        });
                                                    } else {
                                                        context.selectedNode = null;
                                                        loadMetaNodes(context, callback);
                                                    }
                                                } else {
                                                    callback("unable to load root",context);
                                                }
                                            });
                                        } else {
                                            callback('cannot find commit',context);
                                        }

                                    });
                                };

                                if (config.branchName) {
                                    context.project.getBranchNames(function (err, branchNames) {
                                        console.log(branchNames);
                                        if (branchNames.hasOwnProperty(config.branchName)) {
                                            context.commit = branchNames[config.branchName];
                                            console.log(context.commit);
                                            callback(null,context);
                                        } else {
                                            callback('cannot find branch',context);
                                        }
                                    });
                                } else {
                                    loadCommitHashAndRun(context.commitHash);
                                }

                            } else {
                                callback("cannot openproject",context);
                            }
                        });
                    } else {
                        callback("cannot open database",context);
                    }
            });
            console.log('is database already open');
        };

        // TODO: read from file or command line arguments
        var config = {
                "host": CONFIG.mongoip,
                "port": CONFIG.mongoport,
                "database": "multi",
                "project": "CyPhyLight",
                "token": "",
                "selected": selectedID,
                "commit": null, //"#668b3babcdf2ddcd7ba38b51acb62d63da859d90",
                //"root": ""
                "branchName": "master"
            };

        // callback for getContext
        function invokeInterpreterHandler(err, context){
            if (err) {
                console.log(err);
            } else {
                console.log(Interpreter);
                var interpreter = new Interpreter();
                var dataConfig = null;
                interpreter.doGUIConfig(null, function (interpreterConfig) {
                    if (interpreterConfig.dataSourcePath) {
                        dataConfig = require(interpreterConfig.dataSourcePath);
                    }
                });

                context.dataConfig = dataConfig;
                interpreter.run(context, function(result) {
                    console.log(result);
                });
            }
        }

        getContext(config, invokeInterpreterHandler);
    }
);<commit_msg>Fix run_interpreter if branch name is given.<commit_after>/*
 config object structure
 {
 "host": <string> shows the location of the webGME server //not really used by internally run interpreters = NUII,
 "project": <string> show the name of the project,
 "token": <string> authentication token for REST API //NUII,
 "selected": <string> gives the URL / path of the selected object , you can convert URL to path,
 "commit": <string> the hash / URL part of the selected commit, you can convert URL part to hash,
 "root": <string> the hash / URL of the root object, you can convert URL to hash,
 "branch": <string> the name of the selected branch
 }
 */
var requirejs = require("requirejs");
var program = require('commander');
var CONFIG = require('./config.json');

requirejs.config({
    nodeRequire: require,
    baseUrl: __dirname,
    paths: {
        //interpreters: 'interpreters'
    }
});

// TODO: get this from command line argument
program.option('-i, --interpreterPath <name>', 'Path to given interpreter.', './src/interpreters/CyPhyLight.CyPhy2Modelica/CyPhyLight.CyPhy2Modelica');
program.option('-s, --selectedObjID <webGMEID>', 'ID to selected component.', '/-1/-1/-3/-16');
program.parse(process.argv);
var interpreterName = program.interpreterPath;
//var interpreterName = './interpreters/DsmlApiGenerator/DsmlApiGenerator';
var selectedID = program.selectedObjID;
console.log('Given interpreter : %j', interpreterName);

// FIXME: dependency does matter!
requirejs([interpreterName, 'webgme'],
    function(Interpreter, WebGME){
        console.log(Interpreter);
        var Core = WebGME.core,
            Storage = WebGME.serverUserStorage;

        //somehow you should build up a config object for the interpreter
        //and get the name of the interpreter
        //now we start with a predefined ones

        var loadMetaNodes = function (context, callback) {

             // get meta members
            var metaIDs = context.core.getMemberPaths(context.rootNode, 'MetaAspectSet');

            var len = metaIDs.length;

            var nodeObjs = [];

            var allObjectsLoadedHandler = function () {
                var len2 = nodeObjs.length;

                var nameObjMap = {};

                while (len2--) {
                    var nodeObj = nodeObjs[len2];

                    nameObjMap[context.core.getAttribute(nodeObj, 'name')] = nodeObj;
                }

                context.META = nameObjMap;
                callback(null, context);
            };

            var loadedMetaObjectHandler = function (err, nodeObj) {
                nodeObjs.push(nodeObj);

                if (nodeObjs.length === metaIDs.length) {
                    allObjectsLoadedHandler();
                }
            };

            while (len--) {
                context.core.loadByPath(context.rootNode, metaIDs[len], loadedMetaObjectHandler);
            }
        };

        var getContext = function(config,callback) {
            var context = { storage: new Storage({'host':config.host, 'port':config.port, 'database':config.database})};
            context.storage.openDatabase(function(err){
                console.log('database is open');

                    if (!err) {
                        context.storage.openProject(config.project,function(err,project){
                            if(!err){
                                context.project = project;
                                context.projectName = config.project;
                                context.core = new Core(context.project,{corerel:2});
                                context.commitHash = config.commit;
                                context.selected = config.selected;

                                var loadCommitHashAndRun = function (commitHash) {
                                    context.project.loadObject(commitHash, function(err, commitObj) {
                                        if(!err && commitObj !== null && commitObj !== undefined){
                                            context.core.loadRoot(commitObj.root, function(err, rootNode) {
                                                if(!err){
                                                    context.rootNode = rootNode;
                                                    if(typeof context.selected === 'string'){
                                                        context.core.loadByPath(context.rootNode, context.selected, function (err, selectedNode) {
                                                            if(!err){
                                                                context.selectedNode = selectedNode;
                                                                loadMetaNodes(context, callback);
                                                            } else {
                                                                callback("unable to load selected object",context);
                                                            }
                                                        });
                                                    } else {
                                                        context.selectedNode = null;
                                                        loadMetaNodes(context, callback);
                                                    }
                                                } else {
                                                    callback("unable to load root",context);
                                                }
                                            });
                                        } else {
                                            callback('cannot find commit',context);
                                        }

                                    });
                                };

                                if (config.branchName) {
                                    context.project.getBranchNames(function (err, branchNames) {
                                        console.log(branchNames);
                                        if (branchNames.hasOwnProperty(config.branchName)) {
                                            context.commitHash = branchNames[config.branchName];
                                            console.log(context.commitHash);
                                            loadCommitHashAndRun(context.commitHash);
                                        } else {
                                            callback('cannot find branch',context);
                                        }
                                    });
                                } else {
                                    loadCommitHashAndRun(context.commitHash);
                                }

                            } else {
                                callback("cannot openproject",context);
                            }
                        });
                    } else {
                        callback("cannot open database",context);
                    }
            });
            console.log('is database already open');
        };

        // TODO: read from file or command line arguments
        var config = {
                "host": CONFIG.mongoip,
                "port": CONFIG.mongoport,
                "database": "multi",
                "project": "CyPhyLight",
                "token": "",
                "selected": selectedID,
                "commit": null, //"#668b3babcdf2ddcd7ba38b51acb62d63da859d90",
                //"root": ""
                "branchName": "master"
            };

        // callback for getContext
        function invokeInterpreterHandler(err, context){
            if (err) {
                console.log(err);
            } else {
                console.log(Interpreter);
                var interpreter = new Interpreter();
                var dataConfig = null;
                interpreter.doGUIConfig(null, function (interpreterConfig) {
                    if (interpreterConfig.dataSourcePath) {
                        dataConfig = require(interpreterConfig.dataSourcePath);
                    }
                });

                context.dataConfig = dataConfig;
                interpreter.run(context, function(result) {
                    console.log(result);
                });
            }
        }

        getContext(config, invokeInterpreterHandler);
    }
);<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 kishigo
 *
 * 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.
 */
class ThreeJSViewContainer extends React.Component {
    constructor () {
        super();
    }

    componentDidMount () {

    }
}<commit_msg>Remove unused file<commit_after><|endoftext|>


<commit_before>var dbc         = require('dbc');
var openiLogger = require('openi-logger')
var async       = require('async')
var HTTPStatus  = require('http-status');
var openiUtils   = require('openi-cloudlet-utils')

var couchbase   = require('couchbase')
var uuid        = require('uuid');

var conf        = require('./config.js');
var createViews = require('./couchbaseViews')
var zmq         = require('m2nodehandler')

var logger      = null;
var dbs         = {};

var init = function (logger_params) {
   logger = openiLogger(logger_params)

   dbs['openi'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'openi'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected openi bucket!');
      }
   });

   dbs['attachments'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'attachments'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected attachments bucket!');
      }
   });

   dbs['permissions'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'permissions'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected permissions bucket!');
      }
   });

   createViews(dbs['openi'], logger)

}

var getCouchbaseError = function(err, documentName, id){

   switch (err.code){
   case 4:
      return 'Object too big';
      break;
   case 13:
      return 'Entity with that id does not exist';
      break;
   case 12:
      if (0 === documentName.indexOf('t_')){
         return 'OPENi Type already exists (' + id + ').';
      }
      return 'Incorrect revision number provided';
      break;
   default:
      return "Reason unknown"
      break;
   }
}

var getDb = function(name){
   switch(name){
   case "attachments":
      return dbs['attachments']
   case "permissions":
      return dbs['permissions']
   default:
      return dbs['openi']
   }
}

var postAction = function (msg, callback) {

   var options = (undefined     === msg.format) ? {} : {format: msg.format }
   var db_use  = getDb(msg['bucket'])

   db_use.add(msg.database, msg.object_data, options, function (err, result) {
      if (err) {
         var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;
         callback(null,
            { 'error' : 'Error adding entity: ' + getCouchbaseError(err, msg.database, msg.id) },
            httpCode)
      }
      else {
         callback(null, { 'id' : msg.id }, HTTPStatus.CREATED)
      }
   })
}

var putAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      var revisionParts = msg.revision.split('-');

      if (db_body.cas['0'] != revisionParts[0] && db_body.cas['1'] != revisionParts[1]){
         callback(null, { 'error' : 'Entity already updated'},
            HTTPStatus.CONFLICT)
         return;
      }

      if (db_body.value.openi_type === msg.object_data.openi_type
            && db_body.cas['1'] != revisionParts[1]){
         callback(null, { 'error' : 'Entity already updated'},
            HTTPStatus.CONFLICT)
         return;
      }

      var options = (undefined === msg.format) ? {} : {format: msg.format }

      db_use.set(msg.database, msg.object_data, options, {cas: db_body.cas}, function (err,result) {

         if (err) {
            logger.log('error', err )

            var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;

            callback(null, { 'error' : 'Error updating entity: ' + getCouchbaseError(err) },
               httpCode)
         }
         else {
            callback(null, { 'id' : msg.id }, HTTPStatus.OK)
         }
      })
   })
}

var processGetData = function(db_body, msg){

   var headers = zmq.header_json

   var resp = {}

   switch(msg['resp_type']){
   case 'cloudlet':
      resp = openiUtils.cloudletHelper(db_body, msg)
      break;
   case 'binary':
      headers  = {'Content-Type': db_body.value["Content-Type"]}
      resp = new Buffer(db_body.value['file'], 'base64')
      break;
   case 'binary_meta':
      db_body.value['file'] = undefined
      resp = db_body.value
      break;
   case 'type':
      resp = openiUtils.typeHelper(db_body, msg)
      break;
   case 'object':
   default:
      resp = openiUtils.objectHelper(db_body, msg)
      break;
   }

   return {'headers':headers, 'resp':resp}
}

var getOrPostAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      if (err) {
         postAction(msg, function(a, b, c){
            if (c === HTTPStatus.CREATED && undefined !== msg.token){
               var key = msg.token.user + "-" + msg.object_data.id
               var permissions = {}
               //read, write, admin permissions
               permissions[msg.object_data.id] = 'rwa'

               getDb("permissions").add(key, permissions, function (err, result) {
                  if (err) {
                     var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;
                     callback(null,
                        { 'error' : 'Error adding entity: ' + getCouchbaseError(err, msg.database, msg.id) },
                        httpCode)
                  }
                  else {
                     callback(a, b, c)
                  }
               })
            }
            else{
               callback(a, b, c)
            }
         })
      }
      else {
         var response = processGetData(db_body, msg)

         callback(null, response.resp, HTTPStatus.OK, response.headers )
      }
   })

}

var getAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      if (err) {
         logger.log('error', err )
         callback(null, { 'error' : 'Error getting data from datastore' }, HTTPStatus.INTERNAL_SERVER_ERROR)
      }
      else {
         var response = processGetData(db_body, msg)

         callback(null, response.resp, HTTPStatus.OK, response.headers )
      }
   })

}

var viewAction = function (msg, callback) {

   msg.count    = (typeof msg.count !== 'number' || isNaN(msg.count) || msg.count > 30) ? 30 : msg.count;
   msg.skip     = (typeof msg.skip  !== 'number' || isNaN(msg.skip))                    ? 0  : msg.skip;
   msg.startkey = typeof msg.startkey !== 'string' ? "" : msg.startkey;

   var params = {
      startkey_docid : msg.startkey,
      skip           : msg.skip,
      stale          : false,
      limit          : msg.count
   }

   if (undefined !== msg.key){
      params.startkey = msg.key;
      params.endkey   = msg.key;
   }

   if ( undefined !== msg.group && msg.group ){
      params.group = msg.group
   }

   getDb('openi').view(msg.design_doc, msg.view_name, params).query(function(err, res)
   {
      var respObj = [];

      for (var i = 0; i < res.length; i++){

         if (msg.resp_type === 'type'){
            respObj[i] = openiUtils.typeHelper(res[i], msg)
         }
         else if (msg.resp_type === 'type_stats') {
            respObj[i] = openiUtils.typeStats(res[i], msg)
         }
         else if(msg.resp_type === 'cloudlet'){
            respObj[i] = openiUtils.cloudletHelper(res[i], msg)
         }
         else{
            respObj[i] = openiUtils.objectHelper(res[i], msg)
         }
      }

      callback(null,  respObj, HTTPStatus.OK)
   });

}

var fetchAction = function (msg, callback) {

   getDb('openi').get(msg.database, function (err, db_body) {

      if (err) {
         logger.log('error', err )
         callback(null,
            { 'error' : 'Error getting entity: ' + getCouchbaseError(err) },
               HTTPStatus.INTERNAL_SERVER_ERROR )
      }
      else {
         callback(null,  { 'data' : db_body }, HTTPStatus.OK)
      }
   })

}

var createDBAction = function(msg, callback ){

   getDb('openi').add(msg.database, {}, function(err, res)
	{

		if(err && err.code != 12)
		{
         //logger.log('error', err)
    	    callback(null,
             { 'error' : 'Error creating entity: ' + getCouchbaseError(err) },
             HTTPStatus.INTERNAL_SERVER_ERROR )
      }
      else
      {
        	logger.log('debug', 'Cloudlet created, id: ' + msg.database )
        	callback(null, { 'id' : msg.database }, HTTPStatus.OK)
      }
	});
}

var deleteDBAction = function( msg, callback ){

   getDb(msg['bucket']).remove(msg.database, function (err) {

      if (err){
         logger.log('error', err)
         callback(null, { 'error' : 'Error deleting entity : ' + getCouchbaseError(err) }, HTTPStatus.NOT_FOUND)
      }
      else{
         logger.log('debug', 'entity deleted, id: ' + msg.database )
         callback(null, { 'id' : msg.id }, HTTPStatus.OK)
      }
   })
}

var evaluateAction = function (msg, callback) {

   dbc.conditionalHasMember(msg, 'database', (msg.action !== 'VIEW') )
   dbc.hasMemberIn(         msg, 'action',      ['POST', 'PUT', 'GET', 'FETCH', 'CREATE', 'DELETE', 'VIEW', 'GET_OR_POST'])
   dbc.conditionalHasMember(msg, 'object_data', (msg.action === 'POST'   || msg.action === 'PUT'))
   dbc.conditionalHasMember(msg, 'revision',    (msg.action === 'PUT'))

   var resp_msg = ''

   switch (msg.action){
   case 'POST':
      resp_msg = postAction     (msg, callback)
      break;
   case 'PUT':
      resp_msg = putAction     (msg, callback)
      break;
   case 'GET':
      resp_msg = getAction     (msg, callback)
      break;
   case 'GET_OR_POST':
      resp_msg = getOrPostAction(msg, callback)
      break;
   case 'FETCH':
      resp_msg = fetchAction   (msg, callback)
      break;
   case 'CREATE':
      resp_msg = createDBAction(msg, callback)
      break;
   case 'DELETE':
      resp_msg = deleteDBAction(msg, callback)
      break;
   case 'VIEW':
      resp_msg = viewAction     (msg, callback)
      break;
   }
   return resp_msg;
}

var actionToFunction = function(action) {
   return ( function(action) {
      return function(callback){
         evaluateAction(action, callback)
      }
   }(action) )
}

var evaluateMessage = function (msg, myCallback) {

   dbc.hasMember(msg, 'dao_actions'  )
   dbc.hasMember(msg, 'clients'      )

   dbc.assert(msg.clients.length     > 0)
   dbc.assert(msg.dao_actions.length > 0)

   var arr = {}

   for ( var i = 0; i < msg.dao_actions.length; i++){

      var action = msg.dao_actions[i]
      arr[i]     = actionToFunction(action)

   }

   async.series(arr, function(err, results, httpStatusCode){
      myCallback(err, results, httpStatusCode)
   })

}

module.exports.init            = init
module.exports.evaluateMessage = evaluateMessage
<commit_msg>rearranged requires<commit_after>var dbc         = require('dbc');
var openiLogger = require('openi-logger')
var zmq         = require('m2nodehandler')
var openiUtils  = require('openi-cloudlet-utils')
var async       = require('async')
var HTTPStatus  = require('http-status');

var couchbase   = require('couchbase')
var uuid        = require('uuid');

var conf        = require('./config.js');
var createViews = require('./couchbaseViews')

var logger      = null;
var dbs         = {};

var init = function (logger_params) {
   logger = openiLogger(logger_params)

   dbs['openi'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'openi'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected openi bucket!');
      }
   });

   dbs['attachments'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'attachments'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected attachments bucket!');
      }
   });

   dbs['permissions'] = new couchbase.Connection({host: 'localhost:8091', bucket: 'permissions'}, function(err){
      if (err) {
         console.log('Connection Error', err);
      } else {
         console.log('Connected permissions bucket!');
      }
   });

   createViews(dbs['openi'], logger)

}

var getCouchbaseError = function(err, documentName, id){

   switch (err.code){
   case 4:
      return 'Object too big';
      break;
   case 13:
      return 'Entity with that id does not exist';
      break;
   case 12:
      if (0 === documentName.indexOf('t_')){
         return 'OPENi Type already exists (' + id + ').';
      }
      return 'Incorrect revision number provided';
      break;
   default:
      return "Reason unknown"
      break;
   }
}

var getDb = function(name){
   switch(name){
   case "attachments":
      return dbs['attachments']
   case "permissions":
      return dbs['permissions']
   default:
      return dbs['openi']
   }
}

var postAction = function (msg, callback) {

   var options = (undefined     === msg.format) ? {} : {format: msg.format }
   var db_use  = getDb(msg['bucket'])

   db_use.add(msg.database, msg.object_data, options, function (err, result) {
      if (err) {
         var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;
         callback(null,
            { 'error' : 'Error adding entity: ' + getCouchbaseError(err, msg.database, msg.id) },
            httpCode)
      }
      else {
         callback(null, { 'id' : msg.id }, HTTPStatus.CREATED)
      }
   })
}

var putAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      var revisionParts = msg.revision.split('-');

      if (db_body.cas['0'] != revisionParts[0] && db_body.cas['1'] != revisionParts[1]){
         callback(null, { 'error' : 'Entity already updated'},
            HTTPStatus.CONFLICT)
         return;
      }

      if (db_body.value.openi_type === msg.object_data.openi_type
            && db_body.cas['1'] != revisionParts[1]){
         callback(null, { 'error' : 'Entity already updated'},
            HTTPStatus.CONFLICT)
         return;
      }

      var options = (undefined === msg.format) ? {} : {format: msg.format }

      db_use.set(msg.database, msg.object_data, options, {cas: db_body.cas}, function (err,result) {

         if (err) {
            logger.log('error', err )

            var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;

            callback(null, { 'error' : 'Error updating entity: ' + getCouchbaseError(err) },
               httpCode)
         }
         else {
            callback(null, { 'id' : msg.id }, HTTPStatus.OK)
         }
      })
   })
}

var processGetData = function(db_body, msg){

   var headers = zmq.header_json

   var resp = {}

   switch(msg['resp_type']){
   case 'cloudlet':
      resp = openiUtils.cloudletHelper(db_body, msg)
      break;
   case 'binary':
      headers  = {'Content-Type': db_body.value["Content-Type"]}
      resp = new Buffer(db_body.value['file'], 'base64')
      break;
   case 'binary_meta':
      db_body.value['file'] = undefined
      resp = db_body.value
      break;
   case 'type':
      resp = openiUtils.typeHelper(db_body, msg)
      break;
   case 'object':
   default:
      resp = openiUtils.objectHelper(db_body, msg)
      break;
   }

   return {'headers':headers, 'resp':resp}
}

var getOrPostAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      if (err) {
         postAction(msg, function(a, b, c){
            if (c === HTTPStatus.CREATED && undefined !== msg.token){
               var key = msg.token.user + "-" + msg.object_data.id
               var permissions = {}
               //read, write, admin permissions
               permissions[msg.object_data.id] = 'rwa'

               getDb("permissions").add(key, permissions, function (err, result) {
                  if (err) {
                     var httpCode = (12 === err.code) ? HTTPStatus.CONFLICT : HTTPStatus.INTERNAL_SERVER_ERROR;
                     callback(null,
                        { 'error' : 'Error adding entity: ' + getCouchbaseError(err, msg.database, msg.id) },
                        httpCode)
                  }
                  else {
                     callback(a, b, c)
                  }
               })
            }
            else{
               callback(a, b, c)
            }
         })
      }
      else {
         var response = processGetData(db_body, msg)

         callback(null, response.resp, HTTPStatus.OK, response.headers )
      }
   })

}

var getAction = function (msg, callback) {

   var db_use  = getDb(msg['bucket'])

   db_use.get(msg.database, function (err, db_body) {

      if (err) {
         logger.log('error', err )
         callback(null, { 'error' : 'Error getting data from datastore' }, HTTPStatus.INTERNAL_SERVER_ERROR)
      }
      else {
         var response = processGetData(db_body, msg)

         callback(null, response.resp, HTTPStatus.OK, response.headers )
      }
   })

}

var viewAction = function (msg, callback) {

   msg.count    = (typeof msg.count !== 'number' || isNaN(msg.count) || msg.count > 30) ? 30 : msg.count;
   msg.skip     = (typeof msg.skip  !== 'number' || isNaN(msg.skip))                    ? 0  : msg.skip;
   msg.startkey = typeof msg.startkey !== 'string' ? "" : msg.startkey;

   var params = {
      startkey_docid : msg.startkey,
      skip           : msg.skip,
      stale          : false,
      limit          : msg.count
   }

   if (undefined !== msg.key){
      params.startkey = msg.key;
      params.endkey   = msg.key;
   }

   if ( undefined !== msg.group && msg.group ){
      params.group = msg.group
   }

   getDb('openi').view(msg.design_doc, msg.view_name, params).query(function(err, res)
   {
      var respObj = [];

      for (var i = 0; i < res.length; i++){

         if (msg.resp_type === 'type'){
            respObj[i] = openiUtils.typeHelper(res[i], msg)
         }
         else if (msg.resp_type === 'type_stats') {
            respObj[i] = openiUtils.typeStats(res[i], msg)
         }
         else if(msg.resp_type === 'cloudlet'){
            respObj[i] = openiUtils.cloudletHelper(res[i], msg)
         }
         else{
            respObj[i] = openiUtils.objectHelper(res[i], msg)
         }
      }

      callback(null,  respObj, HTTPStatus.OK)
   });

}

var fetchAction = function (msg, callback) {

   getDb('openi').get(msg.database, function (err, db_body) {

      if (err) {
         logger.log('error', err )
         callback(null,
            { 'error' : 'Error getting entity: ' + getCouchbaseError(err) },
               HTTPStatus.INTERNAL_SERVER_ERROR )
      }
      else {
         callback(null,  { 'data' : db_body }, HTTPStatus.OK)
      }
   })

}

var createDBAction = function(msg, callback ){

   getDb('openi').add(msg.database, {}, function(err, res)
	{

		if(err && err.code != 12)
		{
         //logger.log('error', err)
    	    callback(null,
             { 'error' : 'Error creating entity: ' + getCouchbaseError(err) },
             HTTPStatus.INTERNAL_SERVER_ERROR )
      }
      else
      {
        	logger.log('debug', 'Cloudlet created, id: ' + msg.database )
        	callback(null, { 'id' : msg.database }, HTTPStatus.OK)
      }
	});
}

var deleteDBAction = function( msg, callback ){

   getDb(msg['bucket']).remove(msg.database, function (err) {

      if (err){
         logger.log('error', err)
         callback(null, { 'error' : 'Error deleting entity : ' + getCouchbaseError(err) }, HTTPStatus.NOT_FOUND)
      }
      else{
         logger.log('debug', 'entity deleted, id: ' + msg.database )
         callback(null, { 'id' : msg.id }, HTTPStatus.OK)
      }
   })
}

var evaluateAction = function (msg, callback) {

   dbc.conditionalHasMember(msg, 'database', (msg.action !== 'VIEW') )
   dbc.hasMemberIn(         msg, 'action',      ['POST', 'PUT', 'GET', 'FETCH', 'CREATE', 'DELETE', 'VIEW', 'GET_OR_POST'])
   dbc.conditionalHasMember(msg, 'object_data', (msg.action === 'POST'   || msg.action === 'PUT'))
   dbc.conditionalHasMember(msg, 'revision',    (msg.action === 'PUT'))

   var resp_msg = ''

   switch (msg.action){
   case 'POST':
      resp_msg = postAction     (msg, callback)
      break;
   case 'PUT':
      resp_msg = putAction     (msg, callback)
      break;
   case 'GET':
      resp_msg = getAction     (msg, callback)
      break;
   case 'GET_OR_POST':
      resp_msg = getOrPostAction(msg, callback)
      break;
   case 'FETCH':
      resp_msg = fetchAction   (msg, callback)
      break;
   case 'CREATE':
      resp_msg = createDBAction(msg, callback)
      break;
   case 'DELETE':
      resp_msg = deleteDBAction(msg, callback)
      break;
   case 'VIEW':
      resp_msg = viewAction     (msg, callback)
      break;
   }
   return resp_msg;
}

var actionToFunction = function(action) {
   return ( function(action) {
      return function(callback){
         evaluateAction(action, callback)
      }
   }(action) )
}

var evaluateMessage = function (msg, myCallback) {

   dbc.hasMember(msg, 'dao_actions'  )
   dbc.hasMember(msg, 'clients'      )

   dbc.assert(msg.clients.length     > 0)
   dbc.assert(msg.dao_actions.length > 0)

   var arr = {}

   for ( var i = 0; i < msg.dao_actions.length; i++){

      var action = msg.dao_actions[i]
      arr[i]     = actionToFunction(action)

   }

   async.series(arr, function(err, results, httpStatusCode){
      myCallback(err, results, httpStatusCode)
   })

}

module.exports.init            = init
module.exports.evaluateMessage = evaluateMessage
<|endoftext|>