Source: stores/memory.js

/*jslint plusplus: true, devel: true, nomen: true, node: true, indent: 4, maxerr: 50 */

"use strict";

var Strings     = require("../strings"),
    util        = require("../util"),
    async       = require("async");

/**
 * Constructor for Memory rule store.
 *
 * This store keeps rules in memory only.
 * Rules are not persisted across application reloads and therefore they have to be loaded early in the application start (initialization) phase.
 *
 * This is the default store for authority and it doesn’t have to be explicitly configured unless it is used in conjunction with other stores.
 *
 * @example
 *  var authority = require("authority");
 *
 *  authority.setRules([{
 *          name: "allow_managers_only",
            description: "Only managers can pass.",
            condition: { title: "Manager" }
 *      }, {
 *          name: "allow_teenagers_only",
            description: "Only users between 13 and 19 years old can pass.",
            condition: { age: { $gte: 13, $lte: 19 } }
 *      }
 *  ]);
 *
 * @class Represents a Memory rule store.
 */
function MemoryStore() {
    /**
     * The name of this store. The default value is "memory". NOTE: every store is required to have a unique name within a manager.
     */
    this.name = "memory";

    /**
     * The object that holds the references to all stored rules. NOTE: this member is not part of the Authority API and it is specific to this store only.
     */
    this.rules = {};
}

/**
 * Adds one or more rules to the store.
 *
 * @param {(object|object[])} rules - The rule or an array of rules to be added to the store.
 *
 * @param {boolean=} override - Specifies whether existing rules should be replaced by the ones provided to this method. Rules are matched by their name.
 * If this parameter is not specified or is false and there is a name conflict an error will be returned or thrown depending on the usage of the method.
 *
 * @param {function=} done - Optional callback function that will be called after the rule(s) have been added.
 * If the method is unsuccessful an error object will be passed as a single parameter to the callback.
 * If the callback is omitted and the method is unsuccessful an error will be thrown.
 *
 * @return {null}
 */
MemoryStore.prototype.setRules = function (rules, override, done) {
    var that = this;

    if (typeof override === "function") {
        done = override;
        override = null;
    }

    if (!done) {
        done = function (err) {
            if (err) {
                throw err;
            }
        };
    }

    function setRule(rule, cb) {
        if (!override && that.rules[rule.name]) {
            return cb(new Error(Strings.ERR_RULE_EXISTS));
        }

        that.rules[rule.name] = rule;
        cb();
    }

    if (Array.isArray(rules)) {
        async.each(rules, function (item, callback) {
            setRule(item, callback);
        }, done);
    } else {
        setRule(rules, done);
    }
};

/**
 * Retrieves the specified rule from the store.
 *
 * @param {string} name - The name of the rule.
 * @param {function} done - The callback that handles the result.
 * The first parameter will always be null for this store while the second parameter will contain the requested rule or null if not found.
 * @return {null}
 */
MemoryStore.prototype.getRule = function (name, done) {
    done(null, this.rules[name]);
};

/**
 * Removes the specified rules from the store.
 *
 * @param {(string|string[])} names - The name or an array of names to remove.
 * @param {function=} done - Optional callback function that will be called after the rule(s) have been deleted.
 * If the method is unsuccessful an error object will be passed as a single parameter to the callback.
 * If the callback is omitted and the method is unsuccessful an error will be thrown.
 * @return {null}
 */
MemoryStore.prototype.deleteRules = function (names, done) {
    var that = this;

    if (!done) {
        done = function (err) {
            if (err) {
                throw err;
            }
        };
    }

    function remRule(name, cb) {
        delete that.rules[name];
        cb();
    }

    if (Array.isArray(names)) {
        async.each(names, function (item, callback) {
            remRule(item, callback);
        }, done);
    } else {
        remRule(names, done);
    }
};

/**
 * Retrieves the names and descriptions of the rules present in the store and matching the specified criteria.
 *
 * All parameters are required.
 *
 * @param {number} start - The index at wich to begin retrieving names. The index of the first element is 0.
 * @param {number} count - The number of names to retrieve. `0` denotes all remaining.
 * @param {string} match - Wildcard expression to match names. `null` denotes any name. Example: `allow_*`
 * @param {function} done - The callback that handles the result.
 * The first parameter will always be null for this store while the second parameter will contain an array of matched objects `{ name: "string", description: "string" }`.
 */
MemoryStore.prototype.getRuleNames = function (start, count, match, done) {
    var keys    = Object.keys(this.rules),
        res     = [],
        that    = this,
        regex;

    if (match) {
        regex = util.regExpFromWildExp(match);
        keys = keys.filter(function (el) {
            return regex.test(el);
        });
    }

    if (start || count) {
        if (count) {
            count = start + count;
        } else {
            count = undefined;
        }
        keys = keys.splice(start, count);
    }

    keys.forEach(function (key) {
        var rule = that.rules[key];
        res.push({ name: rule.name, description: rule.description });
    });

    done(null, res);
};

/**
 * Gets the total count of rules present in the store.
 *
 * @param {function} done - The callback that handles the result.
 * The first parameter will always be null for this store while the second parameter will contain a number representing the total count of rules.
 */
MemoryStore.prototype.getRuleCount = function (done) {
    done(null, Object.keys(this.rules).length);
};

module.exports = MemoryStore;
Authority Copyright © 2013-2014 The contributors to the Authority projects.
Documentation generated by JSDoc 3.2.2 on Sat Jan 18 2014 02:44:25 GMT+0200 (EET) using the DocStrap template.