<commit_before>module.exports = function(grasshopper){
    "use strict";

    var node = {},
        async = require('async'),
        _ = require('underscore'),
        base = require('./api-base')(grasshopper);


    function userCanForNode(user, parentNodeId, minRole, callback){
        var isAllowed = _.find(user.permissions, function(permission){
            var userPrivLevel = base.AVAILABLE_PRIVILEGES[permission.role.toUpperCase()];
            return (permission.nodeid == parentNodeId &&  (userPrivLevel <= parseInt(minRole, 10)));
        });

        callback((!isAllowed) ? new Error("User does not have enough privileges.") : null);
    }

    function userPreventedForNode(user, parentNodeId, minRole, callback){
        var ruleIsSet = false,
            isAllowed = _.find(user.permissions, function(permission){
                var userPrivLevel = base.AVAILABLE_PRIVILEGES[permission.role.toUpperCase()];
                ruleIsSet = true;

                return (permission.nodeid == parentNodeId &&  (userPrivLevel <= parseInt(minRole, 10)));
            });

        callback((ruleIsSet && !isAllowed) ? new Error("User does not have enough privileges.") : null);
    }

    function userCan(token, minRole, parentNodeId, callback){

        async.waterfall([
            function(cb){
                grasshopper.users.getById(token.profile._id, function(err, obj){
                    var permissions = {
                        userPermission: false,
                        nodePermission: false,
                        nodeRestriction: true
                    };

                   cb(null, obj, permissions);
                });
            },
            function(user, permissions, cb){
                userCanForNode(user, parentNodeId, minRole, function(err){
                   permissions.nodePermission = (err == null);
                   cb(null, user, permissions);
                });
            },
            function(user, permissions, cb){
                userPreventedForNode(user, parentNodeId, minRole, function(err){
                    permissions.nodeRestriction = (err != null);
                    cb(null, user, permissions);
                });
            },
            function(user, permissions, cb){
                base.userCan(token, minRole, function(err){
                    permissions.userPermission = (err == null);
                    cb(null, user, permissions);
                });
            }
        ], function(err, user, permissions){
            var error = ((permissions.userPermission && !permissions.nodeRestriction) || permissions.nodePermission) ? null : new Error("User does not have  rights to perform this action.");
            callback(error);
        });
    }


     node.getById = function (req, res){
        base.authenticateRequest(req, res, function(token){

            userCan(token, base.AVAILABLE_PRIVILEGES.READER, req.params.node, function(err){

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.getById(req.params.node, function(err, userObj){
                        if(err){
                            if(err.message.indexOf('[404]') > -1){
                                base.write(base.STATUS_CODES.NOT_FOUND, JSON.stringify(err), res);
                            }
                            else {
                                base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                            }
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(userObj), res);
                        }
                    });
                }
            });
        });
    };

     node.deleteById = function(req, res){
        base.authenticateRequest(req, res, function(token){

            base.userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, function(err){
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.deleteById(req.params.id, function(err){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify({}), res);
                        }
                    });
                }
            });
        });
    };

    node.getChildNodes = function(req, res){
        //[TODO]
    };

    node.getFiles = function(req, res){
        //[TODO]
    };

    node.getFilesDeepLoad = function(req, res){
        //[TODO]
    };

    node.getChildNodesDeepLoad = function(req, res){
        //[TODO]
    };

     node.describe = function (req, res){
        base.authenticateRequest(req, res, function(token){

            base.userCan(token, base.AVAILABLE_PRIVILEGES.READER, function(err){

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.describe(function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

     node.update = function(req, res){
        base.authenticateRequest(req, res, function(token){

            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.param.body._id, function(err) {

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {

                    grasshopper.nodes.update(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    node.create = function(req, res){
        base.authenticateRequest(req, res, function(token){
            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.body.parent, function(err) {
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.create(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    return node;
};<commit_msg>Added methods to add and delete content types to a node.<commit_after>module.exports = function(grasshopper){
    "use strict";

    var node = {},
        async = require('async'),
        _ = require('underscore'),
        base = require('./api-base')(grasshopper);


    function userCanForNode(user, parentNodeId, minRole, callback){
        var isAllowed = _.find(user.permissions, function(permission){
            var userPrivLevel = base.AVAILABLE_PRIVILEGES[permission.role.toUpperCase()];
            return (permission.nodeid == parentNodeId &&  (userPrivLevel <= parseInt(minRole, 10)));
        });

        callback((!isAllowed) ? new Error("User does not have enough privileges.") : null);
    }

    function userPreventedForNode(user, parentNodeId, minRole, callback){
        var ruleIsSet = false,
            isAllowed = _.find(user.permissions, function(permission){
                var userPrivLevel = base.AVAILABLE_PRIVILEGES[permission.role.toUpperCase()];
                ruleIsSet = true;

                return (permission.nodeid == parentNodeId &&  (userPrivLevel <= parseInt(minRole, 10)));
            });

        callback((ruleIsSet && !isAllowed) ? new Error("User does not have enough privileges.") : null);
    }

    function userCan(token, minRole, parentNodeId, callback){

        async.waterfall([
            function(cb){
                grasshopper.users.getById(token.profile._id, function(err, obj){
                    var permissions = {
                        userPermission: false,
                        nodePermission: false,
                        nodeRestriction: true
                    };

                   cb(null, obj, permissions);
                });
            },
            function(user, permissions, cb){
                userCanForNode(user, parentNodeId, minRole, function(err){
                   permissions.nodePermission = (err == null);
                   cb(null, user, permissions);
                });
            },
            function(user, permissions, cb){
                userPreventedForNode(user, parentNodeId, minRole, function(err){
                    permissions.nodeRestriction = (err != null);
                    cb(null, user, permissions);
                });
            },
            function(user, permissions, cb){
                base.userCan(token, minRole, function(err){
                    permissions.userPermission = (err == null);
                    cb(null, user, permissions);
                });
            }
        ], function(err, user, permissions){
            var error = ((permissions.userPermission && !permissions.nodeRestriction) || permissions.nodePermission) ? null : new Error("User does not have  rights to perform this action.");
            callback(error);
        });
    }


     node.getById = function (req, res){
        base.authenticateRequest(req, res, function(token){

            userCan(token, base.AVAILABLE_PRIVILEGES.READER, req.params.node, function(err){

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.getById(req.params.node, function(err, userObj){
                        if(err){
                            if(err.message.indexOf('[404]') > -1){
                                base.write(base.STATUS_CODES.NOT_FOUND, JSON.stringify(err), res);
                            }
                            else {
                                base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                            }
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(userObj), res);
                        }
                    });
                }
            });
        });
    };

     node.deleteById = function(req, res){
        base.authenticateRequest(req, res, function(token){

            base.userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, function(err){
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.deleteById(req.params.id, function(err){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify({}), res);
                        }
                    });
                }
            });
        });
    };

    node.getChildNodes = function(req, res){
        //[TODO]
    };

    node.getFiles = function(req, res){
        //[TODO]
    };

    node.getFilesDeepLoad = function(req, res){
        //[TODO]
    };

    node.getChildNodesDeepLoad = function(req, res){
        //[TODO]
    };

     node.describe = function (req, res){
        base.authenticateRequest(req, res, function(token){

            base.userCan(token, base.AVAILABLE_PRIVILEGES.READER, function(err){

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.describe(function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify(err), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

     node.update = function(req, res){
        base.authenticateRequest(req, res, function(token){

            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.param.body._id, function(err) {

                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {

                    grasshopper.nodes.update(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    node.create = function(req, res){
        base.authenticateRequest(req, res, function(token){
            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.body.parent, function(err) {
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.create(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    node.addContentTypes = function(req, res){
        base.authenticateRequest(req, res, function(token){
            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.body.parent, function(err) {
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.addContentTypes(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    node.addContentType = function(req, res){
        base.authenticateRequest(req, res, function(token){
            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.body.parent, function(err) {
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.addContentTypes(req.body, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    node.deleteContentType = function(req, res){
        base.authenticateRequest(req, res, function(token){
            userCan(token, base.AVAILABLE_PRIVILEGES.EDITOR, req.params.id, function(err) {
                if(err){
                    base.write(base.STATUS_CODES.FORBIDDEN, base.getStatusMessage(base.STATUS_CODES.FORBIDDEN), res);
                }
                else {
                    grasshopper.nodes.deleteContentTypes(req.params.cid, function(err, obj){
                        if(err){
                            base.write(base.STATUS_CODES.SERVER_ERROR, JSON.stringify({message: err.message}), res);
                        }
                        else {
                            base.write(base.STATUS_CODES.SUCCESS, JSON.stringify(obj), res);
                        }
                    });
                }
            });
        });
    };

    return node;
};
{'fraction_non_alphanumeric': 0.1122036183840881, 'fraction_numerical': 0.0008989774131924936, 'mean_word_length': 1.363431151241535, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7010262', 'n_tokens_mistral': 4766, 'n_tokens_neox': 4530, 'n_words': 697}