diff --git a/docs/conf.py b/docs/conf.py index f1811f5..1062054 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -50,7 +50,7 @@ copyright = u'2014, Pierre-Francois Carpentier' # # The short X.Y version. # The full version, including alpha/beta/rc tags. -release = '0.0.1' +release = '0.0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ldapcherry/__init__.py b/ldapcherry/__init__.py index 1f83017..76f51e3 100644 --- a/ldapcherry/__init__.py +++ b/ldapcherry/__init__.py @@ -92,8 +92,8 @@ class LdapCherry(object): def _get_groups(self, username): """ Get groups of a user - @str username: name of the user - @rtype: dict, format { '': [] } + @str username: name of the user + @rtype: dict, format { '': [] } """ ret = {} for b in self.backends: @@ -106,9 +106,9 @@ class LdapCherry(object): def _get_roles(self, username): """ Get roles of a user - @str username: name of the user - @rtype: dict, format { 'roles': [], - 'unusedgroups': [] } + @str username: name of the user + @rtype: dict, format { 'roles': [], + 'unusedgroups': [] } """ groups = self._get_groups(username) user_roles = self.roles.get_roles(groups) @@ -116,7 +116,7 @@ class LdapCherry(object): msg = "user '" + username +"' roles: " + str(user_roles), severity = logging.DEBUG, ) - return user_roles + return user_roles def _is_admin(self, username): """ Check if a user is an ldapcherry administrator @@ -127,8 +127,8 @@ class LdapCherry(object): return self.roles.is_admin(roles['roles']) def _check_backends(self): - """ Check that every backend in roles and attributes - is declared in main configuration + """ Check that every backend in roles and attributes + is declared in main configuration """ backends = self.backends_params.keys() for b in self.roles.get_backends(): @@ -139,8 +139,8 @@ class LdapCherry(object): raise MissingBackend(b) def _init_backends(self, config): - """ Init all backends - @dict: configuration of ldapcherry + """ Init all backends + @dict: configuration of ldapcherry """ self.backends_params = {} self.backends = {} @@ -185,7 +185,7 @@ class LdapCherry(object): def _init_auth(self, config): """ Init authentication - @dict: configuration of ldapcherry + @dict: configuration of ldapcherry """ self.auth_mode = self._get_param('auth', 'auth.mode', config) if self.auth_mode in ['and', 'or', 'none']: @@ -277,8 +277,8 @@ class LdapCherry(object): """ return logging level object corresponding to a given level passed as a string - @str level: name of a syslog log level - @rtype: logging, logging level from logging module + @str level: name of a syslog log level + @rtype: logging, logging level from logging module """ if level == 'debug': return logging.DEBUG @@ -300,10 +300,10 @@ class LdapCherry(object): return logging.INFO def _auth(self, user, password): - """ authenticate a user + """ authenticate a user @str user: login of the user - @str password: password of the user - @rtype: dict, {'connected': , + @str password: password of the user + @rtype: dict, {'connected': , 'isadmin': } """ if self.auth_mode == 'none': @@ -327,8 +327,8 @@ class LdapCherry(object): return {'connected': True, 'isadmin': isadmin} def _load_templates(self, config): - """ load templates - @dict: configuration of ldapcherry + """ load templates + @dict: configuration of ldapcherry """ # definition of the template directory self.template_dir = self._get_param('resources', 'templates.dir', config) @@ -361,8 +361,8 @@ class LdapCherry(object): ) def reload(self, config = None): - """ load/reload configuration - @dict: configuration of ldapcherry + """ load/reload configuration + @dict: configuration of ldapcherry """ try: # log configuration handling @@ -403,7 +403,7 @@ class LdapCherry(object): def _search(self, searchstring): """ search users - @str searchstring: search string + @str searchstring: search string @rtype: dict, {: {: }} """ if searchstring is None: @@ -423,7 +423,7 @@ class LdapCherry(object): def _get_user(self, username): """ get user attributes - @str username: user to get + @str username: user to get @rtype: dict, {: } """ if username is None: @@ -438,7 +438,7 @@ class LdapCherry(object): ret[attrid] = tmp[attr] cherrypy.log.error( - msg = "user '" + username + "' attributes " + str(ret), + msg = "user '" + username + "' attributes " + str(ret), severity = logging.DEBUG ) return ret @@ -458,7 +458,7 @@ class LdapCherry(object): elif p_type == 'role': ret['roles'][param] = params[p] elif p_type == 'group': - # with groups there is a second prefix + # with groups there is a second prefix # corresponding to the backend backend, sep, value = param.partition('.') if not backend in ret['groups']: diff --git a/ldapcherry/backend/backendLdap.py b/ldapcherry/backend/backendLdap.py index e8ad15c..d4ee703 100644 --- a/ldapcherry/backend/backendLdap.py +++ b/ldapcherry/backend/backendLdap.py @@ -139,7 +139,7 @@ class Backend(ldapcherry.backend.Backend): else: # this is even darker magic ldap_client.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND) - # it doesn't make sense to set it to never (don't check certifate) + # it doesn't make sense to set it to never (don't check certifate) # but it only works with this option... and it checks the certificat # (I've lost my sanity over this) ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) @@ -252,8 +252,8 @@ class Backend(ldapcherry.backend.Backend): ldap_client = self._bind() tmp = self._get_user(username, ALL_ATTRS) dn = tmp[0] - old_attrs = tmp[1] - for attr in attrs: + old_attrs = tmp[1] + for attr in attrs: content = self._str(attrs[attr]) attr = self._str(attr) new = { attr : content } @@ -274,7 +274,7 @@ class Backend(ldapcherry.backend.Backend): ldap_client = self._bind() tmp = self._get_user(username, ALL_ATTRS) dn = tmp[0] - attrs = tmp[1] + attrs = tmp[1] attrs['dn'] = dn for group in groups: group = self._str(group) @@ -298,12 +298,12 @@ class Backend(ldapcherry.backend.Backend): ldap_client.unbind_s() self._exception_handler(e) ldap_client.unbind_s() - + def del_from_groups(self, username, groups): ldap_client = self._bind() tmp = self._get_user(username, ALL_ATTRS) dn = tmp[0] - attrs = tmp[1] + attrs = tmp[1] attrs['dn'] = dn for group in groups: group = self._str(group) @@ -349,7 +349,7 @@ class Backend(ldapcherry.backend.Backend): for attr in attrs_tmp: value_tmp = attrs_tmp[attr] if len(value_tmp) == 1: - ret[attr] = self._uni(value_tmp[0]) + ret[attr] = self._uni(value_tmp[0]) else: ret[attr] = map(self._uni, value_tmp) return ret diff --git a/misc/debug_roles.py b/misc/debug_roles.py index 33442ee..e20722b 100644 --- a/misc/debug_roles.py +++ b/misc/debug_roles.py @@ -16,7 +16,7 @@ class CustomDumper(yaml.SafeDumper): return True inv = Roles('./conf/roles.yml') -print +print print inv.dump_nest() groups = { diff --git a/setup.py b/setup.py index 0371c42..5bb3b22 100755 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ try: f.close() except IOError: description = small_description - + try: license = open('LICENSE').read() except IOError: @@ -74,7 +74,7 @@ def get_list_files(basedir, targetdir): return return_list # add static files and templates in the list of thing to deploy -resources_files = get_list_files('resources', +resources_files = get_list_files('resources', os.path.join(datarootdir, 'share', 'ldapcherry')) # add the configuration files if they don't exist @@ -95,7 +95,7 @@ setup( scripts = ['scripts/ldapcherryd'], url = 'https://github.com/kakwa/ldapcherry', license = license, - description = small_description, + description = small_description, long_description = description, install_requires = install_requires, tests_require = ['pytest'], diff --git a/tests/html_validator.py b/tests/html_validator.py index 269fc5b..559f0ff 100755 --- a/tests/html_validator.py +++ b/tests/html_validator.py @@ -2,22 +2,22 @@ # Copyright (c) 2007-2008 Mozilla Foundation # -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # -# The above copyright notice and this permission notice shall be included in +# The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. from __future__ import print_function, with_statement @@ -105,7 +105,7 @@ for arg in argv: errorsOnly = True else: sys.stderr.write('Unknown argument %s.\n' % arg) - sys.exit(3) + sys.exit(3) else: if fileName: sys.stderr.write('Cannot have more than one input file.\n') @@ -130,7 +130,7 @@ elif fileName: m = extPat.match(fileName) if m: ext = m.group(1) - ext = ext.translate(maketrans(string.ascii_uppercase, string.ascii_lowercase)) + ext = ext.translate(maketrans(string.ascii_uppercase, string.ascii_lowercase)) if ext in extDict: contentType = extDict[ext] else: @@ -138,7 +138,7 @@ elif fileName: sys.exit(3) else: sys.stderr.write('Could not extract a filename extension. Please force the type.\n') - sys.exit(6) + sys.exit(6) else: sys.stderr.write('Need to force HTML or XHTML when reading from stdin.\n') sys.exit(4) @@ -172,7 +172,7 @@ if gnu: url = url + '?out=gnu' else: url = url + '?out=text' - + if errorsOnly: url = url + '&level=error' @@ -188,19 +188,19 @@ while status in (302,301,307) and redirectCount < 10: if redirectCount > 0: url = response.getheader('Location') parsed = urlparse.urlsplit(url) - + if redirectCount > 0: connection.close() # previous connection print('Redirecting to %s' % url) print('Please press enter to continue or type \'stop\' followed by enter to stop.') if raw_input() != '': sys.exit(0) - + if parsed.scheme == 'https': connection = httplib.HTTPSConnection(parsed[1]) else: connection = httplib.HTTPConnection(parsed[1]) - + headers = { 'Accept-Encoding': 'gzip', 'Content-Type': contentType, @@ -208,13 +208,13 @@ while status in (302,301,307) and redirectCount < 10: 'Content-Length': len(gzippeddata), } urlSuffix = '%s?%s' % (parsed[2], parsed[3]) - + connection.connect() connection.request('POST', urlSuffix, body=gzippeddata, headers=headers) - + response = connection.getresponse() status = response.status - + redirectCount += 1 # @@ -226,7 +226,7 @@ if status != 200: if response.getheader('Content-Encoding', 'identity').lower() == 'gzip': response = gzip.GzipFile(fileobj=BytesIO(response.read())) - + if fileName and gnu: quotedName = '"%s"' % fileName.replace("'", '\\042') for line in response.read().split('\n'): diff --git a/tests/test_Attributes.py b/tests/test_Attributes.py index c5a9f9b..4ce888d 100644 --- a/tests/test_Attributes.py +++ b/tests/test_Attributes.py @@ -33,7 +33,7 @@ class TestError(object): def testGetSearchAttributes(self): inv = Attributes('./tests/cfg/attributes.yml') ret = inv.get_search_attributes() - expected = {'first-name': {'backends': {'ad': 'givenName', 'ldap': 'givenName'}, 'display_name': 'First Name', 'description': 'First name of the user', 'weight': 20, 'search_displayed': True, 'type': 'string'}, 'cn': {'autofill': {'function': 'cn', 'args': ['$first-name', '$name']}, 'backends': {'ad': 'CN', 'ldap': 'cn'}, 'display_name': 'Display Name', 'description': 'Firt Name and Display Name', 'weight': 30, 'search_displayed': True, 'type': 'string'}, 'name': {'backends': {'ad': 'sn', 'ldap': 'sn'}, 'display_name': 'Name', 'description': 'Family name of the user', 'weight': 10, 'search_displayed': True, 'type': 'string'}, 'uid': {'display_name': 'UID', 'description': 'UID of the user', 'weight': 50, 'autofill': {'function': 'uid', 'args': ['$first-name', '$last-name']}, 'backends': {'ad': 'UID', 'ldap': 'uid'}, 'key': True, 'search_displayed': True, 'type': 'string'}} + expected = {'first-name': {'backends': {'ad': 'givenName', 'ldap': 'givenName'}, 'display_name': 'First Name', 'description': 'First name of the user', 'weight': 20, 'search_displayed': True, 'type': 'string'}, 'cn': {'autofill': {'function': 'cn', 'args': ['$first-name', '$name']}, 'backends': {'ad': 'CN', 'ldap': 'cn'}, 'display_name': 'Display Name', 'description': 'Firt Name and Display Name', 'weight': 30, 'search_displayed': True, 'type': 'string'}, 'name': {'backends': {'ad': 'sn', 'ldap': 'sn'}, 'display_name': 'Name', 'description': 'Family name of the user', 'weight': 10, 'search_displayed': True, 'type': 'string'}, 'uid': {'display_name': 'UID', 'description': 'UID of the user', 'weight': 50, 'autofill': {'function': 'uid', 'args': ['$first-name', '$last-name']}, 'backends': {'ad': 'UID', 'ldap': 'uid'}, 'key': True, 'search_displayed': True, 'type': 'string'}} assert ret == expected def testGetBackendAttributes(self): @@ -45,7 +45,7 @@ class TestError(object): def testGetKey(self): inv = Attributes('./tests/cfg/attributes.yml') ret = inv.get_key() - expected = 'uid' + expected = 'uid' assert ret == expected def testWrongGetBackendAttributes(self): diff --git a/tests/test_BackendLdap.py b/tests/test_BackendLdap.py index 17e8a84..f00d40b 100644 --- a/tests/test_BackendLdap.py +++ b/tests/test_BackendLdap.py @@ -8,7 +8,7 @@ import pytest import sys from sets import Set from ldapcherry.backend.backendLdap import Backend, DelUserDontExists, CaFileDontExist -from ldapcherry.exceptions import * +from ldapcherry.exceptions import * from disable import travis_disabled import cherrypy import logging @@ -77,7 +77,7 @@ class TestError(object): ldapc = inv._connect() ldapc.simple_bind_s(inv.binddn, inv.bindpassword) except ldap.SERVER_DOWN as e: - return + return else: raise AssertionError("expected an exception") @@ -166,7 +166,7 @@ class TestError(object): def testSearchUser(self): inv = Backend(cfg, cherrypy.log, 'ldap', attr, 'uid') ret = inv.search('smith') - expected = {'ssmith': {'sn': 'smith', 'uid': 'ssmith', 'cn': 'Sheri Smith', 'userPassword': 'passwordsmith'}, 'jsmith': {'sn': 'Smith', 'uid': 'jsmith', 'cn': 'John Smith', 'userPassword': 'passwordsmith'}} + expected = {'ssmith': {'sn': 'smith', 'uid': 'ssmith', 'cn': 'Sheri Smith', 'userPassword': 'passwordsmith'}, 'jsmith': {'sn': 'Smith', 'uid': 'jsmith', 'cn': 'John Smith', 'userPassword': 'passwordsmith'}} assert ret == expected def testAddUser(self): @@ -232,7 +232,7 @@ class TestError(object): def testGetUser(self): inv = Backend(cfg, cherrypy.log, 'ldap', attr, 'uid') ret = inv.get_user('jwatson') - expected = {'uid': 'jwatson', 'objectClass': 'inetOrgPerson', 'carLicense': 'HERCAR 125', 'sn': 'watson', 'mail': 'j.watson@example.com', 'homePhone': '555-111-2225', 'cn': 'John Watson', 'userPassword': u'passwordwatson'} + expected = {'uid': 'jwatson', 'objectClass': 'inetOrgPerson', 'carLicense': 'HERCAR 125', 'sn': 'watson', 'mail': 'j.watson@example.com', 'homePhone': '555-111-2225', 'cn': 'John Watson', 'userPassword': u'passwordwatson'} assert ret == expected def testAddUserMissingMustattribute(self): diff --git a/tests/test_LdapCherry.py b/tests/test_LdapCherry.py index c523b88..23351ba 100644 --- a/tests/test_LdapCherry.py +++ b/tests/test_LdapCherry.py @@ -108,7 +108,7 @@ class TestError(object): cfg['global']['log.error_handler']=t app._set_access_log(cfg, logging.DEBUG) app._set_error_log(cfg, logging.DEBUG) - + def testPPolicy(self): app = LdapCherry() loadconf('./tests/cfg/ldapcherry.ini', app) @@ -163,7 +163,7 @@ class TestError(object): def testGetUser(self): app = LdapCherry() loadconf('./tests/cfg/ldapcherry.ini', app) - expected = {'password': u'passwordsmith', 'cn': u'Sheri Smith', 'uid': u'ssmith', 'name': u'smith'} + expected = {'password': u'passwordsmith', 'cn': u'Sheri Smith', 'uid': u'ssmith', 'name': u'smith'} ret = app._get_user('ssmith') assert expected == ret diff --git a/tests/test_Roles.py b/tests/test_Roles.py index 08332fb..5cebc08 100644 --- a/tests/test_Roles.py +++ b/tests/test_Roles.py @@ -78,7 +78,7 @@ class TestError(object): def testNested(self): inv = Roles('./tests/cfg/nested.yml') - expected = {'developpers': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=developpers,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Developpers', 'description': 'description'}, 'admin-lv3': {'backends_groups': {'ad': ['Domain Users', 'Administrators', 'Domain Controllers'], 'ldap': ['cn=nagios admins,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com', 'cn=puppet admins,ou=group,dc=example,dc=com', 'cn=dns admins,ou=group,dc=example,dc=com']}, 'display_name': 'Administrators Level 3', 'description': 'description'}, 'admin-lv2': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=nagios admins,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Administrators Level 2', 'description': 'description', 'LC_admins': True}, 'users': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Simple Users', 'description': 'description'}} + expected = {'developpers': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=developpers,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Developpers', 'description': 'description'}, 'admin-lv3': {'backends_groups': {'ad': ['Domain Users', 'Administrators', 'Domain Controllers'], 'ldap': ['cn=nagios admins,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com', 'cn=puppet admins,ou=group,dc=example,dc=com', 'cn=dns admins,ou=group,dc=example,dc=com']}, 'display_name': 'Administrators Level 3', 'description': 'description'}, 'admin-lv2': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=nagios admins,ou=group,dc=example,dc=com', 'cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Administrators Level 2', 'description': 'description', 'LC_admins': True}, 'users': {'backends_groups': {'ad': ['Domain Users'], 'ldap': ['cn=users,ou=group,dc=example,dc=com']}, 'display_name': 'Simple Users', 'description': 'description'}} assert expected == inv.flatten def testGetGroupMissingRole(self): @@ -147,5 +147,5 @@ class TestError(object): ], 'toto': ['not a group'], } - expected = {'unusedgroups': {'toto': Set(['not a group']), 'ad': Set(['Domain Users 2'])}, 'roles': Set(['developpers', 'admin-lv2', 'users'])} + expected = {'unusedgroups': {'toto': Set(['not a group']), 'ad': Set(['Domain Users 2'])}, 'roles': Set(['developpers', 'admin-lv2', 'users'])} assert inv.get_roles(groups) == expected