<commit_before>from __future__ import absolute_import

import logging
import random
import string
import yaml
from passlib.hash import ldap_salted_sha1

try:
    from yaml import CSafeLoader as YAMLLoader
except ImportError:
    from yaml import SafeLoader as YAMLLoader

import ldap
from ldap import dn, modlist, SERVER_DOWN

log = logging.getLogger(__file__)


class UnknownLdapUser(Exception):
    """ When user was not found in a ldap search """


class LdapWrapper(object):
    """ Simple ldap class wrapper"""
    _url = None
    _conn = None
    _base = None
    _filter = None

    def __init__(self, filename):
        with open(filename) as fdesc:
            conf = yaml.load(fdesc, YAMLLoader)

        self._url = conf['ldap_url']
        self._base = conf['basedn']
        self._filter = conf['search_filter']

        self.mail_attr = conf['mail_attr']
        self.firstname_attr = conf['firstname_attr']
        self.lastname_attr = conf['lastname_attr']
        self.login_attr = conf['login_attr']
        self.manager_attr = conf['manager_attr']
        self.country_attr = conf['country_attr']

        self.admin_dn = conf['admin_dn']

        self.system_DN = conf['system_dn']
        self.system_password = conf['system_pass']

        self.team_dn = conf['team_dn']

        self._conn = ldap.initialize(self._url)
        self._bind(self.system_DN, self.system_password)

        log.info('Ldap wrapper initialized')

    def _bind(self, dn, password):
        """ bind a user in ldap with given password

        ldap does not support unicode for binding
        so we must cast password to utf-8
        """
        log.debug('binding with dn: %s' % dn)
        try:
            self._conn.simple_bind_s(dn, password.encode('utf-8'))
        except SERVER_DOWN:
            self._conn = ldap.initialize(self._url)
            self._conn.simple_bind_s(dn, password.encode('utf-8'))

    def _search(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        log.debug('searching: %s for: %s' % (what, retrieve))
        return self._conn.search_s(self._base, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_admin(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        return self._conn.search_s(self.admin_dn, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_team(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        return self._conn.search_s(self.team_dn, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_by_item(self, item):
        required_fields = ['cn', 'mail', 'uid', 'givenName', 'sn', 'manager',
                           'ou', 'userPassword']
        res = self._search(self._filter % item, required_fields)
        if not res:
            raise UnknownLdapUser

        USER_DN, entry = res[0]
        return self.parse_ldap_entry(USER_DN, entry)

    def search_user_by_login(self, login):
        item = 'cn=*%s*' % login
        return self._search_by_item(item)

    def search_user_by_dn(self, user_dn):
        item = 'cn=*%s*' % self._extract_cn(user_dn)
        return self._search_by_item(item)

    def _extract_country(self, user_dn):
        """ Get country from a user dn """
        for rdn in dn.str2dn(user_dn):
            rdn = rdn[0]
            if rdn[0] == self.country_attr:
                return rdn[1]

    def _extract_cn(self, user_dn):
        """ Get cn from a user dn """
        for rdn in dn.str2dn(user_dn):
            rdn = rdn[0]
            if rdn[0] == self.login_attr:
                return rdn[1]

    def parse_ldap_entry(self, user_dn, entry):
        """
        Format ldap entry and parse user_dn to output dict with expected values
        """
        if not user_dn or not entry:
            return

        data = {
            'email': entry[self.mail_attr].pop(),
            'lastname': entry[self.lastname_attr].pop(),
            'login': entry[self.login_attr].pop(),
            'manager_dn': '',
            'firstname': '',
        }

        if self.manager_attr in entry:
            data['manager_dn'] = entry[self.manager_attr].pop()

        if self.firstname_attr in entry:
            data['firstname'] = entry[self.firstname_attr].pop()

        if 'ou' in entry:
            data['ou'] = entry['ou']

        # save user dn
        data['dn'] = user_dn
        data['country'] = self._extract_country(user_dn)
        data['manager_cn'] = self._extract_country(data['manager_dn'])
        data['userPassword'] = entry['userPassword'].pop()

        return data

    def authenticate(self, login, password):<commit_msg>OU field is a list as other fields<commit_after>from __future__ import absolute_import

import logging
import random
import string
import yaml
from passlib.hash import ldap_salted_sha1

try:
    from yaml import CSafeLoader as YAMLLoader
except ImportError:
    from yaml import SafeLoader as YAMLLoader

import ldap
from ldap import dn, modlist, SERVER_DOWN

log = logging.getLogger(__file__)


class UnknownLdapUser(Exception):
    """ When user was not found in a ldap search """


class LdapWrapper(object):
    """ Simple ldap class wrapper"""
    _url = None
    _conn = None
    _base = None
    _filter = None

    def __init__(self, filename):
        with open(filename) as fdesc:
            conf = yaml.load(fdesc, YAMLLoader)

        self._url = conf['ldap_url']
        self._base = conf['basedn']
        self._filter = conf['search_filter']

        self.mail_attr = conf['mail_attr']
        self.firstname_attr = conf['firstname_attr']
        self.lastname_attr = conf['lastname_attr']
        self.login_attr = conf['login_attr']
        self.manager_attr = conf['manager_attr']
        self.country_attr = conf['country_attr']

        self.admin_dn = conf['admin_dn']

        self.system_DN = conf['system_dn']
        self.system_password = conf['system_pass']

        self.team_dn = conf['team_dn']

        self._conn = ldap.initialize(self._url)
        self._bind(self.system_DN, self.system_password)

        log.info('Ldap wrapper initialized')

    def _bind(self, dn, password):
        """ bind a user in ldap with given password

        ldap does not support unicode for binding
        so we must cast password to utf-8
        """
        log.debug('binding with dn: %s' % dn)
        try:
            self._conn.simple_bind_s(dn, password.encode('utf-8'))
        except SERVER_DOWN:
            self._conn = ldap.initialize(self._url)
            self._conn.simple_bind_s(dn, password.encode('utf-8'))

    def _search(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        log.debug('searching: %s for: %s' % (what, retrieve))
        return self._conn.search_s(self._base, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_admin(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        return self._conn.search_s(self.admin_dn, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_team(self, what, retrieve):
        # rebind with system dn
        self._bind(self.system_DN, self.system_password)
        return self._conn.search_s(self.team_dn, ldap.SCOPE_SUBTREE, what,
                                   retrieve)

    def _search_by_item(self, item):
        required_fields = ['cn', 'mail', 'uid', 'givenName', 'sn', 'manager',
                           'ou', 'userPassword']
        res = self._search(self._filter % item, required_fields)
        if not res:
            raise UnknownLdapUser

        USER_DN, entry = res[0]
        return self.parse_ldap_entry(USER_DN, entry)

    def search_user_by_login(self, login):
        item = 'cn=*%s*' % login
        return self._search_by_item(item)

    def search_user_by_dn(self, user_dn):
        item = 'cn=*%s*' % self._extract_cn(user_dn)
        return self._search_by_item(item)

    def _extract_country(self, user_dn):
        """ Get country from a user dn """
        for rdn in dn.str2dn(user_dn):
            rdn = rdn[0]
            if rdn[0] == self.country_attr:
                return rdn[1]

    def _extract_cn(self, user_dn):
        """ Get cn from a user dn """
        for rdn in dn.str2dn(user_dn):
            rdn = rdn[0]
            if rdn[0] == self.login_attr:
                return rdn[1]

    def parse_ldap_entry(self, user_dn, entry):
        """
        Format ldap entry and parse user_dn to output dict with expected values
        """
        if not user_dn or not entry:
            return

        data = {
            'email': entry[self.mail_attr].pop(),
            'lastname': entry[self.lastname_attr].pop(),
            'login': entry[self.login_attr].pop(),
            'manager_dn': '',
            'firstname': '',
        }

        if self.manager_attr in entry:
            data['manager_dn'] = entry[self.manager_attr].pop()

        if self.firstname_attr in entry:
            data['firstname'] = entry[self.firstname_attr].pop()

        if 'ou' in entry:
            data['ou'] = entry['ou'].pop()

        # save user dn
        data['dn'] = user_dn
        data['country'] = self._extract_country(user_dn)
        data['manager_cn'] = self._extract_country(data['manager_dn'])
        data['userPassword'] = entry['userPassword'].pop()

        return data

    def authenticate(self, login, password):
{'fraction_non_alphanumeric': 0.11037823353601979, 'fraction_numerical': 0.0026795836339276514, 'mean_word_length': 2.25746894931185, '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': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6573715', 'n_tokens_mistral': 3037, 'n_tokens_neox': 2961, 'n_words': 706}