<commit_before>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var util = require('util');

var ldap = require('ldapjs');

var common = require('./common');

var clog = require('./changelog');


///--- Handlers

function entryExists(req, res, next) {
    return req.exists(req.bucket, req.key, function (err, exists) {
        if (err)
            return next(err);

        if (exists)
            return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));

        return next();
    });
}


function parentExists(req, res, next) {
    var bucket = req.bucket;
    var log = req.log;

    if (req.dn.equals(req.suffix)) {
        log.debug({
            bucket: bucket,
            key: req.key
        }, 'Adding suffix');
        return next();
    }

    var parent = req.dn.parent().toString();
    assert.ok(parent);

    return req.exists(bucket, parent, function (err, exists) {
        if (err)
            return next(err);

        if (!exists)
            return next(new ldap.NoSuchObjectError(parent));

        // Tack on an _parent attribute so future indexed requests work
        req.attributes.push(new ldap.Attribute({
            type: '_parent',
            vals: [parent]
        }));

        return next();
    });
}


function checkBlacklist(req, res, next) {
    req._entry = req.toObject().attributes;

    if (req._entry.objectclass) {
        req._entry.objectclass = req._entry.objectclass.map(function (v) {
            return v.toLowerCase();
        });
    }

    if (!req._entry.login ||
        !req._entry.email ||
        req._entry._imported ||
        (req._entry._replicated && !req.config.ufds_is_master)) {
        return next();
    }

    var key = req.config[req.suffix].blacklistRDN + ', ' + req.suffix;

    return req.get(req.bucket, key, function (err, val) {
        if (err) {
            if (err.name === 'NoSuchObjectError') {
                // No blacklist, move forward:
                return next();
            }
            return next(err);
        }

        var blacklist = val.value;
        var blacklisted = blacklist.email.some(function (x) {
            var email = req._entry.email;
            if (x === email) {
                return true;
            }
            /* JSSTYLED */
            var re = new RegExp(x.replace(/\*/, '.\*'));
            return re.test(email);
        });

        if (blacklisted) {
            return next(new ldap.ConstraintViolationError(
                        'Email address is blacklisted.'));
        }
        return next();
    });
}


function validateLogin(req, res, next) {
    if (!req._entry.login ||
        req._entry._imported ||
        (req._entry._replicated && !req.config.ufds_is_master)) {
        return next();
    }

    // Given this will run before schema, and we do not want any "fancy"
    // character going into the following query:
    var LOGIN_RE = /^[a-zA-Z][a-zA-Z0-9_\.@]+$/;
    if (!LOGIN_RE.test(req._entry.login)) {
        return next(new ldap.ConstraintViolationError('Login is invalid'));
    }

    var query = util.format('select count(*) from %s where login ~* \'%s\'',
            req.config[req.suffix].bucket, req._entry.login);

    var count = 0;
    var r = req.moray.sql(query);

    r.on('record', function (rec) {
        if (rec && rec.count) {
            count = parseInt(rec.count, 10);
        }
    });

    r.once('error', function (err) {
        r.removeAllListeners('record');
        r.removeAllListeners('end');
        return next(err);
    });

    r.once('end', function () {
        if (count !== 0) {
            return next(new ldap.ConstraintViolationError(
                    'Login is already taken'));
        }
        return next();
    });
}


function save(req, res, next) {
    if (!req.headers) {<commit_msg>[CAPI-302] Avoid false positives on login match when new login is a substring of existing one<commit_after>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var util = require('util');

var ldap = require('ldapjs');

var common = require('./common');

var clog = require('./changelog');


///--- Handlers

function entryExists(req, res, next) {
    return req.exists(req.bucket, req.key, function (err, exists) {
        if (err)
            return next(err);

        if (exists)
            return next(new ldap.EntryAlreadyExistsError(req.dn.toString()));

        return next();
    });
}


function parentExists(req, res, next) {
    var bucket = req.bucket;
    var log = req.log;

    if (req.dn.equals(req.suffix)) {
        log.debug({
            bucket: bucket,
            key: req.key
        }, 'Adding suffix');
        return next();
    }

    var parent = req.dn.parent().toString();
    assert.ok(parent);

    return req.exists(bucket, parent, function (err, exists) {
        if (err)
            return next(err);

        if (!exists)
            return next(new ldap.NoSuchObjectError(parent));

        // Tack on an _parent attribute so future indexed requests work
        req.attributes.push(new ldap.Attribute({
            type: '_parent',
            vals: [parent]
        }));

        return next();
    });
}


function checkBlacklist(req, res, next) {
    req._entry = req.toObject().attributes;

    if (req._entry.objectclass) {
        req._entry.objectclass = req._entry.objectclass.map(function (v) {
            return v.toLowerCase();
        });
    }

    if (!req._entry.login ||
        !req._entry.email ||
        req._entry._imported ||
        (req._entry._replicated && !req.config.ufds_is_master)) {
        return next();
    }

    var key = req.config[req.suffix].blacklistRDN + ', ' + req.suffix;

    return req.get(req.bucket, key, function (err, val) {
        if (err) {
            if (err.name === 'NoSuchObjectError') {
                // No blacklist, move forward:
                return next();
            }
            return next(err);
        }

        var blacklist = val.value;
        var blacklisted = blacklist.email.some(function (x) {
            var email = req._entry.email;
            if (x === email) {
                return true;
            }
            /* JSSTYLED */
            var re = new RegExp(x.replace(/\*/, '.\*'));
            return re.test(email);
        });

        if (blacklisted) {
            return next(new ldap.ConstraintViolationError(
                        'Email address is blacklisted.'));
        }
        return next();
    });
}


function validateLogin(req, res, next) {
    if (!req._entry.login ||
        req._entry._imported ||
        (req._entry._replicated && !req.config.ufds_is_master)) {
        return next();
    }

    // Given this will run before schema, and we do not want any "fancy"
    // character going into the following query:
    var LOGIN_RE = /^[a-zA-Z][a-zA-Z0-9_\.@]+$/;
    if (!LOGIN_RE.test(req._entry.login)) {
        return next(new ldap.ConstraintViolationError('Login is invalid'));
    }

    var query = util.format('select count(*) from %s where login ~* \'^%s$\'',
            req.config[req.suffix].bucket, req._entry.login);

    var count = 0;
    var r = req.moray.sql(query);

    r.on('record', function (rec) {
        if (rec && rec.count) {
            count = parseInt(rec.count, 10);
        }
    });

    r.once('error', function (err) {
        r.removeAllListeners('record');
        r.removeAllListeners('end');
        return next(err);
    });

    r.once('end', function () {
        if (count !== 0) {
            return next(new ldap.ConstraintViolationError(
                    'Login is already taken'));
        }
        return next();
    });
}


function save(req, res, next) {
    if (!req.headers) {
{'fraction_non_alphanumeric': 0.14603705609881626, 'fraction_numerical': 0.002959341224909933, 'mean_word_length': 1.9014557670772676, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1012085', 'n_tokens_mistral': 2385, 'n_tokens_neox': 2288, 'n_words': 561}