All files / node-activedirectory/lib/services/internal service.parseRangeAttributes.js

16.28% Statements 7/43
0% Branches 0/24
0% Functions 0/3
17.07% Lines 7/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 861x 1x 1x 1x 1x                     1x                                                                                                                                           1x
const _                                 = require('underscore');
const log                               = require('./service.log');
const parseDistinguishedName            = require('./service.parseDistinguishedName');
const search                            = require('./service.search');
const RangeRetrievalSpecifierAttribute  = require('../../client/rangeretrievalspecifierattribute');
 
 
/**
 * Handles any attributes that might have been returned with a range= specifier.
 *
 * @private
 * @param {Object} result The entry returned from the query.
 * @param {Object} opts The original LDAP query string parameters to execute. { scope: '', filter: '', attributes: [ '', '', ... ], sizeLimit: 0, timelimit: 0 }
 * @param {Function} callback The callback to execute when completed. callback(err: {Object}, result: {Object}})
 */
const parseRangeAttributes = function(result, opts, callback) {
    log.trace('parseRangeAttributes(%j,%j)', result, opts);
    var self = this;
 
    // Check to see if any of the result attributes have range= attributes.
    // If not, return immediately.
    if (!RangeRetrievalSpecifierAttribute.prototype.hasRangeAttributes(result)) {
        callback(null, result);
        return;
    }
 
    // Parse the range attributes that were provided. If the range attributes are null
    // or indicate that the range is complete, return the result.
    var rangeAttributes = RangeRetrievalSpecifierAttribute.prototype.getRangeAttributes(result);
    if ((!rangeAttributes) || (rangeAttributes.length <= 0)) {
        callback(null, result);
        return;
    }
 
    // Parse each of the range attributes. Merge the range attributes into
    // the properly named property.
    var queryAttributes = [];
    _.each(rangeAttributes, function (rangeAttribute, index) {
        // Merge existing range into the properly named property.
        if (!result[rangeAttribute.attributeName]) result[rangeAttribute.attributeName] = [];
        Array.prototype.push.apply(result[rangeAttribute.attributeName], result[rangeAttribute.toString()]);
        delete (result[rangeAttribute.toString()]);
 
        // Build our ldap query attributes with the proper attribute;range= tags to
        // get the next sequence of data.
        var queryAttribute = rangeAttribute.next();
        if ((queryAttribute) && (!queryAttribute.isComplete())) {
            queryAttributes.push(queryAttribute.toString());
        }
    });
 
    // If we're at the end of the range (i.e. all items retrieved), return the result.
    if (queryAttributes.length <= 0) {
        log.debug('All attribute ranges %j retrieved for %s', rangeAttributes, result.dn);
        callback(null, result);
        return;
    }
 
    log.debug('Attribute range retrieval specifiers %j found for "%s". Next range: %j',
        rangeAttributes, result.dn, queryAttributes);
    // Execute the query again with the query attributes updated.
    opts = _.defaults({
        filter: '(distinguishedName=' + parseDistinguishedName(result.dn) + ')',
        attributes: queryAttributes
    }, opts);
    search.call(self, opts, function onSearch(err, results) {
        if (err) {
            callback(err);
            return;
        }
 
        // Should be only one result
        var item = (results || [])[0];
        for (var property in item) {
            if (item.hasOwnProperty(property)) {
                if (!result[property]) result[property] = [];
                if (_.isArray(result[property])) {
                    Array.prototype.push.apply(result[property], item[property]);
                }
            }
        }
        callback(null, result);
    });
}
 
module.exports = parseRangeAttributes;